# Diagnostics Tools Contract To perform its function, diagnostics tools need to make assumptions on how the compiler, runtime, and framework works. This was done in various obscure ways. Often, the dependency is taken in another code base such that breaking changes are detected only in runtime during integration tests, which is often too late. The crux of the problem is that the contract is implicit. Therefore, we are making changes to the product so that we establish a formal and explicit contract between the components and the diagnostics tools. For example, certain kind of breaking changes can now be detected during build time. You are reading this probably because you have made a change that broke the contract. In the sequel of the document, we will talk about why your change is breaking and what can you do about it. ## Overall Principle At a breakpoint when the debuggee stops. We can look at any memory freely in the debuggee. This is often the most convenient way to perform any debugging operation. Therefore, unlike other applications, debuggers are mostly interested in the fields of the debuggee, not the APIs. This is especially true in the AOT scenario where we do not have support for true function evaluation in the debuggee, yet. The debugger accesses the field through symbols, so this is mostly a no-op for the framework developers. But there are a few exceptions because the debugger is trying to make sense of those objects and give better diagnostics experience, for example: ### Strings In a typical application, you have many strings. Strings are just another managed object such that we can inspect all the fields out of it. There is a character array, we can inspect the characters. But that would be an awful experience. The user will want to just look at the string. In order to do that, the debugger makes an assumption that `System.String._firstChar` represent the head of the character array and get the string out the debuggee memory and display as a string. Now imagine what would happen if the field is renamed? The debugger will not be able to find the string, and it may fallback any other approach. That is fundamentally why we need to keep the fields unchanged. Not only the name and its existence, but also its meaning. If `_firstChar` is repurposed to mean something else, the debugger would output something wrong, which is arguably worse. ### StringBuilder Most data structures are linked, in a typical debugging scenario, you would want to know the list content without having to traverse a tree of pointers. Luckily, the code that is required to traverse the pointer is in the debuggee itself, so mostly the debugger do not need to take a dependency on the semantic structure of the tree, by just leveraging the capability of the debuggee to decode its own data. An interesting example would be the `StringBuilder`. A debugging developer would most likely want to know what is the string that is currently in the `StringBuilder`, not the chunks. Because the debuggee is stopped, we cannot run the debuggee code, but we could run those code out of the debuggee process and access memory as those code being run. The key challenges for that is that, as of now (1st July 2016), we do not support inspecting ThreadStatic fields, so whenever such an out of process execution need a thread static field, it will need to fall back to some other means to simulate it. That is why the diagnostics tool is taking a dependency on the various ThreadStatic fields. Note that this is just a temporary restriction and we are looking forward to eliminating these dependencies in the future. ### Async Stepping Not just inspection, sometimes other operations need to take dependencies on fields as well. A good example would be async stepping. Where would you like to stop when you try to step out an async call, you would like to get back to the next line of the caller, right? In order to do that, the debugger needs to know which thread to go back to, and this is done by inspecting the data structure generated by the compiler and the framework. ## Questions? If you are trying to make a change that you have to break the contract, please contact us, @dotnet/dotnet-diag.