Как получить трассировку стека адресов в Windows без использования dbghelp.dll?
Мне не нужно знать, какие символы или имена функций связаны с адресами, мне просто нужен список адресов - что-то похожее на отслеживание систем * nix.
Спасибо!





Обратите внимание на функцию CaptureStackBackTrace (), которая находится в Kernel32.dll. Это должно сделать все, что вам нужно.
Captures a stack back trace by walking up the stack and recording the information for each frame.
USHORT WINAPI CaptureStackBackTrace(
__in ULONG FramesToSkip,
__in ULONG FramesToCapture,
__out PVOID *BackTrace,
__out_opt PULONG BackTraceHash
);
Выглядит неплохо. Но я использую VS 2005, а CaptureStackBackTrace no RtlCaptureBackTrace не определен в winbase.h. Я попробую вручную включить прототип функции для RtlCaptureBackTrace (...) и посмотрю, сработает ли это для меня. Спасибо!
Круто! Я писал код трассировки стека как минимум 3 раза и понятия не имел, что он существует. Спасибо!
@Uhall: Вы можете попробовать установить более новую версию Windows SDK. Минимальный поддерживаемый клиент указан как Windows XP, хотя на странице MSDN указано, что он был включен в Windows SDK, начиная с Windows Vista.
Если вы хотите сделать этот очень сильно непереносимым, вы можете просто прочитать регистр EBP и самостоятельно пройтись по стеку. Это будет работать только для архитектуры x86 и также предполагает, что среда выполнения C, которую вы используете, правильно инициализирует EBP равным 0 перед вызовом первой функции.
uint32_t read_ebp(void)
{
uint32_t my_ebp;
__asm
{
mov ebp, my_ebp
}
return my_ebp;
}
void backtrace(void)
{
uint32_t ebp = read_ebp();
printf("backtrace:\n");
while(ebp != 0)
{
printf("0x%08x\n", ebp);
ebp = ((uint32_t *)ebp)[1];
}
}
В сборках релиза это даст вам только первые несколько кадров. Чтобы это действительно работало надежно, вам необходимо установить "Omit Frame Pointers" = No.
пункт назначения идет первым, поэтому вам нужно mov my_ebp, ebp .. кроме этого это довольно круто
Предыдущий вариант у меня не работает (msvc 6), поэтому:
unsigned long prev;
unsigned long addr;
__asm { mov prev, ebp }
while(addr!=0) {
addr = ((unsigned long *)prev)[1];
printf("0x%08x\n", addr);
prev = ((unsigned long *)prev)[0];
}
Adam, thanks for highlighting the way!
Зачем вам это нужно делать без DbgHelp.dll. DbgHelp.dll встроен в Windows, начиная с Windows 2000. Также посмотрите Stackwalker Йохена Калмбаха: codeproject.com/KB/threads/StackWalker.aspx