I'm looking for an extension for Visual Studio where in debug mode it's possible to single step through the intermediate language beside C#.
I'm not looking for a solution to debug managed and unmanaged code.
What is your purpose? Is your IL generated by C# compiler or dynamically produced at run time? If the former one, you can use a trick of re-compiling your binary through ilasm.
Compile C# code as you normally would. It does not matter if it is optimized or not, but you have to specify compilation option to produce full PDB symbols.
Use ildasm to convert your binary to .il file. It is option Dump in the menu.
re-compile the .il file to get a new binary (and a new symbols)
ilasm .il [/exe|/dll] /debug
Now when debugging that specific assembly you will see IL code rather than C# code. You will also see a matching lines from original C# file if you select appropriate option in step 2.
For the case of dynamically generated IL, I would simply use WinDbg with SOS extension. It can dump IL and step through it, but it takes a bit to get used to.
Although not strictly a Visual Studio extension as the OP requested, there's now a maybe even better way to do this using dnSpy, a comprehensive, standalone, open-source .NET debugging tool. The tool actually does much more than just debugging; for example it allows direct editing of .NET and native (PEFile) assemblies, de-obfuscating them, browsing and modifying the raw managed and native headers, content, resources, BAML, and metadata, and more that I probably haven't discovered.
For the purposes of the discussion on this page, be sure to check out the IL interpreter section of the dnSpy project. Exactly as requested by the OP, this is the library that implements an IL interpreter for simulating the (pretend) execution of the IL code in parallel with the debugger's (actual) native instruction single-stepping, for the purposes of displaying the state of the (logical) IL execution stack. I believe there's some excellent x86/x64 disassembly rendering built-in to the debugger as well, if needed. Kudos to the developer of this tour-de-force app.
I don't think that an external disassembler is necessary here. When you're debugging in VS 2010 (though not Express) you can right-click on the code window and select "Go To Disassembly" to step through the IL code. Could that be what you're looking for? Read more here
Related
I create a project, and add a file. I can build an exe and so on, works fine.
Question is: what if I have multiple files in my project and I want to check the syntax of my code in one single file, and don't want to build an exe or dll?
When programming c, I press ctrl+F7 in the Visual Studio IDE and that compiles my code. I understand that there are no object files in c#. Microsoft c# reference states: "There are no object (.obj) files created as a result of invoking the C# compiler; output files are created directly.".
Is there a csc.exe switch to tell me 'ok your code looks fine', or 'the expression at line xx doesn't make sense'?
Note: please do not give the link to Command-line Building With csc.exe. All the sample command lines are for creating an exe or dll, from one or multiple files. Or on how to exclude a file from building. I don't want that.
The compiler is the syntax checker. It will tell you if your C# code is valid or not when it compiles it. Any errors or warnings will be available at the end of the attempted compilation. If there are none, then it's valid code.
You can individually compile any arbitrary piece of C# code any time you like. However, if that code depends on other code then in order for it to be valid that other code will need to be included in the compilation as well. Code which uses otherwise undefined symbols (such as classes defined in other code files) isn't valid. Those symbols need to be defined.
In the comments above you indicate a concern that such compilation of an entire project might take a long time. This would be addressed by organizing your code into smaller components. If you have one enormous C# project that takes a long time to compile, then what you have is a mess. Break it apart into smaller components. Each of those components can be in their own projects which can be compiled separately. Different projects will depend on each other, and dependent projects will be included in that compilation. But that dependency graph also shouldn't be too large and unwieldy. If it is, you still have a mess but just on a different scale. Keep the dependency graph shallow and maintainable between your projects.
Sort of answering my own question. When I posted this I wasn't aware that splitting definition and implementation in c#, as you did in c or c++, was not possible. https://social.msdn.microsoft.com/Forums/en-US/64800602-4ff2-4747-8c42-a4e1980d4124/c-no-header-files-all-code-is-written-inline-why?forum=csharplanguage states that Interfaces do this, but not in a way I asked in the original post. Looks like in a multi file project, only the IDE gives me this piece of information (syntax checking), other than building the whole project.
It appears that ctrl+F7 on a single file (Visual Studio), or -c or -fsyntax-only switches (on gcc) are not possible with c#.
I have a C# program from which I am calling some functions/variables from C++.
The C++ program itself runs fine, and is checked. But, when I build this DLL and use it for C#, there is some bug in the interfacing code that is preventing me to get the correct result in C#.
Most probably, there is some error in export variables/exported functions giving out the results, which I want to check.
My primary question is : How do I debug this DLL, as in by putting breakpoints etc. and following along by seeing the results as we could do for any other program?
Assuming you have source code and debug symbols for the native (C++) DLL, you can check the "Enable unmanaged code debugging" option on the "Debug" tab of the managed (C#) EXE project, and then set breakpoints, inspect variables etc. in the C++ code as usual. You can add the C++ project to the solution, or just open a single C++ source code file and set breakpoints there.
If you want to debug the DLL, you should work in your C++ environment, put breakpoints in your c++ code, but use the executable generated by c#.
The best way to debug this kind of scenario, is by either using Visual Studio mixed mode debugging (via devenv /debugexe yourapp.name.exe command) or using Windbg + SOS extension (steeper learning curve, but this would show a lot more information, like you type sizes in native and managed code)
To learn how to use Windbg + SOS, please see Advanced .NET Debugging by Mario Hewardt
Note, that often these kind of issues are caused by
1) Incorrectly chosen C# data type to use with C++ APIs
2) Incorrectly specified / unspecified function calling convention
http://blogs.msdn.com/b/adam_nathan/archive/2003/05/21/56690.aspx
Are there any good programs out there to compare to compile .NET assemblies?
For example I have HelloWorld.dll (1.0.0.0) and HelloWorld.dll (2.0.0.0), and I want to compare differences how can I do this?
I know I can use .NET Reflector and use the Assembly Diff plugin. Are there any other good tools out there to do this?
Ways to Compare .NET Assemblies suggests
Commercial:
NDepend
Free:
JustAssembly (only shows differences in API)
BitDiffer (same)
Reflector Diff Add-in (which you've already discovered, but not available anymore)
Existing compare tools like Beyond Compare (commercial) can do this by special configuration. Here's how to do this for Beyond Compare:
Go to Tools → Options
Click New.., select "Text format", click OK
Give it a name (say, EXE, or DLL), and specify the mask as *.exe or *.dll
Click on tab Conversion and select "External program (Unicode filenames)"
Under "Loading", specify the path to ildasm and add %s /OUT:%t /NOBAR (i.e.: C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\ildasm.exe %s /OUT:%t /NOBAR)
Make sure to check disable editing.
Click Save, then Close
Restart BC and open two exe files to compare, it should decompile into ilasm automatically now.
You can also add syntax highlighting to this new format. I plan to send the syntax file to them so that it'll become available to share.
Two ways.
You could ILDASM and diff with classic tools.
Or you could use NDepends, which will cost for that feature.
[Piece to C# bloaters..]
I just had to compare two revisions of the same DLL, which had the same version (I needed to implement a small hotfix, and deploy the DLL in production, but I wanted to make sure that no other changes leaked into code). Ideally, I would want the Assemby Diff add-in to show me the difference, but it does not work (it thinks that I'm comparing a DLL to itself). So this is what I did:
Created two folders to hold disassembled source files.
Used the Reflector's Export option (from context menu) to generate source files from each DLL in the folders created in previous step.
Used the free DiffMerge tool to compare two directories; the tools showed me the modified files and the difference.
It's a bit kludgy, but seems to work. I wish the Assembly Diff add-in worked, though.
UPDATE: The latest version of the Assembly Diff add-in is supposed to fix the issue of comparing two versions of the same assembly. Give it a try.
The tool NDepend offers many features to compare compiled .NET assemblies.
First from the NDepend Start Page click: Compare 2 versions of a code base. This will let you provide older and newer versions of your assemblies.
Then after NDepend has analyzed both older and newer assemblies, you can use the panel Search by Change. It is dedicated to browse assemblies code diff. Notice that:
If source code is available, just right click an element and click Diff Source. In the NDepend options you can plug to NDepend any code diff tool (Visual Studio, Beyond Compare...)
If you don't have the source code and just only the raw assemblies, there is the option Compare older and newer version disassembled with ILSpy. ILSpy v7.0 and upper versions are supported. This menu works on assembly, namespace, type and method level and you can choose to decompile to C# or IL.
Notice also in the screenshot that a CQLinq code query is generated to browse the diff.
from m in Application.Methods
where m.CodeWasChanged()
select new { m, m.NbLinesOfCode }
Many others default diff queries and rules are proposed by default, that will let you browse .NET code diff in a smart way.
Types that used to be 100% covered but not anymore
API Breaking Changes: Methods
Avoid making complex methods even more complex
Avoid decreasing code coverage by tests of types
From now, all types added or refactored should respect basic quality principles
Avoid transforming an immutable type into a mutable one
Heuristic to find types moved from one namespace or assembly to another
Disclaimer: I am one of the developer of the tool.
One more option is LibCheck from Microsoft.
Pretty old console tool for just getting public API diff. I could not run without debugging and retargeting to a more recent .net version. However, it gave me very clear output and I am going to use it later.
Here is an article with screenshots.
Here's a thinking outside the box approach whcih works fine.
Dump your old and new assemblies with dnSpy, dotPeek or JustDecompile into projects.
Create a new Git repo and commit the old assembly code first.
In your local repo folder delete all the files/folders except for ".git" and paste the new assembly files.
Either commit the new changes and view changes on say Github or use a Git viewer like Fork. Easy code comparison for free.
Java has a nice one: Semantic Diff Utilities
If I have a DLL (that was built in release-mode) and the corresponding PDB file, is it possible to debug (step-into) classes/methods contained in that DLL?
If so, what are the required steps/configuration (e.g. where to put the PDB file)?
Edit:
If have the PDB file in the same place as the DLL (in the bin/debug directory of a simple console test application). I can see that the symbols for the DLL are loaded (in the Output window and also in the Modules window), but still I cannot step into the methods of that DLL.
Could this be the result of compiler optimizations (as described by Michael in his answer)?
The pdb is usually (for me at least) detected if it is next to the dll (like with the intellisense xml files).
Alternatively; you'll need a break point after the module has loaded...
At the break-point, bring up the "Modules" window (Ctrl+D,M - or Debug->Windows->Modules). Right click on your dll "Load symbols from", "Symbol path", etc.
Yes, you can debug release code with a PDB. There are some pitfalls however with debugging optimized code, more info here and here.
Your PDB just needs to be in a place that the debugger can find it - for local debugging same directory as the dll is usually easiest. Otherwise, put it in some place that the debugger can find it, and point the debugger to that place with the symbol path.
I finally found what cause the problems debugging a DLL that was built in release configuration:
First of all, it basically works as expected. Which means, if I have a DLL built in release-configuration plus the corresponding PDB file, then I can debug the classes/methods contained in that DLL.
When I first tried this, I unfortunately tried to step into methods of a class which has the DebuggerStepThroughAttribute, e.g:
[System.Diagnostics.DebuggerStepThrough]
public class MyClass {
public void Test() { ... }
}
In that case, it is of course not possible to step into the method from the debugger (as expected/intended).
So everything works as intended. Thanks a lot for your answers.
Debugging a release build is typically much harder that debugging a debug version. In general you'll need some understanding of x86 assembler and you'll likely spend some time looking at the disassembly window. This tends to be the only way to figure out what line of code you are really on since in a release build with optimizations on the compiler may do significant inlining and instruction reordering. In addition I find the debugger frequently fails to correctly report values of variables. If you need to know a variable's value and you are not sure the debugger is correct, go into the disassembly window and find the memory location or register it is located in.
The pdb files can be stored in a Symbol Server. Check out Setting up a Symbol Server for a good tutorial. Every product we build on a build machine publishes the symbols to our symbol server, so we can always debug any crash dumps we receive from WinQual.
When should I include PDB files for a production release? Should I use the Optimize code flag and how would that affect the information I get from an exception?
If there is a noticeable performance benefit I would want to use the optimizations but if not I'd rather have accurate debugging info. What is typically done for a production app?
When you want to see source filenames and line numbers in your stacktraces, generate PDBs using the pdb-only option. Optimization is separate from PDB generation, i.e. you can optimize and generate PDBs without a performance hit.
From the C# Language Reference
If you use /debug:full, be aware that there is some impact on the speed and size of JIT optimized code and a small impact on code quality with /debug:full. We recommend /debug:pdbonly or no PDB for generating release code.
To answer your first question, you only need to include PDBs for a production release if you need line numbers for your exception reports.
To answer your second question, using the "Optimise" flag with PDBs means that any stack "collapse" will be reflected in the stack trace. I'm not sure whether the actual line number reported can be wrong - this needs more investigation.
To answer your third question, you can have the best of both worlds with a rather neat trick. The major differences between the default debug build and default release build are that when doing a default release build, optimization is turned on and debug symbols are not emitted. So, in four steps:
Change your release config to emit debug symbols. This has virtually no effect on the performance of your app, and is very useful if (when?) you need to debug a release build of your app.
Compile using your new release build config, i.e. with debug symbols and with optimization. Note that 99% of code optimization is done by the JIT compiler, not the language compiler.
Create a text file in your app's folder called xxxx.exe.ini (or dll or whatever), where xxxx is the name of your executable. This text file should initially look like:
[.NET Framework Debugging Control]
GenerateTrackingInfo=0
AllowOptimize=1
With these settings, your app runs at full speed. When you want to debug your app by turning on debug tracking and possibly turning off (CIL) code optimization, just use the following settings:
[.NET Framework Debugging Control]
GenerateTrackingInfo=1
AllowOptimize=0
EDIT According to cateye's comment, this can also work in a hosted environment such as ASP.NET.
There is no need to include them in your distribution, but you should definitely be building them and keeping them. Otherwise debugging a crash dump is practically impossible.
I would also turn on optimizations. Whilst it does make debugging more difficult the performance gains are usually very non-trivial depending on the nature of the application. We easily see over 10x performance on release vs debug builds for some algorithms.