我标记了以下代码:
#include "stdafx.h"
#include <process.h>
#include <iostream>
#include <Windows.h>
#include <dbghelp.h>
using namespace std;
#define TRACE_MAX_STACK_FRAMES 1024
#define TRACE_MAX_FUNCTION_NAME_LENGTH 1024
int printStackTrace()
{
void *stack[TRACE_MAX_STACK_FRAMES];
HANDLE process = GetCurrentProcess();
SymInitialize(process, NULL, TRUE);
WORD numberOfFrames = CaptureStackBackTrace(0, TRACE_MAX_STACK_FRAMES, stack, NULL);
char buf[sizeof(SYMBOL_INFO)+(TRACE_MAX_FUNCTION_NAME_LENGTH - 1) * sizeof(TCHAR)];
SYMBOL_INFO* symbol = (SYMBOL_INFO*)buf;
symbol->MaxNameLen = TRACE_MAX_FUNCTION_NAME_LENGTH;
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
DWORD displacement;
IMAGEHLP_LINE64 line;
line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
for (int i = 0; i < numberOfFrames; i++)
{
DWORD64 address = (DWORD64)(stack[i]);
SymFromAddr(process, address, NULL, symbol);
if (SymGetLineFromAddr64(process, address, &displacement, &line))
{
printf("\tat %s in %s: line: %lu: address: 0x%0X\n", symbol->Name, line.FileName, line.LineNumber, symbol->Address);
}
else
{
printf("\tSymGetLineFromAddr64 returned error code %lu.\n", GetLastError());
printf("\tat %s, address 0x%0X.\n", symbol->Name, symbol->Address);
}
}
return 0;
}
void function2()
{
int a = 0;
int b = 0;
throw new exception;
}
void function1()
{
int a = 0;
function2();
}
void function0()
{
function1();
}
static void threadFunction(void *param)
{
try
{
function0();
}
catch (...)
{
printStackTrace();
}
}
int _tmain(int argc, _TCHAR* argv[])
{
_beginthread(threadFunction, 0, NULL);
printf("Press any key to exit.\n");
cin.get();
return 0;
}
它的作用是记录堆栈跟踪,但问题是它记录的堆栈跟踪没有给我想要的行号。我希望它在调用堆栈上记录引发异常的位置的行号,有点像在 C# 中。但它现在实际做的是输出以下内容:
at printStackTrace in c:\users\<yourusername>\documents\visual studio 2013\pr
ojects\stacktracing\stacktracing\stacktracing.cpp: line: 17: address: 0x10485C0
at threadFunction in c:\users\<yourusername>\documents\visual studio 2013\pro
jects\stacktracing\stacktracing\stacktracing.cpp: line: 68: address: 0x10457C0
SymGetLineFromAddr64 returned error code 487.
at beginthread, address 0xF9431E0.
SymGetLineFromAddr64 returned error code 487.
at endthread, address 0xF9433E0.
SymGetLineFromAddr64 returned error code 487.
at BaseThreadInitThunk, address 0x7590494F.
SymGetLineFromAddr64 returned error code 487.
at RtlInitializeExceptionChain, address 0x7713986A.
SymGetLineFromAddr64 returned error code 487.
at RtlInitializeExceptionChain, address 0x7713986A.
我再次面临的问题是,line: 68
在此跟踪中对应于调用方法的行printStackTrace();
,而我希望它给我第 45 行,它对应于引发异常的行:throw new exception;
然后继续向上堆栈。
我怎样才能实现这种行为并在它抛出这个异常时准确地进入这个线程以获得正确的堆栈跟踪?
PS 上面的代码是为使用 MSVC++ 的控制台应用程序运行的,在 Windows 8.1 x64 机器上启用了 unicode,应用程序在调试模式下作为 Win32 应用程序运行。