Манипулирование информацией о размотке x64 для соответствия крюку сборки - PullRequest
0 голосов
/ 09 ноября 2018

Редактировать: Я, кажется, ошибся, обратная трассировка прекрасно работает из любой точки Linux - только при удаленной отладке с gdb в ubuntu на удаленные окна, трассировка стека полностью уничтожается после входа в одну из памяти функции выделения в msvcrt ... dammit microsoft.

И это происходит как для 64-битных, так и для 32-битных окон, поэтому я не уверен, что это связано с информацией о раскрутке ...

Редактировать: Похоже, добавление -g3 и -Og помогло решить часть проблемы в некоторых программах, но проблема все еще сохраняется в других программах, не могу опубликовать их источник здесь, так как это IP моей компании - извините !

Фон

Я использую gcc для компиляции ubuntu-> ubuntu и mingw для компиляции ubuntu-> windows.

Я создал кросс-платформенную (linux + windows) библиотеку для отслеживания памяти и обнаружения утечек, которая перехватывает malloc / calloc / realloc / free с помощью байт-патча сборки на первых инструкциях (не перехватывает IAT / PLT).

Хук перенаправляет на гейт, который проверяет, включены ли хуки в текущем потоке, и перенаправляет на функцию хуков отслеживания памяти, если они есть, в противном случае он просто перенаправляет на батут реальной функции, если они отключены для этого потока. .

Библиотека прекрасно работает и обнаруживает утечки в linux / windows (возможно, будет работать на Mac, но у меня ее нет).

Я использую библиотеку для программного обнаружения утечек из моего кода, я могу устанавливать обратные вызовы в подпрограммах выделения памяти и программно поднимать точки останова (путем зацикливания и ожидания присоединения отладчика, затем выполняя asm ("int3")) внутри обратных вызовов так что я могу подключиться к моей программе, пока она находится внутри вызова, что приводит к утечке памяти.

Все прекрасно работает до тех пор, пока я не попытаюсь просмотреть обратную трассировку внутри моего обратного вызова, я понимаю, что это, вероятно, потому, что информация о раскрутке, вероятно, больше не соответствует моему стеку, потому что я вставил новые кадры и данные через подпрограммы ловушек, которые у меня есть вставлена.

Редактировать: Если я ошибаюсь из-за того, что информация о раскрутке, не совпадающая со стеком, является причиной неправильной трассировки, пожалуйста, исправьте меня!

Вопрос

Есть ли какие-нибудь небольшие хаки, которые я могу сделать, чтобы обмануть GDB в правильной перестройке обратной трассировки из моих обратных вызовов хука?

Я понимаю, что могу вручную ходить и редактировать информацию о раскрутке с помощью libdwarf или чего-то еще, но я думаю, что это было бы невероятно громоздким и большим.

Так что мне интересно, может быть, есть какой-нибудь хак или чит, который я мог бы сделать, чтобы обмануть GDB в правильном восстановлении следа?

Если нет легких хитростей или уловок, то каковы все мои варианты решения этой проблемы?

Редактировать: просто чтобы выяснить точный порядок вызовов всего:

program
   V
malloc
   V
hook_malloc -> hooks are disabled -> return malloc trampoline -> real malloc > program
   V
hooks are enabled 
   V
Call original malloc -> malloc trampoline -> real malloc -> returns to hook
   V
Record memory size/info etc from malloc
   V
Call user defined callback -> **User defined callback* -> returns to hook
   V
return to program

Это «Определяемый пользователем обратный вызов», где я хочу получить обратную трассировку

1 Ответ

0 голосов
/ 10 ноября 2018

Видимо, это та же проблема GDB Windows ?? в следах

И решение было просто добавить -g3 к флагам компиляции mingw и альт у меня есть неразбитые следы!

Редактировать: Неважно, это не полный ответ. Похоже, что это исправление работало для некоторых тестовых программ, но другие программы по-прежнему отображают неправильные следы, такие как:

(gdb) bt
#0  malloc_callback (s=38, rv=0x2c5058) at test_dll.c:729
#1  0x000000000040731d in hook_malloc_raw (file=0x410ea1 <__FUNCTION__.63079+55> "", function=0x410ea1 <__FUNCTION__.63079+55> "", line=0, s=38, rv=8791758343065)
#2  0x0000000000407367 in hook_malloc (s=38)
#3  0x000007fefda20b9e in ?? ()
#4  0x0000000000000026 in ?? ()
#5  0x0000000000410ea1 in __FUNCTION__.63079 ()
#6  0x0000000000000000 in ?? ()

Очевидно, что кадр № 4 на самом деле не является кадром стека, и я не уверен, почему кадр № 5 помечен как «__FUNCTION __. 63079».

Edit2: Если люди собираются понизить голос, по крайней мере, оставьте комментарий, объясняющий, почему

...