Focus on Microsoft Technologies - Tutorials, Articles, Code Samples.

Thursday, August 31, 2006

How .NET Debugger Process Break Points

  1. From the current frame, the SampleDebugger application queries for its IL frame.
  2. From the IL frame, it retrieves the current instruction pointer (which is an offset from the beginning of the function).
  3. From the current frame, SampleDebugger retrieves the current function through ICorDebugFrame::GetFunction.
  4. From the current function, the debugger retrieves its token.
  5. Using the module's metadata, the debugger retrieves the symbolic method for the runtime function.
  6. From the symbolic method, SampleDebugger retrieves its sequence point count, allocates some space to hold the data, and then retrieves the method's sequence points.
  7. SampleDebugger then searches each sequence point returned, comparing its offset (which is an instruction pointer offset) to the current instruction pointer offset from Step 2.
  8. When a match is made, SampleDebugger looks at the source line where the sequence point occurred and stops searching the remaining sequence points. Matching the instruction pointer to the sequence point implicitly matches the current instruction pointer to the line of source code that is executing.

Figure 6 Finding Breakpoints
Figure 6 Finding Breakpoints

Once you know how to decode where breakpoints have occurred, they need to be added. Ultimately, breakpoints belong with the module (which contains the code) to which they are matched. Since the debugger is notified when a module is loaded through the managed callback, all it has to do is wait for the notification from the CLR and then add the breakpoints as needed. The steps to adding the breakpoints can be viewed in CManagedCallback::LoadModule (in ManagedCallback.cpp) and CDebuggerServices::AddBreakpointToModule (in DebuggerServices.cpp in the code download). Figure 6 shows how this process works. The steps can be summarized as follows:

  1. Start the process and wait for the module load notification.
  2. Match the module name to the module being debugged.
  3. Retrieve the module's metadata interface so source code can be matched to IL.
  4. Retrieve a symbol reader and then get the document from it.
  5. Retrieve the method from the document position for the given breakpoint.
  6. Retrieve the method's token.
  7. Retrieve the method's IL offset from the beginning of the method.
  8. Retrieve the runtime function from the CLR from the current module based on the token previously retrieved.
  9. Retrieve the IL code for the runtime function.
  10. Create a breakpoint on the code returned and set it (whether it's active or not).
  11. Add additional breakpoints by repeating Steps 6-11 until all breakpoints are added.
  12. Continue the process that was stopped on the module load notification.

Continue with complate article from Microsoft.
, , , ,

Post a Comment