Как отлаживать невыровненный доступ на amd64 с помощью Visual Studio?

Я хотел бы отлаживать и профилировать некоторое 64-битное программное обеспечение, выполняющее невыровненный доступ, как в следующем примере:

int foo[2] = { 1, 2 };
*((int *)((char *)foo + 2)) = 3;

Способ gcc

Я знаю два способа сделать поэтому при использовании gcc и gdb . Первый - включить выровненную проверку бит (бит 18) в регистре eflags , непосредственно в моем коде C или 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. Встроенная сборка в программе на C ++ больше не доступна в режиме x64 в любой версии Visual Studio, но вместо этого я могу использовать встроенные функции :

#include 
/* ... */
__writeeflags(__readeflags() | 0x40000);

Это точно такой же код, как и в Linux. Это вроде работает : я получаю исключение, когда выполняется мой ошибочный код. За исключением того, что флаг EFL.AC сбрасывается в ноль каждый раз, когда достигается точка останова. Это означает, что я не могу должным образом отлаживать большое приложение с множеством сложных точек останова, если я не засорю код вызовами моей функции asm.

Итак, я попытался вручную изменить EFL | = 0x40000 из сеанса отладки регистров Visual Studio (это именно то, что я обычно делаю в Linux). Никакого эффекта, бит устанавливается в ноль, как только я возобновляю отладку. Это означает, что я не могу правильно отладить код, для которого у меня нет исходного кода.

Я не понимаю, что здесь происходит. Visual Studio принудительно устанавливает EFL.AC = 0 ? Если да, могу ли я отключить эту «функцию»? Кроме того, есть ли способ включить / отключить EFL.AC во время сеанса отладки?

Как в реальном мире разработчики Windows отслеживают невыровненный доступ в своем коде?

Изменить : обнаружено о __ readeflags , которого не было в списке встроенных функций x64 .

23
задан sam hocevar 31 March 2011 в 10:36
поделиться