Чтение полей экземпляра при отладке сборок JIT

Последние пару недель я играл с неуправляемым API отладки.NET.

В то время как MSDN документирует сами интерфейсы, чтобы выяснить, как на самом деле использовать их любым осмысленным способом, я прибегнул к различным блогам (в основном Mike Stall) и к управляемым оболочкам в примерах CLR Managed Debugger и источниках ILSpy. В конце я смог прикрепить свою тестовую программу к работающему процессу, установить точки останова и нажать на них.

Что я хотел бы сделать дальше - это нажать на точку останова, прочитав поле соответствующего экземпляра объекта. Это прекрасно работает, когда целевой метод отладки не был NGEN или JIT, отключая загрузку сборок NGEN (параметр среды 'COMPLUS_ZAPDISABLE=1') и отключая JIT-оптимизации (так называемый трюк.ini file).).

Однако, когда я пытаюсь сделать то же самое с моей идеальной целью - кодом, оптимизированным для розничной торговли (NGEN/JIT), - это не работает. Например: я могу при достижении точки останова входа по-прежнему получать количество аргументов метода, но не могу получить сам первый аргумент (API отладки выдает исключение).

Теперь я предполагаю, что причина этого в том, что API отладки должны быть независимыми от платформы, и в этом случае сборки больше не будут. Но что, если я приму эту зависимость от платформы от Intel: насколько мне известно, CLR использует соглашение о вызовах fastcall, где в этом случае регистр ECX содержит первый аргумент метода (неявная ссылка "this" для функций-членов),

Я проверил это, и, действительно, при достижении точки останова ECX содержит OBJECTREF (адрес экземпляра объекта) в сборках NGEN.

Теперь последний шаг в чтении поля экземпляра состоит в том, чтобы получить смещение поля относительно этого указателя, и я застрял в этом, поскольку мне кажется, что я не могу выяснить, как CLR выполняет упаковку полей экземпляра во время генерации собственного кода,

Я понимаю, что это может зависеть от версии / реализации CLR, но, видимо, есть способы, так как WinDbg с расширением SOS может найти этот макет. Если не через API отладки, могу ли я как-то использовать SOS.dll?

1 ответ

По первому вопросу причина, по которой вы не можете найти аргументы / локальные параметры, заключается в том, что вы отлаживаете оптимизированный код. Оптимизированный код не позволяет отслеживать args / localals.

Что касается вашего второго вопроса, вам нужно использовать SOS.dll SOSEX.dll или PSSCOR2/4.dll в WinDbg или SOS/PSSCOR в Visual Studio для того, чтобы прочитать поля объекта.

РЕДАКТИРОВАТЬ: Теперь я вижу, что вы хотели бы сделать это из кода. Это требует использования API доступа к данным (DAC), который, к сожалению, недокументирован.

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