2015-04-30 1 views
7

разборки выглядит следующим образом:Почему я не могу войти в команду вызова во время отладки/разборки?

   methShort(ref x, ref y); 
000007FF00163F67 lea   r8,[rsp+34h] 
000007FF00163F6C lea   rdx,[rsp+30h] 
000007FF00163F71 mov   rcx,qword ptr [rsp+20h] 
000007FF00163F76 mov   rcx,qword ptr [rcx+8] 
000007FF00163F7A mov   rax,qword ptr [rsp+20h] 
000007FF00163F7F call  qword ptr [rax+18h] 

Метод "methShort" динамически создаются в .NET с использованием Reflection.Emit. В качестве значений «byRef» требуется два параметра Int32. Это отлаживается как сборка «release-режим».

Я могу выполнить сборку вплоть до инструкции «вызов». Содержимое памяти, на которое указывают R8 и RDX (параметры), выглядит отлично. Я не знаю, какая магия позволила JIT использовать регистры для вызова вместо стека, но это не относится к делу.

Когда я пытаюсь выполнить «шаг за шагом» в команде вызова, вместо этого отладчик «перешагивает» его. Подпрограмма действительно называется - метод выполнил свою функцию правильно. Но я не могу разбираться и не вступать в метод.

В точке непосредственно перед вызовом RAX содержит значение 00000000025C67A8h. Когда к нему добавляется 18h, адрес для косвенности становится 00000000025C67C0h. QWORD по этому адресу: 000000001b64dc48h.

Если я попытаюсь разобрать этот адрес (000000001b64dc48h), отладчик вернется с «Указанный адрес не может быть отображен. В указанном месте отсутствует код».

Как попытка Hail Mary, я попытался разобрать код в RAX без косвенности, но, как я ожидал, это тоже не удалось.

Может ли кто-нибудь сказать мне, как добраться до любого кода по адресу, или если что-то похожее на LEA должно выполняться по адресу (RAX + 18h), прежде чем разбирать код там?

+3

https://msdn.microsoft.com/en-us/library/ms235286.aspx в x64 первые два параметра вызова метода находятся в RCX и RDX. – xanatos

+1

VS отказывается показать вам некоторые части среды выполнения. Это должен быть вызов помощника во время выполнения. Я никогда не понимал, почему они абсолютно уверены, что отладчик не может даже разобрать время выполнения. – usr

ответ

6

Вам нужно иметь в виду, что отладчик пытается избавить вас от потери нескольких часов вашей жизни. methShort() - это вызов делегата, все еще должен быть лот выполненной работы до того, как этот звонок может завершиться. Вы не будете наслаждаться однократным нажатием на дрожание, компилируя свой динамический метод в машинный код, CAS проверяет потребность в ссылке, CLR создает заглушку делегата и привязывает его к сайту вызова.

Я отвечу на вопрос как отправленный, отладчик не покажет вам целевой код вызова, потому что это неуправляемый код. Вы можете указать по адресу, удаленному от местоположения вашего jitted-кода. Убедить его, что вы хотите, чтобы видеть это требует несколько приемов:

  • Project + Свойства, вкладка Debug, отметьте опцию «Включить родной отладки кода»
  • Вы должны переключить отладчик из управляемого в неуправляемый режим. Для этого нет явной команды, простейшим способом я знаю, как это сделать - использовать окно «Стек вызовов». Дважды щелкните нижний кадр (__RtlUserThreadStart @ 8).
  • Нажмите ссылку «просмотреть разборку» в всплывающем окне «Источник недоступно», чтобы вернуться в окно «Разборка». Отладчик теперь находится в неуправляемом режиме. Остерегайтесь того, что с новым механизмом отладки вы не можете легко сказать, так как теперь отображаются правильные коды.
  • Теперь вы можете ввести адрес, который вы обнаружили в поле Адрес. Обязательно поставьте «0x» перед ним.

Не может быть полезно при отладке динамического метода, хотя я довольно быстро бросил полотенце, когда я его попробовал.Вероятно, вы опережаете вызов метода дважды, чтобы обойти все накладные расходы при втором вызове. Попробуйте поместить вызов в Debugger.Break() в свой метод.

Смежные вопросы