This project is read-only.

PDB source location amibiguity issues

Topics: PDB Writer
Mar 23, 2011 at 10:41 PM

I'm following the example of the "ILMutator" sample in the CCI source distro, but cannot quite get the PDB files I'm producing to work identically to the original PDB.   Unfortunately, the ILMutator sample seems to punt on this issue (according to the comment in ILMutator.cs just before the PdbWriter is constructed and PeWrite.WritePeToStream is called), so I've tried to figure out it out myself based on the hint provided in that comment.

Since I'm just injecting IL instructions into the tops of methods, I've built an implementation of ISourceLocationProvider & ILocalScopeProvider that essentially delegates to a PdbReader wired up to the original PDB file associated with the assembly I'm injecting code into.  When my provider is called, I make adjustments based on whether the location I'm working with is an original instruction from the input assembly, or an instruction I've injected.

In general, I've got things working.  I can step into/over/through methods, and the auto, locals, watch and other debug windows all seem to be in working order.  However, when I use the "set next statement" feature of Visual Studio's debugger to move the instruction pointer to a new location, I get a modal dialog box titled "Resolve Ambiguity" that lists multiple IL instruction offsets corresponding to the (C#) statement I've tried to navigate to.  Looking at the disassembled IL for the offsets listed shows that the set of instructions shown in the dialog box always equates to the set of IL instructions making up the high level C# statement I've tried to move to (usually 3-5 IL instructions).  The set-next-statement operation works fine if I select the first instruction listed, but I shouldn't be getting the dialog box at all - and assume it's the result of an error in the formation of the PDB file I've produced.

A couple of notes about my implementation:

* I don't need the user to be able to debug/step through the code I'm injecting.  I just need the code I'm injecting to not mess up the debugability of the original code in the assembly I'm rewriting.

* In order to enable people to step into rewritten methods from the outside, I set the Location property of the Operation I'm injecting to refer to the same Location that the original (non-injected) first operation in the method body was using.  If I don't do this, step-into doesn't work.

* I get the "Resolve Ambiguity" dialog box even for methods whose method body I haven't touched at all, but that are elsewhere in the assembly I've rewritten.  So the error I have effects even methods I haven't touched during rewriting.

So two questions:

(1) Any advice on what mistake I've made that causes the "Resolve Ambiguity" dialog.

(2) Is there an example somewhere that demonstrates how to use CCI to rewrite an assembly *and* its associated PDB file (so that the rewritten assembly can be debugged just like the original)?



Mar 24, 2011 at 5:36 AM

Try setting the location of the first (injected) operation to be SourceDummy.PrimarySourceLocation. That will emit the infamous FEEFEE line number that is used to mark things like non user prologue code.

Apr 12, 2011 at 2:59 AM

I missed the fact that my advice was based on a set of changes that only got made to our internal copy. This should work now, I hope. Sorry about that.