多年来我在很多游戏项目中都使用过minidumps,他们似乎有大约50%的机会拥有一个有效的调用堆栈.我该怎么做才能让他们有更好的调用堆栈?
我已经尝试将最新的dbghelp.dll放在exe目录中.这似乎有些帮助.
Visual Studio 2008或2010是否更好?(我还在VS 2005).
我使用的代码看起来像这个样本.
我目前使用未处理的异常捕获MiniDumps,__CODE__但有时我得到"R6025:纯虚函数".
我理解一个纯虚函数调用是如何发生的我只是想知道是否有可能捕获它们所以我可以在那时创建一个MiniDump.
我标记了以下代码:
#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);
SYMBOL_INFO *symbol = (SYMBOL_INFO *)malloc(sizeof(SYMBOL_INFO)+(TRACE_MAX_FUNCTION_NAME_LENGTH - 1) * sizeof(TCHAR));
symbol->MaxNameLen = TRACE_MAX_FUNCTION_NAME_LENGTH;
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
DWORD displacement;
IMAGEHLP_LINE64 *line = (IMAGEHLP_LINE64 *)malloc(sizeof(IMAGEHLP_LINE64));
line->SizeOfStruct = sizeof(IMAGEHLP_LINE64);
for (int i = 0; i < numberOfFrames; i++)
{
DWORD64 address = (DWORD64)(stack[i]);
SymFromAddr(process, address, …Run Code Online (Sandbox Code Playgroud) 我使用CodeProject中的Jochen Kalmbach的StackWalker类,在我的DLL中发生异常时产生堆栈跟踪.
它依赖于DbgHelp.dll
DbgHelp.dll是否内置于Windows Vista,WS2008,Windows 7?
我知道微软的Windows调试工具,我知道DbgHelp.dll附带在该软件包中.但我也在我的机器上的%windir%\ system32中找到了DbgHelp.dll.
如果没有默认安装,有没有办法让我用我的DLL的调试版本重新分发它?
我如何得到EXCEPTION_POINTERS,即:
PEXCEPTION_RECORD 和 PCONTEXTEExternal异常期间的数据?
当Windows抛出异常时,它会传递一个PEXCEPTION_POINTERS; 指向异常信息的指针:
typedef struct _EXCEPTION_POINTERS {
PEXCEPTION_RECORD ExceptionRecord;
PCONTEXT ContextRecord;
} EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;
Run Code Online (Sandbox Code Playgroud)
当Delphi抛出EExternal异常时,它只包含一半的信息,PEXCEPTION_RECORD唯一的:
EExternal = class(Exception)
public
ExceptionRecord: PExceptionRecord;
end;
Run Code Online (Sandbox Code Playgroud)
在EExternal例外情况下,如何同时获得两者?
我正在尝试使用MiniDumpWriteDumpDelphi中的函数编写Minidump .
该函数有一些可选参数:
function MiniDumpWriteDump(
hProcess: THandle; //A handle to the process for which the information is to be generated.
ProcessID: DWORD; //The identifier of the process for which the information is to be generated.
hFile: …Run Code Online (Sandbox Code Playgroud) 我正在尝试调用SymLoadModuleEx从PDB文件加载符号,然后用于SymFromAddr查找该PDB中的符号.但是,我想不出什么来传递的参数BaseOfDll和DllSize-文件明确地说,加载PDB文件时,这些参数不能为0,确实试图通过0导致它失败ERROR_INVALID_PARAMETER.
这是我的代码的样子:
SymSetOptions(SYMOPT_LOAD_LINES);
HANDLE hprocess = GetCurrentProcess();
if (!SymInitialize(hprocess, NULL, FALSE))
die("SymInitialize");
if(SymLoadModuleEx(hprocess, NULL, "full path to some PDB file.pdb", NULL,
0, // What to pass here?
0, // What to pass here?
NULL, 0) == 0)
{
die("SymLoadModuleEx");
}
Run Code Online (Sandbox Code Playgroud)
你如何找出BaseOfDll并DllSize以加载PDB文件时传递?有问题的PDB文件是不同程序可执行文件(不是DLL)的符号文件,只是为了参数,假设您无权访问生成PDB的原始EXE.
或者,是否有更好的方法从PDB文件中查找与给定地址对应的符号?
我有一大堆minidump,它们是在应用程序运行期间通过MiniDumpWriteDump记录的.minidump是在具有与我的开发机器不同的操作系统版本的机器上创建的.
现在我正在尝试编写一个程序,使用dbghelp.dll从minidump中提取堆栈跟踪.我正在走MINIDUMP_MODULE_LIST并调用SymLoadModule64,但是无法从公共符号服务器下载pdbs(kernel32等).如果我在符号路径中添加"C:\ Windows\System32",它会找到dll并下载符号,但当然它们与minidump中的dll不匹配,因此结果没用.
那么如何告诉dbghelp.dll下载并使用正确的pdbs?
[编辑]
我忘了声明SymLoadModule64只接受文件名而没有版本/校验和信息,所以很明显只有SymLoadModule64,dbghelp无法找出要下载的pdb.
这些信息实际上在MINIDUMP_MODULE_LIST中可用,但我不知道如何将其传递回dbghelp API.
有一个SymLoadModuleEx,它需要额外的参数,但我不知道这是我需要的,或者我应该传递给其他参数.
[编辑]
到目前为止没有运气,但我注意到在调试SDK中还有dbgng.dll与dbghelp.dll一起分发.MSDN看起来很好,并说它与windbg使用的引擎相同.也许我可以使用它来提取堆栈跟踪.
如果有人能指出我使用dbgeng.dll处理可能有用的minidumps的一些介绍,因为MSDN只记录单个组件,但不记录它们如何一起工作.
作为背景,我遇到了将中型Linux代码库(编译成巨型.so)移植到x64窗口(编译成.dll).我有连接器问题.
作为一个最小的测试用例,如果我只从以下文件创建一个Visual Studio项目:
#include <Windows.h>
#include <Dbghelp.h>
void do_stuff(char const * s)
{
char buffer[4096];
long int len = UnDecorateSymbolName(
s,
buffer,
sizeof(buffer),
UNDNAME_COMPLETE);
}
Run Code Online (Sandbox Code Playgroud)
我将项目类型设置为DLL并构建它,我收到错误"LNK2001:未解析的外部符号__imp_UnDecorateSymbolName".也就是说,文件正确编译,但无法链接到dll.
我认为目标是我的dll链接到dbghelp.dll,特别是因为(至少在我的系统上)没有像dbghelp.lib这样的文件.那么为什么现在尝试解析该符号,而不是当我的DLL加载到应用程序中时呢?为什么它无论如何都看不到这个功能呢?
为了清楚起见,我已经确认我正在构建x64 DLL,并且C:\ Windows\System32中的dbghelp.dll是x64.
OlyDbg第2版最近发布.它现在支持使用Microsoft Symbol Server进行调试:
它通过dbghelp.dll支持Microsoft编译器.新增了对符号服务器的支持,使用dbghelp的堆栈遍历和过程参数的名称.
如何让OlyDbg使用Microsoft Symbol Server?

答案很长:
我设置了一个系统环境变量:
_NT_SYMBOL_PATH=SRV*d:\Symbols*http://msdl.microsoft.com/download/symbols
Run Code Online (Sandbox Code Playgroud)我添加SRV*d:\Symbols*http://msdl.microsoft.com/download/symbols了OlyDbg应该搜索的"目录",以及YouTube视频

c)OlyDbg 2.0中没有符号出现
