PersistedAssemblyBuilder PDB Help #111316
-
I am trying to generate a dynamic assembly to file then run an entry point within the assembly from a host .NET application with debug information. I have scrapped together some code and I can generate the assembly to file using PersistedAssemblyBuilder and run it dynamically in VsCode. I am also generating an embedded PDB. I am emitting IL instructions within the generated assembly that will call into a static function in the host assembly with some parameters and return a result. Works perfectly. However, I want to now generate some debug information so I can map the IL instructions to a source file on disk and debug through those lines in the debugger. I am doing this to test out the API of the assembly builder, PDB sequence points, etc.. Ultimately, I am investigating implementing a custom language on the CLR. The file I am trying to map to is a dummy file with a few lines of "code". The code doesn't matter, I just want the debugger to map, for example IL Offset 0 to line 1 of the file, IL Offset 4 to line 3 of the file, etc.. I am using the IL generator mark sequence point function to attempt to do this. Here is the issue. I am generating (what appear to be) the correct sequence points within the embedded PDB. I generated 4 sequence points for 4 lines of "code" within the file. All IL offsets are mapping to the correct line spans. However, when I try to debug into the file, it is not working correctly. Once the dynamic assembly is loaded, the breakpoint bubbles are settable and solid red in VsCode within the file to indicate that the PDB was loaded correctly. I can hit the first breakpoint (first line) within the file when I run during debug; however, if I try and step into or over, the code executes without breaking on the next line and ends up back in the host application after the "code" in the file executed. I can sometimes jigger the generated sequence points to hit one of the other 4 lines in the code. I can share the godawful code I slopped together if it helps, but I am not sure what I am doing wrong during the generation. How exactly does the VsCode "step over" and "step into" debug operations work? I had assumed at least for step over that the IL that I generated between the current sequence point and the next one would execute and it would then break within the file on the line defined in the next sequence point. That does not appear to be happening. I seem to only be able to somewhat reliably break on the first line of the "code". My thought here is that I might be generating a release assembly mode instead of a debug assembly mode so the code is just being bypassed as expected. Do I need to add nops at each sequence point? I have been searching online, but there is not a ton of material on generating the debug info besides explaining the APIs exist and a few simple examples. TLDR: I am dynamically generating and running an assembly with embedded PDB that includes source file sequence points. The sequence points look to be correct; however, stepping through a debug session in VsCode does not work correctly in the source file. Only the first sequence point somewhat reliably causes a debugger break within the source file. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
OH I SEE! I went spelunking into the PDB of the C# host program to read what it was writing for sequence points. I noticed that the IL offsets for the sequence points seemed to be pointing only at IL instructions such as stloc. This got me thinking that sequence points may only work for certain instructions. I modified my PDB generation to place sequence points in front of stloc instructions and poof, now I can actually step over each line! NANI!? Does this mean there is a requirement for sequence points to only appear before / after certain instructions and they don't work for all instructions? The original sequence points I was generating were before load constant instructions (ldc_I4). However the other line I did hit happened to have a stloc on it. Is this explained in the documentation somewhere? |
Beta Was this translation helpful? Give feedback.
The sequence points must point to locations with empty IL stack, nop instruction or IL instruction right after call.
This detail is touched upon in https://stackoverflow.com/questions/6937198/making-your-net-language-step-correctly-in-the-debugger or in https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.debuggableattribute.debuggingmodes . I agree that this can be documented better.