Я хочу реализовать аналог утилиты backtrace под windows, чтобы добавить эту информацию, например, в исключение.
Мне нужно захватить обратные адреса, а затем перевести их в имена символов.
Мне известно о StackWalk64 и проекте StackWalker, но, к сожалению, у него есть несколько существенных недостатков:
- Известно, что он очень медленный (StackWalk64), и я не хочу тратить много времени на сбор трассировки, в основном это можно сделать так же быстро, как пройтись по связанному списку.
- Известно, что функция StackWalk64 не является потокобезопасной.
Я хочу поддерживать только x86 и возможные архитектуры x86_64
Основная идея у меня следующая:
- Запуск в стеке с использованием регистров esp/ebp аналогично
__builtin_return_address(x)
/__builtin_frame_address(x)
doe GCC, пока я не достигну нижней части стека (это то, что делает glibc). - Преобразование адресов в символы
- Демангл их.
Проблемы/Вопросы:
- Как я узнаю, что достиг вершины стека? Например, реализация glibc имеет
__libc_stack_end
, поэтому легко найти, где остановиться. Есть ли аналог такой штуки под Windows? Как я могу получить нижний адрес стека? - Какие есть аналоги функционала dladdr. Теперь я знаю, что в отличие от платформы ELF, которая хранит большинство имен символов, формат PE этого не делает. Так что он должен как-то читать отладочную информацию. Любые идеи?