SymGetLineFromAddr工作不正常

SymGetLineFromAddr not working properly

本文关键字:不正常 工作 SymGetLineFromAddr      更新时间:2023-10-16

我有以下代码:

#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%0Xn", 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%0Xn", symbol->Name, line->FileName, symbol->Address);

原因是因为行的FileName似乎为NULL。实际上,整条线的结构都乱了。我试图写一个应用程序来显示一个堆栈跟踪错误。为什么会这样呢?它不应该使用上面的代码工作吗?PS我在Win32上编译了它,作为一个简单的msvc++控制台应用程序。

有同样的问题与您的代码(Windows 7 64b, Unicode 32位构建,VS2012 Express)

修复:

DWORD dwDisplacement;
SymGetLineFromAddr(process, (DWORD)(stack[i]), &dwDisplacement, line);
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)。减1的原因是名称中的第一个字符已在结构体的大小中计算。

我特别强调。必须分配至少sizeof(SYMBOL_INFO) + MaxNameLen + 1字节的存储空间。您只分配sizeof(SYMBOL_INFO)字节。