Получение указателя на конец стека вызовов и разрешение символа по адресу (например, dladdr) в Windows - PullRequest
2 голосов
/ 27 сентября 2010

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

Мне нужно захватить адреса возврата и затем перевести их в имена символов.

Я знаю о StackWalk64 и проекте StackWalker , но, к сожалению, у него есть несколько важных недостатков:

  • Известно, что он очень медленный (StackWalk64), и я не хочу тратить много времени на сбор трассировки, в основном это можно сделать так же быстро, как ходить по связанному списку.
  • Известно, что функция StackWalk64 не является поточно-ориентированной.

Я хочу поддерживать только архитектуру x86 и возможные архитектуры x86_64

Основная идея, которую я имею в виду:

  1. Запуск в стеке с использованием регистров esp / ebp аналогично тому, что делает __builtin_return_address(x) / __builtin_frame_address(x) в GCC, пока я не достигну дна стека (это то, что делает glibc).
  2. Перевести адреса в символы
  3. Разобрать их.

Проблемы / Вопросы:

  1. Откуда мне знать, что я достиг стека? Например, реализация glibc имеет __libc_stack_end, поэтому легко найти, где остановиться. Есть ли аналог Windows под Windows? Как получить адрес нижнего стека?
  2. Какие аналоги функциональности dladdr. Теперь я знаю, что в отличие от платформы ELF, которая хранит большинство имен символов, формат PE - нет. Так что стоит как-то прочитать отладочную информацию. Есть идеи?

Ответы [ 2 ]

2 голосов
/ 14 февраля 2011
  • Захват трассировки стека: RtlCaptureStackBackTrace
  • Получение символов: использование библиотеки справки DBG (только MSVC).Ключевые функции:

    // Initialization
    hProcess = GetCurrentProcess()
    SymSetOptions(SYMOPT_DEFERRED_LOADS)
    SymInitialize(hProcess, NULL, TRUE)
    // Fetching symbol
    SymFromAddr(...)
    

    Реализация может быть найдена там

1 голос
/ 27 сентября 2010

Вы используете StackWalk, но разрешаете символы позже.

...