Как отлаживать несвязанные обращения на amd64 с помощью Visual Studio?
Я хотел бы отлаживать и профилировать некоторое 64-битное программное обеспечение, выполняющее несвязанные обращения, например, в следующем примере:
int foo[2] = { 1, 2 };
*((int *)((char *)foo + 2)) = 3;
Способ gcc
Я знаю два способа сделать это при использовании gcc и gdb. Первый из них - это включить выравниваемый контрольный бит (бит 18) в регистре eflags
непосредственно в моем коде C или С++:
asm volatile("pushf \n"
"pop %%rax \n"
"or $0x40000, %%rax \n"
"push %%rax \n"
"popf \n" ::: "rax");
Это очень удобно, потому что я могу выбрать внутри самого приложения, обойти или не проверять нелицензированные проверки доступа, например, при вызове известных дефектных библиотек.
Другой способ - от gdb, в любой момент при отладке исполняемого файла:
set $eflags |= 1<<18
Опять же, это можно включить или отключить по своему усмотрению, сценарию и т.д. Очень удобно.
Visual Studio
Теперь я полностью не смог сделать то же самое с помощью Visual Studio 2008 или 2010 на Vista64. Встроенная сборка в программе на С++ больше не доступна в режиме x64 в любой версии Visual Studio, но я могу использовать intrinsics вместо:
#include <intrin.h>
/* ... */
__writeeflags(__readeflags() | 0x40000);
Это точно такой же код, как и для Linux. Это своего рода работы: я получаю исключение, когда мой ошибочный код запускается. Если флаг EFL.AC
равен reset равным нулю при каждом ударе точки останова. Это означает, что я не могу должным образом отлаживать большое приложение с множеством сложных точек останова, если я не помешал код вызовам моей функции asm.
Итак, я попытался вручную изменить EFL |= 0x40000
из сеанса отладки реестра Visual Studio (это именно то, что я обычно делаю в Linux). Никакого эффекта тоже, бит устанавливается на ноль, как только я возобновляю отладку. Это означает, что я не могу правильно отлаживать код, для которого у меня нет исходного кода.
Я не понимаю, что здесь происходит. Является ли Visual Studio принудительной установкой EFL.AC=0
? Если да, могу ли я отключить эту функцию? Кроме того, есть ли способ включить/отключить EFL.AC
во время сеанса отладки?
Как разработчики Windows в реальном мире отслеживают несвязанные обращения в своем коде?
Изменить: узнал о __readeflags
, который не был в списке x64 intrinsics.
Ответы
Ответ 1
К сожалению, при отладке x64-отладчика в VS очищает флажок проверки выравнивания при любом исключении (в том числе тот, который первым отправлен в отладчик). Вы пробовали переходить через код с помощью windbg (гораздо более мощный отладчик Windows)? Я не смог попробовать его с помощью флага AC, но он должен быть простым с r efl = или непосредственно из окна регистров.
Если у вас нет установленного Windbg, вы можете получить его из новейшего SDK Windows.
Ответ 2
Использовать asmjit http://code.google.com/p/asmjit/
Ответ 3
Очень беспорядочное обходное решение - иметь поток в вашей программе, который постоянно устанавливает этот бит. Каждые 100 мс или около того.
Затем вы узнаете, что вскоре после того, как вы вернетесь с точки останова, выравнивание снова будет проверено. Не на 100% безопасно, но это может быть достаточно хорошо.