在客户环境中创建内存转储好吗?
我的程序面临严重的问题,该问题只能在客户处重现。 放置日志并没有帮助,因为我怀疑故障发生在第三方 dll 中。 由于某些原因,我无法从图书馆提供商那里获得帮助。 我正在考虑在故障点生成转储,以便离线分析它。 这是推荐的做法吗? 或者有什么替代方案吗?
I am facing a severe problem with my program, which gets reproduced only in the customer place. Putting logs, are not helping as I doubt the failure is happening in a third party dll. For some reasons, I couldn't get help from the library provider. I am thinking of producing a dump at the point of failure, so that to analyze it offline. Is this a recommended practice? Or any alternatives?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
是的,这是每个程序都应该拥有并尽可能经常使用的东西。
我建议你不要使用第三方库。 相反,创建您自己的转储。 这非常简单直接。 您基本上需要执行以下操作:
您的程序需要访问dbghelp.dll。 它是一个 Windows DLL,允许您创建人类可读的调用堆栈等。调试器使用此 DLL 来显示进程中的数据。 它还处理事后调试,即某种类型的转储。 该 dll 可以安全地与您的软件一起分发。 我建议您下载并安装Windows 调试工具。 这将使您可以访问各种工具,最好的工具 WinDbg.exe 和最新的 dbghelp.dll 也在该发行版中。
在 dbghelp.dll 中,您调用例如 MiniDumpWriteDump(),它将创建转储文件,或多或少就是这样。 你完成了。 一旦您拿到该文件,就可以开始使用它。 在 Visual Studio 调试器(甚至可能与 .dmp 文件扩展名相关)中或在 WinDbg 中。
现在,当您这样做时,有一些事情需要考虑。 当检查这样的转储文件时,您需要在编译和链接可执行文件时生成 .pdb 文件。 否则,就没有机会将转储数据映射到人类可读的数据,例如获得良好的调用堆栈和变量值等。这也意味着您必须保存这些 .pdb 文件。 您需要能够将它们与该版本完全匹配。 由于转储文件带有可执行文件的日期戳,因此调试器需要准确的 pdb 文件。 如果您的代码没有任何改变,那并不重要,如果 .pdb 文件属于另一个编译会话,那么您就完了。
我鼓励每个 Windows win32 开发人员查看 Oleg Starodumov 的网站 DebugInfo.com。 它包含大量示例和教程以及如何配置和调整转储文件生成。 当然,有多种方法可以排除某些数据、创建自定义调试消息以附加到转储等。
请记住,小型转储将包含有关异常时应用程序状态的非常有限的信息。 代价是文件很小(大约 50-100 kB,具体取决于您的设置)。 但如果您愿意,您可以创建一个完整转储,其中将包含整个应用程序的状态,即全局变量甚至内核对象。 这些文件可能很大,并且只应在极端情况下使用。
如果存在法律方面的问题,只需确保您的客户知道您在做什么即可。 我敢打赌你已经签订了一些合同,其中你不应该泄露商业秘密或其他法律方面的内容。 如果客户抱怨,请让他们相信发现错误是多么重要,并且这将极大地提高软件的质量。 或多或少地提高了质量,而无需付出任何代价。 如果他们不需要付出任何代价,这也是一个很好的论据:)
最后,如果您想阅读有关故障转储分析的更多信息,这里还有另一个很棒的网站:dumpanalysis.org
希望这会有所帮助。 如果您想让我解释更多,请评论。
干杯!
编辑:
只是想添加 MiniDumpWriteDump() 要求您有一个指向 MINIDUMP-EXCEPTION-INFORMATION (带下划线)结构的指针。 但是 GetExceptionInformation() 宏在异常处理程序(结构化异常处理或 SEH)中发生异常时为您提供了这一点:
YourHandlerFunction() 将负责生成小型转储(或其他一些调用链中的函数)。 另外,如果您的程序中有自定义错误,例如发生了不应发生但技术上不属于异常的情况,您可以使用 RaiseException() 来创建自己的错误。
GetExceptionInformation() 只能在此上下文中使用,在程序执行期间不能在其他地方使用。
Yes, this is something that every program should have and utilize as often as possible.
I suggest that you don't use third party libraries. Create your own dumps instead. It's very simple and straight forward. You basically need to do the following:
Your program needs to access dbghelp.dll. It's a windows dll that allows you to create human readable call stacks etc. The debugger uses this dll to display data in your process. It also handles post mortem debugging, i.e. dumps of some sort. This dll can safely be distributed with your software. I suggest that you download and install Debugging Tools for Windows. This will give you access to all sorts of tools and the best tool WinDbg.exe and the latest dbghelp.dll is also in that distribution.
In dbghelp.dll you call e.g. MiniDumpWriteDump(), which will create the dump file and that's more or less it. You're done. As soon as you have that file in your hands, you can start using it. Either in the Visual Studio Debugger, which probably even might be associated with the .dmp file extension, or in WinDbg.
Now, there are a few things to think of while you're at it. When checking dump files like this, you need to generate .pdb files when you compile and link your executable. Otherwise there's no chance of mapping the dump data to human readable data, e.g. to get good callstacks and values of variables etc. This also means that you have to save these .pdb files. You need to be able to match them exactly against that very release. Since the dump files are date stamped with the date stamp of the executable, the debugger needs the exact pdb files. It doesn't matter if your code hasn't changed a single bit, if the .pdb files belong to another compilation session, you're toast.
I encourage every windows win32 developer to check out Oleg Starodumov's site DebugInfo.com. It contains a lot of samples and tutorials and how you can configure and tune your dump file generation. There are of course a myriad of ways to exclude certain data, create your custom debug message to attach to the dump etc.
Keep in mind that minidumps will contain very limited information about the application state at exception time. The trade off is a small file (around 50-100 kB depending on your settings). But if you want, you can create a full dump, which will contain the state of the whole application, i.e. globals and even kernel objects. These files can be HUGE and should only be used at extreme cases.
If there are legal aspects, just make sure your customers are aware of what you're doing. I bet you already have some contract where you aren't supposed to reveal business secrets or other legal aspects. If customers complain, convince them how important it is to find bugs and that this will improve the quality of the software drastically. More or less higher quality at the cost of nothing. If it doesn't cost them anything, that's also a good argument :)
Finally, here's another great site if you want to read up more on crash dump analysis: dumpanalysis.org
Hope this helps. Please comment if you want me to explain more.
Cheers !
Edit:
Just wanted to add that MiniDumpWriteDump() requires that you have a pointer to a MINIDUMP-EXCEPTION-INFORMATION (with underscores) struct. But the GetExceptionInformation() macro provides this for you at time of exception in your exception handler (structured exception handling or SEH):
YourHandlerFunction() will be the one taking care of generating the minidump (or some other function down the call chain). Also, if you have custom errors in your program, e.g. something happens that should not happen but technically is not an exception, you can use RaiseException() to create your own.
GetExceptionInformation() can only be used in this context and nowhere else during program execution.
故障转储是一种非常常见的故障排除方法,并且非常有效,特别是对于仅在客户站点重现的问题。
只需确保客户/客户了解您在做什么并且您已获得许可。 故障转储可能包含客户可能不希望(或不被允许)走出门或通过网络泄露的敏感信息。
Crash dumps are a pretty common troubleshooting method and can be very effective, especially for problems that only reproduce at the customer's site.
Just make sure the customer/client understands what you're doing and that you have permission. It's possible that a crash dump can have sensitive information that a customer may not want (or be permitted) to let walk out the door or over the wire.
比这更好的是,有一些库可以将崩溃数据上传回给您。
BugDump 和 BugSplat
还有微软的方法:
http://msdn .microsoft.com/en-us/library/aa936273.aspx
Better than that there are libraries that will upload crash data back you.
BugDump and BugSplat
And there's the Microsoft way:
http://msdn.microsoft.com/en-us/library/aa936273.aspx
免责声明:我不是律师,也不会假装是律师,这不是法律建议。
您可以在日志和故障转储中包含的数据还取决于您所在的域。例如,医疗设备和患者信息系统通常包含有关患者的敏感数据,未经授权的人员不应看到这些数据。
不可能将健康信息与个人联系起来。 故障转储和日志应该匿名并删除任何敏感信息,或者根本不发送。
也许这不适用于您的具体情况,因此这更多的是一般性说明。 我认为它适用于处理敏感信息的其他领域,例如军事和金融等。
Disclaimer: I am not a lawyer, nor do I pretend to be one, this is not legal advice.
The data you can include in logs and crash dumps also depend on what domain you are working in. For example, medical equipment and patient information systems often contain sensitive data about patients that should not be visible to unauthorized persons.
It should not be possible to link health information to an individual. The crash dumps and logs should be anonymized and stripped of any sensitive information, or not sent at all.
Maybe this does not apply to your specific case, so this is more of a general note. I think it applies to other domains that handle sensitive information, such as military and financial, and so on.
基本上,生成转储文件的最简单方法是使用 adplus。 您不需要更改您的代码。
正如上面的文章中提到的,Adplus是Windows调试工具的一部分。
Adplus基本上是windbg的一个巨大的vbscript自动化。
使用 adplus 需要执行的操作:
重现您的 将得到一个包含您需要的所有信息的小型转储。
您可以在您最喜欢的调试器中打开故障转储。
在 Windbg 中,“analyze -v”命令帮助我解决了至少 40% 的仅发生在客户站点且无法在内部重现的崩溃。
Basically the easiest way to produce a dumpfile is by using adplus. You don't need to change your code.
Adplus is part of the debugging tools for windows, as mentioned in the article above.
Adplus is basically a huge vbscript automation of windbg.
What you have to do to use adplus:
you'll get a minidump with all the information you need.
you can open the crash dump in your favorite debugger.
within windbg, the command "analyze -v" helped me in at least 40% of all the crashes that only happened at customer site and were not reproducible in house.