Обратная отладка GDB AVX2
Итак, у меня есть новый модный процессор, который поддерживает набор команд avx2. Это здорово, но нарушает обратную отладку GDB. При компиляции без оптимизации код по-прежнему использует разделяемые библиотеки, например, вызывает memset(), которая затем запускается и вызывает оптимизированную для avx2 версию memset. Это здорово, но avx2 не поддерживается записью GDB.
запись процесса не поддерживает инструкцию 0xc5 по адресу 0x7ffff690dd80.
0xc5 здесь префикс vex.
обратная отладка прекрасно работает с процессором, который не поддерживает avx2. Как получить libc и т. Д., Чтобы не использовать оптимизированные для avx2 версии библиотечных вызовов, чтобы я мог использовать запись gdb, шаг назад и т. Д.?
я пробовал
LD_BIND_NOW=1
LD_HWCAP_MASK=0
compiling with -static
И если не считать отладку на старой машине, у меня нет идей.
1 ответ
Для вашего glibc 2.23, поставляемого на ubuntu 16.04 amd64, есть адаптация моего двоичного kludge (1-битный патч), сделанная точно по той же причине. пакет libc6 (2.23-0ubuntu7)
был загружен с https://packages.ubuntu.com/xenial/amd64/libc6 и файл ld-2.23.so был отредактирован (сохраните копию оригинала или сохраните исправленный по другому пути и измените раздел INTERP своего двоичного файла для использования другой путь):
83 3D 5B C9 20 00 06 cmpl $0x6, smth...
7E 21 jle some_forward_label
B8 07 00 00 00 mov $0x7, %eax
31 C9 xor %ecx,%ecx
0F A2 cpuid
Есть код get_common_indeces
: if (cpu_features->max_cpuid >= 7) __cpuid_count (7, 0, ...
звонил из __get_cpu_features
, EAX=7 лист cpuid имеет всю информацию, необходимую для обнаружения поддержки AVX2 и включения ее, поэтому я просто пропустил фрагмент с cpuid eax=0x7,ecx=0
и сохранение его результатов в некоторых частях памяти путем изменения 0x7e 0x21
в 0x7f 0x21
,
Итак, бинарный патч похож на замену 83 3D xx xx xx xx 06 7E xx B8 07 00 00 00 31 C9 0F A2
(где xx может быть любым байтом) в 83 3D xx xx xx xx 06 7F xx B8 07 00 00 00 31 C9 0F A2
, Вы можете сделать это с помощью любого шестнадцатеричного редактора или с помощью некоторого бинарного сравнения. В 2.23-0ubuntu7 этот код находится в 0x0193B0 - 0x0193B9 - 7e, который нужно заменить на 7f.
Патч тупой и не используйте пропатченный файл глобально, если ваша корневая файловая система может быть запущена с ЦП без поддержки листьев eax=7 cpuid (до процессора Intel Core) или в виртуальной машине, эмулирующей такой процессор до Intel Core ( "Pentium D 8xx / 9xx ", Pentium 4, Pentium M - выйдет из строя).
Вы можете поместить пропатченный файл по пути, имя которого равно по длине или короче исходного пути /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
(какие ссылки в /lib/x86_64-linux-gnu/ld-2.23.so
файл). Например как /lib_x86_64-linux-gnu_ld-linux-noAVX2.so.2
, Затем используйте тот же hexeditor для замены строки "/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2" исполняемого файла вашей программы (ELF) в "/lib_x86_64-linux-gnu_ld-linux-noAVX2.so.2", или используйте инструмент patchelf из patchelf
пакет:
cp /lib/x86_64-linux-gnu/ld-2.23.so /lib_x86_64-linux-gnu_ld-linux-noAVX2.so.2
bless /lib_x86_64-linux-gnu_ld-linux-noAVX2.so.2
# or any other hex editor
patchelf --set-interpreter /lib_x86_64-linux-gnu_ld-linux-no-AVX2.so.2 ./my_program