问题
I'm making a managed .NET debugger using MDBG sample.
Currently I'm struggling with StepInto behavior, while StepOut and StepOver seems to work.
To achieve Just-My-Code
stepping I'm calling SetJMCStatus
on modules load. That works fine and allow me to debug just my code.
But since I'm setting entire module as JMC, some auto-generated code comes into play and ruin stepping-into. An example of such code could be auto-property.
Since debugger is executing Il instructions, with step-into I'm getting inside auto-generated get_propertyName
and set_propertyName
method, which are marked as my code, because they are part of my module.
To distinguish such auto-generated code from my code I can use presence of debugging symbols, that are missing in case of auto-generated code. And then I could simply mark method as not my code to skip it during stepping.
The problem is I don't know which methods are auto-generated before I'm getting inside during stepping. When I stepped inside a method that has no debugging symbols I can mark it as not my code, but it's too late - debugger stopped where it supposed not to stop.
Theoretically I could iterate over my module methods using IMetadataImport and set their JMCStatus when debugger starts, but it seems quite expensive:
foreach (var methodToken in mdbgModule.Importer.EnumerateAllMethodTokens()) {
var func = mdbgModule.GetFunction(methodToken);
if (func.SymMethod == null)
func.CorFunction.JMCStatus = false;
}
If only I would know what function is going to be executed next, then I would be able to set it's status and prevent stepping inside auto-generated code for the first time.
I'm sticking with MDBG approach for stepping, not changing anything, just calling SetJMCStatus where it's needed, so I'm not sure if it makes sense to provide any code... If so, I'll edit the question, just add a comment!
Any suggestion on topic is greatly appreciated!
Regards,
回答1:
Mike Stall hinted at one option, you could set JMC for the entire module and then when the debugger stepper breaks, check to see if the method is debuggable, if not then disable it's JMC status and rerun the stepper. (I'm not sure if this will result in a change in behaviour if the resuming stepper would need to step out before stepping in again.)
You could probably improve things by only setting JMC for modules that have a pdb available and by disabling JMC for classes/methods with [DebuggerNonUserCode]
applied (and perhaps [DebuggerHidden] too). But rather than enumerating all the classes/methods and checking if they have the attribute, enumerate the custom attributes and work back (IMetaDataImport::EnumCustomAttributes with tkType set but not tk, then use IMetaDataImport::GetCustomAttributeProps to get the thing its applied to).
You might be able to do something similar with the [CompilerGenerated]
attribute if its applied at the method level, but will get false positives when applied at the class level (the compiler applies it to state machines for iterators and async methods, but both will likely have non-generated code too).
来源:https://stackoverflow.com/questions/38897784/debugger-stepinto-auto-generated-code-and-jmc-issue