C++ SymGetLineFromAddr工作不正常

C++ SymGetLineFromAddr工作不正常,c++,winapi,visual-c++,stack,dbghelp,C++,Winapi,Visual C++,Stack,Dbghelp,我有以下代码: #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(); SymInit

我有以下代码:

#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;
}
#包括“stdafx.h”
#包括
#包括
#包括
#包括“dbghelp.h”
使用名称空间std;
int LogStackTrace()
{
void*stack[1024];
HANDLE process=GetCurrentProcess();
SymInitialize(进程,NULL,TRUE);
wordnumberofframes=CaptureStackBackTrace(0,1000,stack,NULL);
SYMBOL_INFO*SYMBOL=(SYMBOL_INFO*)malloc(sizeof(SYMBOL_INFO));
符号->MaxNameLen=1024;
symbol->SizeOfStruct=sizeof(symbol\U信息);
IMAGEHLP_线*线=(IMAGEHLP_线*)malloc(sizeof(IMAGEHLP_线));
行->SizeOfStruct=sizeof(IMAGEHLP_行);
printf(“捕获异常”);
for(int i=0;i名称,行->文件名,符号->地址);
}
返回0;
}
无效函数2()
{
int a=0;
int b=0;
抛出新异常(“预期异常”);
}
无效函数1()
{
int a=0;
函数2();
}
void函数0()
{
功能1();
}
静态void线程函数(void*param)
{
尝试
{
函数0();
}
捕获(…)
{
LogStackTrace();
}
}
int _tmain(int argc,_TCHAR*argv[]
{
尝试
{
_beginthread(threadFunction,0,NULL);
}
捕获(…)
{
LogStackTrace();
}
printf(“按任意键退出。\n”);
cin.get();
返回0;
}
问题是它总是在这一行出错:
printf(“在%s中的%s处,地址0x%0x\n”,符号->名称,行->文件名,符号->地址)

原因是因为行的文件名似乎为空。事实上,整个线路结构都搞砸了。我正在尝试编写一个应用程序来显示错误的堆栈跟踪。但为什么呢?它不应该使用上面的代码工作吗?PS我在Win32上编译了它,作为一个简单的MSVC++控制台应用程序

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

结构的大小,以字节为单位。此成员必须设置为sizeof(SYMBOL\u INFO)请注意,数据的总大小是SizeOfStruct+(MaxNameLen-1)*sizeof(TCHAR)。减去一个的原因是名称中的第一个字符在结构的大小中起作用


我的。您必须分配至少
sizeof(SYMBOL\u INFO)+MaxNameLen+1
字节的存储空间。您只分配了
sizeof(SYMBOL\u INFO)
字节。

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

修正了它:

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

这不是问题所在。结构正确返回地址。符号信息没有问题,尽管我可以增加结构的大小,当然。问题在于SymGetLineFromAddr和IMAGEHLP_线结构。即使通过增加SYMBOL\u INFO的大小,IMAGEHLP\u行结构设置不正确仍然存在问题。这还不够,核心问题是他忽略了返回值,没有调用GetLastError()来找出错误。@HansPassant True。当我看到代码可能正在破坏堆时,我倾向于停止寻找其他问题,因为代码已经被破坏了……它不是不可靠的。的文档明确指出“如果函数失败,返回值为
FALSE
。要检索扩展的错误信息,请调用
GetLastError
”是的,正如我已经指出的,您的程序正在破坏堆。请用版本信息更新您的问题。Windows XP还是Windows 7?32位还是64位?MBCS还是Unicode?Windows 8.1,使用Unicode字符集,Win32应用程序。@manuell嘿,我写了一篇关于所有这些的博客文章,制作了一个很好的包装类,人们可以用它来跟踪堆栈,并研究了Windows错误报告(这实际上是一个救命稻草):可选值就这么多了,是吗?这可能解释了错误代码322225477是十六进制的0xC0000005,在Windows上是:#定义状态_访问_违反((NTSTATUS)0xC0000005L)访问违反是Windows版本的“分段错误”,简单地说就是指程序试图访问未分配的内存。发生这种情况的原因有很多,但大部分(如果不是总是)是程序中的一个错误。好吧,它并没有真正被记录为可选:-)或零将被解释为输出值…我犯了一个错误,认为位移是可选的,就像在SymFromAddrThanks中一样,我今天学到了一些东西:-)。我不知道那种API。快乐的黑客!你知道我有多惊讶,我在其他地方没有找到这样的例子吗?我一直在尝试开发这些疯狂的API。您可能会发现我的其他一些堆栈问题非常有趣,但特别是:阅读本文,这将导致