Как отладить доступ без выравнивания на amd64 с помощью Visual Studio? - PullRequest
23 голосов
/ 31 марта 2011

Я хотел бы отладить и профилировать некоторые 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, но вместо нее можно использовать intrinsics :

#include <intrin.h>
/* ... */
__writeeflags(__readeflags() | 0x40000);

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

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

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

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

Редактировать : узнал о __readeflags, которого нет в списке встроенных функций x64 .

Ответы [ 3 ]

3 голосов
/ 15 апреля 2011

К сожалению, при отладке x64 в VS очищается флаг проверки выравнивания для любого исключения (включая тот, который был брошен в первую очередь в отладчик). Вы пытались пройти по коду с помощью windbg (гораздо более мощный отладчик Windows)? Я не смог попробовать это с флагом AC, но это должно быть просто с помощью r efl = или непосредственно из окна регистров. Если у вас не установлен windbg, вы можете получить его из новейшего Windows SDK.

0 голосов
/ 11 апреля 2011

Очень грязный обходной путь - иметь поток в вашей программе, который постоянно устанавливает этот бит.Каждые 100 мс или около того.

Тогда вы узнаете, что вскоре после возобновления с точки останова выравнивание будет проверено снова.Не на 100% безопасно, но может быть достаточно.

0 голосов
/ 05 апреля 2011

Использовать asmjit http://code.google.com/p/asmjit/

...