Отладчик 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] Атрибут, если он применяется на уровне метода, но получит ложные срабатывания при применении на уровне класса (компилятор применяет его к конечным автоматам для итераторов и асинхронных методов, но оба, вероятно, также будут иметь не сгенерированный код).

Другие вопросы по тегам