Отладчик StepInto автоматически сгенерированный код и проблема JMC
Я делаю управляемый.NET отладчик, используя пример MDBG.
В настоящее время я борюсь с поведением StepInto, в то время как StepOut и StepOver, кажется, работают.
Достигать Just-My-Code
я звоню SetJMCStatus
на загрузку модулей. Это прекрасно работает и позволяет мне отлаживать только мой код.
Но так как я устанавливаю весь модуль как JMC, в игру вступает какой-то автоматически сгенерированный код, и он рушится. Примером такого кода может быть авто-свойство.
Так как отладчик выполняет инструкции Il, с шагом я получаю автоматически сгенерированный get_propertyName
а также set_propertyName
метод, который помечен как мой код, потому что они являются частью моего модуля.
Чтобы отличить такой автоматически сгенерированный код от моего кода, я могу использовать наличие символов отладки, которые отсутствуют в случае сгенерированного кода. И тогда я мог просто пометить метод как не мой код, чтобы пропустить его во время шага.
Проблема в том, что я не знаю, какие методы генерируются автоматически, прежде чем я попаду внутрь во время шага. Когда я вошел в метод, у которого нет символов отладки, я могу пометить его как не мой код, но уже слишком поздно - отладчик остановился там, где он должен был не остановиться.
Теоретически я мог бы перебирать методы моего модуля с помощью IMetadataImport и устанавливать их JMCStatus при запуске отладчика, но это кажется довольно дорогим:
foreach (var methodToken in mdbgModule.Importer.EnumerateAllMethodTokens()) {
var func = mdbgModule.GetFunction(methodToken);
if (func.SymMethod == null)
func.CorFunction.JMCStatus = false;
}
Если бы я только знал, какая функция будет выполняться дальше, я бы смог установить ее статус и предотвратить первый шаг в автоматически сгенерированном коде.
Я придерживаюсь подхода MDBG для перехода, ничего не меняя, просто вызываю SetJMCStatus там, где это необходимо, поэтому я не уверен, имеет ли смысл предоставлять какой-либо код... Если так, я отредактирую вопрос, просто добавлю комментарий!
Любое предложение по теме очень ценится!
С Уважением,
1 ответ
Майк Сталл намекнул на одну из опций: вы можете установить JMC для всего модуля, а затем, когда сломается степпер отладчика, проверить, является ли метод отлаживаемым, если нет, отключить его состояние JMC и повторно запустить степпер. (Я не уверен, приведет ли это к изменению поведения, если возобновившемуся степперу нужно будет выйти, прежде чем войти снова.)
Вероятно, вы могли бы улучшить ситуацию, установив JMC только для модулей, у которых есть доступный pdb, и отключив JMC для классов / методов с помощью [DebuggerNonUserCode]
применяется (и, возможно, [DebuggerHidden] тоже). Но вместо того, чтобы перечислять все классы / методы и проверять, есть ли у них атрибут, перечислять пользовательские атрибуты и возвращаться ( IMetaDataImport:: EnumCustomAttributes с установленным tkType, но не с tk, затем используйте IMetaDataImport::GetCustomAttributeProps, чтобы получить объект, к которому он применяется),
Вы можете сделать что-то подобное с [CompilerGenerated]
Атрибут, если он применяется на уровне метода, но получит ложные срабатывания при применении на уровне класса (компилятор применяет его к конечным автоматам для итераторов и асинхронных методов, но оба, вероятно, также будут иметь не сгенерированный код).