Манипулирование информацией о размотке x64 для соответствия крюку сборки

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

И это происходит как для 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 ответ

Видимо это та же самая проблема 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: Если люди собираются понизить это, по крайней мере, оставьте комментарий, объясняющий, почему

Другие вопросы по тегам