1

我们使用 Fogbugz 来跟踪问题,我正在为 Fogbugz 编写一个围绕 XML API的 C++ 包装器。

最佳实践似乎是使用“侦察”字段,以便仅计算类似/相同的崩溃但不再报告。为此,我们需要一个用于特定崩溃原因的唯一字符串。

在 Win32 中 - 在获取 dmp 文件或其他崩溃处理程序之后,为崩溃创建唯一字符串的好方法是什么?(我们将创建一个 dmp 文件并将其发送到fogbugz 服务器)

在以前的帖子/文章/等中,Joel 提出了各种建议,但其中大部分都依赖于像 C# 这样的语言,它使用反射并且有很多难以获得或不可能获得的信息。

有没有其他人得到诸如堆栈跟踪或其他东西来在fogbugz中制作侦察条目?

编辑澄清 - 我们不希望每个事件都有一个唯一的 ID - 可能存在具有相同代码路径的崩溃。我们想要捕捉到这一点。我在想我们会得到我们代码中的最后几个堆栈调用(不是来自 win32 DLL 的堆栈调用) - 但不知道如何去做。

将每次崩溃都报告为唯一是不正确的。报告同一案例下的所有崩溃是不对的。重复导致崩溃的场景的不同用户应映射到同一事件。

编辑

我认为我们想要的是崩溃的一般“签名”——基于堆栈上的内容。类似的堆栈应该具有​​相同的签名。例如 - 采用我们应用程序中的前 5 个方法,然后我们将第一个调用(如果有)放入 MS DLL。这对于签名可能就足够了,并且可能会关联“相同”的崩溃。

那么如何获得堆栈上的方法列表呢?您如何判断它们是来自您自己的应用程序还是来自另一个 DLL?

编辑 - 注意我们想在异常处理程序中创建一个“桶 id”/签名,以便我们可以创建小型转储并将其作为侦察描述发送到雾虫。或者,我们可以在应用程序下一次启动时加载转储,然后使用我们生成的签名发送它。

4

6 回答 6

1

在我的项目中,我使用崩溃的地址内存作为“唯一”ID。

于 2011-01-06T19:16:09.007 回答
1

IMO 您可以使用的最好的东西是转储分析中的存储桶 id。使用正确配置的 Windows 调试工具 (windbg),可以执行 !analyze -v 并根据存储桶 ID 将转储分类到不同的存储桶中。Bucket id 保证如果两个转储相同,则它们的桶 id 将相同。这解决了部分难题。

很多时候,源于同一个问题的两个转储会创建不同的存储桶 ID(可能是版本差异,比如您的 1.0 和 1.1 都在同一点崩溃)。您可以使用故障模块和堆栈签名来关联来自同一故障点的错误。

某些事情会导致非常随机的转储(例如堆损坏,故障模块通常是受害者)。因此,转储分析应被视为尽力而为。当你不能时,你不能。

于 2011-01-07T07:12:26.780 回答
1

我在我的上一个应用程序(MSVC)中使用了类似的东西来生成异常,所以每个错误都会被源文件和它发生的行记录下来:

class Error {
    //...
    public: Error(string file, string line, string error) ;
};

#define ERROR(err) Error(__FILE__, __LINE__, err)
于 2011-01-07T07:25:15.477 回答
1

It's probably a little bit late, but I will add my solution here, too, in case it can help other people. You can do this using fools from "Debugging Tools for Windows", for example windbg.exe or better kd.exe. Running the command "kd.exe -z "path_to_dump.dmp" -c "kd;q" >> dumpstack.txt, you might get the following result:

Microsoft (R) Windows Debugger Version 10.0.15063.400 X86 Copyright (c) Microsoft Corporation. All rights reserved.

Loading Dump File [d:\work\bugs\14122\myexe.exe.2624.dmp] User Mini Dump File with Full Memory: Only application data is available

************* Symbol Path validation summary **************
Response                         Time (ms)     Location
Deferred                                       srv*C:\Symbols*http://msdl.microsoft.com/download/symbols
Symbol search path is: srv*C:\Symbols*http://msdl.microsoft.com/download/symbols
Executable search path is: 
Windows 10 Version 15063 MP (4 procs) Free x86 compatible
Product: WinNt, suite: SingleUserTS
15063.0.x86fre.rs2_release.170317-1834
Machine Name:
Debug session time: Fri Oct 13 00:09:01.000 2017 (UTC + 1:00)
System Uptime: 0 days 0:18:33.797
Process Uptime: 0 days 0:03:40.000
................................................................
.....................................................
Loading unloaded module list
..............................
This dump file has an exception of interest stored in it.
The stored exception information can be accessed via .ecxr.
(a40.2580): Security check failure or stack buffer overrun - code c0000409 (first/second chance not available)
eax=00000001 ebx=00000000 ecx=00000007 edx=77cc4350 esi=00000000 edi=00000000
eip=62ae7666 esp=0b75e17c ebp=0b75e1a8 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
msvcr120!abort+0x28:
62ae7666 cd29            int     29h
0:068> kd: Reading initial command 'kb;q'
ChildEBP RetAddr  Args to Child              
0b75e178 62addc5f 935dda1f 00000000 00000000 msvcr120!abort+0x28
0b75e1a8 0b75e7d4 62a9b436 0b75e1dc 62a52aa5 msvcr120!terminate+0x33
WARNING: Frame IP not in any known module. Following frames may be wrong.
0b75e1ac 62a9b436 0b75e1dc 62a52aa5 00000000 0xb75e7d4
0b75e1b4 62a52aa5 00000000 62a59740 0b75e7d4 msvcr120!__FrameUnwindToState+0x89
0b75e1c8 62a52b33 00000000 00000000 00000000 msvcr120!_EH4_CallFilterFunc+0x12
0b75e1f4 62a5a0f3 62b1f7b8 62a4f7c6 0b75e324 msvcr120!_except_handler4_common+0x8e
0b75e214 77cd6152 0b75e324 0b75e7c4 0b75e344 msvcr120!_except_handler4+0x1e
0b75e238 77cd6124 0b75e324 0b75e7c4 0b75e344 ntdll!ExecuteHandler2+0x26
0b75e30c 77cc4266 0b75e324 0b75e344 0b75e324 ntdll!ExecuteHandler+0x24
0b75e30c 74cf28f2 0b75e324 0b75e344 0b75e324 ntdll!KiUserExceptionDispatcher+0x26
0b75e684 62a59339 e06d7363 00000001 00000003 KERNELBASE!RaiseException+0x62
0b75e6c4 6001821c 0b75e6e4 6004e1bc 946a8f2a msvcr120!_CxxThrowException+0x5b
0b75e6f8 60018042 0b75e720 946a8efa ffffffff mymodule!FunctionC+0x7c
0b75e730 60016544 946a8ece ffffffff 092889d8 mymodule!FunctionB+0x32
0b75e754 600166b8 00842338 6000588d 00000001 myothermodule!FunctionB+0x44

From this stack, you can create a unique bucket if you take for example only your methods from the stack and concatenate them in a string: "mymodule!FunctionC+0x7c;mymodule!FunctionB+0x32;myothermodule!FunctionB+0x44". In order for this to work, you need to have access to you personal symbols server, either using the environment variable _NT_SYMBOL_PATH or with the -y command line switch. You can alternatively create a string from the return addresses only (second column): "62addc5f,0b75e7d4,62a9b436,62a52aa5,62a52b33,62a5a0f3,77cd6152,77cd6124,77cc4266,74cf28f2,62a59339,6001821c,60018042,60016544,600166b8"

于 2017-11-24T13:53:21.447 回答
-1

只需使用从转储文件生成的 MD5 字符串,您可能会为每次崩溃获得一个唯一的字符串。

于 2011-01-06T19:14:26.080 回答
-1

我将首先收集有关代码中每个函数在崩溃报告堆栈跟踪中“闪烁”的频率的数据。每个报告都必须添加到某种数据库中,并且每个函数都必须被索引,以便您以后可以查询,哪些函数似乎比其他函数更频繁地崩溃。(当然,像 main() 这样的函数会出现在每个报告中,但这是可以理解的)。

或者,您认为只有崩溃报告似乎是问题所在,您可以从崩溃堆栈跟踪中删除所有这些条目,然后对其余部分(您的函数)进行哈希处理。这样,您可以查看您自己函数的任何特定调用链是否会反复导致崩溃,无论中间调用了哪些外部函数。

那么当然,一些更复杂的问题无论如何也不会被这样捕获,因为堆栈跟踪将完全不同。为了帮助实现这一点,您可以记录应用程序中的其他数据以及每个报告中的堆栈跟踪,例如缓冲区大小、计数器、应用程序不同部分的状态等等……然后对此进行一些统计。

于 2011-01-06T21:19:55.080 回答