Chapter 3 investigated how you can use JIT debugging to intercept a program crash and launch a debugger automatically. When a crash occurs, the CLR
vs7jit.exe /RegisterOld "c:\Windbg\windbg.exe" "WinDbg"
To unregister WinDbg for JIT debugging, you can use the following command line:
vs7jit.exe /UnregisterOld "c:\Windbg\windbg.exe"
As I've already stated, this switch is undocumented so I don't know for how long it will continue working.
As I discussed in some detail during Chapter 1, perhaps the most noticeable loss within the Source window is the inability to edit your code during a debugging run and then continue execution of the new code without restarting the program (a feature sometimes referred to as Edit and Continue, or E&C). If you select the option Tools
’
Options
’
Debugging
’
Edit and Continue
’
Allow me to edit VB files while debugging, you'll be able to edit your source code during program execution, but this revised code is ignored by the compiler until you restart the program. This is actually rather dangerous, as it's very easy to become
If you do want to take advantage of this ability to change code during a program run, I suggest adding all new and revised code into one or more separate procedures that you can then enclose within a collapsible region using the #Region #End Region directive. The #Region directive allows you to remove the new code from your view so that it doesn't interfere with your view of the code that is currently executing.
Placing the new code into separate procedures, maybe including revised copies of current procedures, is necessary because the
#Region
directive can only be used at a class or namespace level. Unfortunately, you can't place a region directive within a procedure or function. An alternative to creating a new
Having placed the code into one or more
After the current debugging run has finished, double-clicking each of these shortcuts in the Task window takes you directly to the associated region where new code is stored. You can then amend your code to
One frequent query from new .NET developers is how to view and debug Common Intermediate Language (CIL). The Source window only allows you to step through source code, and the Disassembly window only shows you the source code together with the processor-native code. Although your .exe or .dll contains the CIL, it seems to be
There is a neat trick that allows you to both view and step through CIL. It's based on using the CIL disassembler utility to dissect your executable into CIL source and then rebuilding the executable again so that the CIL code is bound to the VB .NET source. This may sound a little complicated, but the command-line steps are simple:
VBC MyProgram.vb /debug:full /optimize- /out: MyProgram.exe
ILDASM MyProgram.exe /source /out: MyTest.il
ILASM MyTest.il /debug /out: MyTest.exe
The first step builds your executable as normal, in full debug mode, and without code optimization. The second step disassembles the resulting binary into a CIL source file ”the /source flag adds the original VB .NET source code as CIL comments. The final step builds a new executable from the CIL source, once again in debug mode.
Having completed these command-line compilation steps, load the original project into Visual Studio. In my case this was a console application called DoubleTrouble.sln containing a single project called
DoubleTrouble
that, in
Figure 4-13:
Single-stepping and debugging CIL code with VB .NET source
Debugging the new executable that you've just created is simple. First, you place a breakpoint on one of the CIL statements shown in the Source window. Then you need to tell Visual Studio to launch your new executable. To do this, you should right-click your project in Solution Explorer and use the option under Properties ’ Configuration Properties ’ Debugging ’ Start external program to specify the executable that you created in the final command-line step mentioned previously. Now when you press F5, the breakpoint that you set should be hit. If you then jump to the Disassembly window, you can see the CIL code together with its corresponding native code. This is an instructive way of learning about CIL and how it functions.