【问题标题】:How to get the stacktrace of a DLL who crashes?如何获取崩溃的 DLL 的堆栈跟踪?
【发布时间】:2018-11-27 02:06:26
【问题描述】:

我为一个应用程序开发了一些 DLL,我想知道是否可以在我的 DLL 崩溃时获取堆栈跟踪(在日志文件中),然后不对主应用程序的代码进行任何修改。

这是一个 DLL 的虚拟示例,我想在它崩溃时记录堆栈跟踪:

HelloDLL.h

#pragma once

//more about this in reference 1
#ifdef DLLDIR_EX
   #define DLLDIR  __declspec(dllexport)   // export DLL information

#else
   #define DLLDIR  __declspec(dllimport)   // import DLL information

#endif 

class DLLDIR HelloDLL
{
public:
    HelloDLL(void);
    ~HelloDLL(void);

    void crash();

private:
    void danger();
};

HelloDLL.cpp

#include "stdafx.h"
#include "HelloDLL.h"
#include <iostream>

using namespace std; 

HelloDLL::HelloDLL(void)
{
}

HelloDLL::~HelloDLL(void)
{
}

void HelloDLL::crash()
{
    danger();
}

void HelloDLL::danger()
{
    abort();
}

我无法更改的应用程序:

#include "stdafx.h"
#include "HelloDLL.h"

#include <iostream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{

    HelloDLL helloDLL;
    helloDLL.crash();

    getchar();

    return 0;
}

我使用this website 创建了这个示例。

换句话说,当我的DLL崩溃时,我怎样才能从DLL中获取最大的信息,以便于调试过程?

【问题讨论】:

  • 崩溃的不是dll,而是进程崩溃。
  • @VTT 我同意,但我怎样才能获得与我的 DLL 关联的进程的堆栈跟踪?
  • 可以获取执行线程的堆栈跟踪...设置故障转储生成主要是系统配置问题。虽然如果在发生致命错误的情况下执行某种手动操作,可能需要修改主应用程序的代码。
  • 正如 VTT 所说,你不能只设置故障转储生成吗?
  • @ssbssa 你说得对,这可能是最好的方法。

标签: c++ debugging logging dll stack-trace


【解决方案1】:

正如 cmets 中所说,获取崩溃进程的堆栈跟踪的最佳方法是生成转储文件。为此,您首先需要编辑HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps 注册表项。以下是获取Hello.exe 应用程序完整转储的示例:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\Hello.exe]
"DumpCount"=dword:a
"DumpType"=dword:2

更多关于可用值的信息可以在here找到。默认情况下,转储文件将存储在%LOCALAPPDATA%\CrashDumps

然后,您需要在没有任何优化选项的情况下编译您的应用程序,并且您必须生成.pdb 文件(使用/DEBUG 选项)。

您现在可以运行您的程序并在CrashDumps 目录中转储文件。要阅读它,您可以使用 VisualStudio(也可以使用其他应用程序,例如 WinDbg):

  1. 用VisualStudio打开.dmp文件(你可以把文件放到打开的解决方案中)
  2. .pdb 文件添加到configuration of VisualStudio(工具> 选项> 调试> 符号)
  3. 点击“仅使用本机运行”

您现在可以在崩溃发生时获取所有线程的堆栈跟踪,还可以在程序停止之前读取变量的值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多