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