【问题标题】:How do you get a fairly C#-esque stack trace in MSVC++?如何在 MSVC++ 中获得相当 C# 风格的堆栈跟踪?
【发布时间】:2014-03-17 18:24:02
【问题描述】:

在 C# 中,您会获得以下类型的堆栈跟踪:

   at ExceptionGenerator.Program.three() in c:\Users\ADIMA\Documents\Visual Stud
io 2013\Projects\ExceptionGenerator\ExceptionGenerator\Program.cs:line 36
   at ExceptionGenerator.Program.two() in c:\Users\ADIMA\Documents\Visual Studio
 2013\Projects\ExceptionGenerator\ExceptionGenerator\Program.cs:line 31
   at ExceptionGenerator.Program.one() in c:\Users\ADIMA\Documents\Visual Studio
 2013\Projects\ExceptionGenerator\ExceptionGenerator\Program.cs:line 26
   at ExceptionGenerator.Program.Main(String[] args) in c:\Users\ADIMA\Documents
\Visual Studio 2013\Projects\ExceptionGenerator\ExceptionGenerator\Program.cs:li
ne 15

我想在 C++ 中做同样的事情,但我不确定两件事......你如何获得文件以及你所在的行号?

到目前为止我工作的示例代码:

// StackTracing.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <process.h>
#include <iostream>
#include <Windows.h>
#include "dbghelp.h"

using namespace std;

int LogStackTrace()
{
    void            *stack[100];
    WORD            numberOfFrames;
    SYMBOL_INFO     *symbol;
    HANDLE          process;
    process = GetCurrentProcess();
    SymInitialize(process, NULL, TRUE);
    numberOfFrames = CaptureStackBackTrace(0, 1000, stack, NULL);
    symbol = (SYMBOL_INFO *)calloc(sizeof(SYMBOL_INFO)+256 * sizeof(char), 1); 
    symbol->MaxNameLen = 255;
    symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
    printf("Caught exception ");
    for (int i = 0; i < numberOfFrames; i++)
    {
        SymFromAddr(process, (DWORD64)(stack[i]), 0, symbol);
        printf("at %s, address 0x%0X\n", symbol->Name, symbol->Address);
    }
    return 0;
}

void function2()
{
    throw new exception("Expected exception.");
}

void function1()
{
    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;
}

输出:

Press any key to exit.
Caught exception at LogStackTrace, address 0xB13860
at threadFunction, address 0xB15680
at beginthread, address 0xFCF31E0
at endthread, address 0xFCF33E0
at BaseThreadInitThunk, address 0x7656494F
at RtlInitializeExceptionChain, address 0x772E986A
at RtlInitializeExceptionChain, address 0x772E986A

【问题讨论】:

  • 在 api 中四处看看几分钟,你会很快找到 SymGetLineFromAddr()
  • @HansPassant 是的,但是如何分配和传递 PIMAGEHLP_LINE 结构对我来说很棘手......
  • 另外,文件名呢?
  • PIMAGEHLP_LINE 包含一个 LineNumber 和 FileName,但它仍然没有为我返回正确的值,我正在尝试 malloc 该结构并让它工作:/它真的令人沮丧
  • @HansPassant 挑战:发布一个可行的解决方案...调用 SymGetLineFromAddr 实际上可以工作,因为我无法让魔法发生...总是返回第 0 行和一个空文件名...

标签: c# c++ visual-c++ trace dbghelp


【解决方案1】:

也许stack frame class 可以在这里为您提供帮助。

【讨论】:

  • 这仅适用于托管代码,不适用于本机 C++。我认为 OP 是关于本机代码的。
猜你喜欢
  • 2010-09-23
  • 1970-01-01
  • 2010-09-11
  • 2014-09-05
  • 2010-11-07
  • 2020-12-03
  • 2022-07-07
相关资源
最近更新 更多