SymGetLineFromAddr не работает должным образом

У меня есть следующий код:

#include "stdafx.h"#include <process.h>
#include <iostream>
#include <Windows.h>
#include "dbghelp.h"
using namespace std;

int LogStackTrace()
{
void *stack[1024];
HANDLE process = GetCurrentProcess();
SymInitialize(process, NULL, TRUE);
WORD numberOfFrames = CaptureStackBackTrace(0, 1000, stack, NULL);
SYMBOL_INFO *symbol = (SYMBOL_INFO *)malloc(sizeof(SYMBOL_INFO));
symbol->MaxNameLen = 1024;
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
IMAGEHLP_LINE *line = (IMAGEHLP_LINE *)malloc(sizeof(IMAGEHLP_LINE));
line->SizeOfStruct = sizeof(IMAGEHLP_LINE);
printf("Caught exception ");
for (int i = 0; i < numberOfFrames; i++)
{
SymFromAddr(process, (DWORD64)(stack[i]), NULL, symbol);
SymGetLineFromAddr(process, (DWORD)(stack[i]), NULL, line);
printf("at %s in %s, address 0x%0X\n", symbol->Name, line->FileName, symbol->Address);
}
return 0;
}

void function2()
{
int a = 0;
int b = 0;
throw new exception("Expected exception.");
}

void function1()
{
int a = 0;
function2();
}

void function0()
{
function1();
}

static void threadFunction(void *param)
{
try
{
function0();
}
catch (...)
{
LogStackTrace();
}
}

int _tmain(int argc, _TCHAR* argv[])
{
try
{
_beginthread(threadFunction, 0, NULL);
}
catch (...)
{
LogStackTrace();
}
printf("Press any key to exit.\n");
cin.get();
return 0;
}

Проблема в том, что он всегда выдает ошибку в этой строке: printf("at %s in %s, address 0x%0X\n", symbol->Name, line->FileName, symbol->Address);

Причина в том, что FileName строки выглядит как NULL. На самом деле, вся структура линии испорчена. Я пытаюсь написать приложение, чтобы показать трассировку стека при ошибке. Но почему это? Разве это не должно работать с использованием приведенного выше кода? PS Я скомпилировал его под Win32, как простое консольное приложение MSVC ++.

3

Решение

У вас была та же проблема с вашим кодом (Windows Seven 64b, Unicode 32-битная сборка, VS2012 Express)

Исправлено с помощью:

DWORD dwDisplacement;
SymGetLineFromAddr(process, (DWORD)(stack[i]), &dwDisplacement, line);
2

Другие решения

SYMBOL_INFO *symbol = (SYMBOL_INFO *)malloc(sizeof(SYMBOL_INFO));
symbol->MaxNameLen = 1024;
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);

Документация для SizeOfStruct состояния:

Размер структуры в байтах. Этот член должен быть установлен в sizeof (SYMBOL_INFO). Обратите внимание, что общий размер данных равен SizeOfStruct + (MaxNameLen — 1) * sizeof (TCHAR). Причина вычитания одного состоит в том, что первый символ в имени учитывается в размере структуры.

Акцент мой. Вы должны выделить как минимум хранилище sizeof(SYMBOL_INFO) + MaxNameLen + 1 байт. Вы только выделяете sizeof(SYMBOL_INFO) байт.

2

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector