如果调试运行正常,但发布崩溃该怎么办
我有一个应用程序在调试版本中运行得很好,但是当我在发布版本中启动它时,我得到一个“
unhandled Exception at 0x0043b134 in myapp.exe: 0xC0000005:
Access violation while reading at position 0x004bd96c
如果我单击“中断””,它告诉我没有加载任何符号,并且无法加载源代码显示。
在这种情况下我该怎么做才能找到问题所在?
I have an application that runs just fine in the debug build, but when I start it in the release build, I get a
unhandled Exception at 0x0043b134 in myapp.exe: 0xC0000005:
Access violation while reading at position 0x004bd96c
If I click on 'break' it tells me that there are no symbols loaded and the source code can't be displayed.
What can I do in such a situation to track down the problem?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
这类问题通常是由于变量的单位化造成的。我会从那里开始寻找你的问题。
调试模式更加宽容,因为它通常被配置为初始化尚未显式初始化的变量。
也许您正在删除一个统一化的指针。在调试模式下它可以工作,因为指针被清空并且删除 ptr 在 NULL 上也可以。发布时它是一些垃圾,然后删除 ptr 实际上会导致问题。
This kind of problem is often due to unitialized variables. I'd start there looking for your problem.
Debug mode is more forgiving because it is often configured to initialize variables that have not been explicitly initialized.
Perhaps you're deleting an unitialized pointer. In debug mode it works because pointer was nulled and delete ptr will be ok on NULL. On release it's some rubbish, then delete ptr will actually cause a problem.
可能是两件事:
要排除前者,请尝试在调试版本中将
assert
重新定义为空操作。如果缺少某些断言导致崩溃,您将会看到它。否则,那就是另外一回事了。另外,我假设你有版本控制。这才刚刚开始发生吗?您可以分析上周以来的代码更改。
最后,即使在调试模式下没有崩溃,运行内存检查器工具也可能有助于发现不正确的内存访问。
It could be two things:
To rule out the former, try redefining
assert
as an empty operation in the debug build. If the absence of some assertion causes the crash, you will see it. Otherwise, it's something else.Also, I assume you have version control. Did this just start happening? You can analyze the code changes from last week.
Finally, even in the absence of a crash in debug mode, running a memory checker tool may be useful to spot incorrect memory access.
两步:
如果问题仍然发生,那么很好并且很容易修复。问题似乎出在调试版本中。
如果问题发生在优化设置开启的情况下,那么问题就非常棘手,必须根据具体情况进行处理。
Two steps:
If the problem still happens, it is very good and easy to fix. It is almsot as if the problem is in debug build.
If the problem happens with optimization settings on, then it is really tough and has to be handled in situation specific manner.
您确定两个版本都使用相同的
.dll
吗?我花了一个小时想知道为什么我的程序在调试模式下编译而不是在发布模式下编译,而且我只是忘记更新发布文件夹中的 dll。Are you sure that both releases use the same
.dll
? I spend an hour wondering why my program did compile in debug mode but not in release mode and I just forgot to update the dll's in the release folder.跟踪从
main
函数开头处插入日志输出的问题。Track down the problem inserting log output here and there right from the beginning of the
main
function.如果不是内存问题,那么您必须在版本中启用断言。对于内存问题,我希望你能进行良好的单元测试。您可以使用 valgrind 轻松捕获此类问题。
顺便说一句,为什么人们在发布版本中禁用断言?在 99% 的情况下,它们不会导致性能问题,并且能够很好地检测错误。
If it is not a memory issue, then you have to enable asserts in the release. For memory issues, I hope you got good unit tests. You can easily catch such problems with valgrind.
btw why are people disabling asserts in the release version? In 99% cases they do not cause performance problems, and are good in detecting errors.
使用 进行故障转储Windows 上的 Microsoft debugdiag(免费)并使用相同的工具分析转储。它为崩溃的函数提供了一个很好的调用堆栈。不过,如果它不断崩溃,则可能是堆损坏的问题。然后,您需要将全局标志(或 gflags,它是免费的微软调试套件工具的一部分)与 debugdiag 结合使用。 Gflags 将为您提供堆实际损坏的位置。希望有帮助。
Take a crash dump using Microsoft debugdiag on windows(it's free) and analyze the dump using the same. It gives a nice call stack for the function where it crashes. Although, if it keeps crashing all over the place, it could be an issue of heap corruption. You then need to use global flags(or gflags which is a part of microsoft tools for debugging suite which is free) in conjunction with debugdiag. Gflags would give you the location where the heap is actually getting corrupted. Hope that helps.
我遇到了这个问题,发布/调试在 Visual Studio 中工作正常,独立调试工作,但发布独立崩溃。调试对我来说不是特别准确,我的解决方案是:
注释掉大部分代码,然后构建、测试、取消注释、重复,直到找到导致崩溃的部分。
就我而言,它传递了一个指向数组的指针,该数组对于函数来说太小了。
I had this problem, release/debug worked fine inside visual studio, debug work stand alone, but release crashed stand alone. Debugging was not particularly accurate for me, my solution was:
Comment out most of the code, then build, test, uncomment, repeat, until you find the section that causes the crash.
In my case it was passing a pointer to an array that was too small to a function.
不看代码,很难说出哪里不好。上述所有建议都很好并且很有帮助,但我发现解决此类问题最有帮助的是分块运行程序的某些部分。即,注释掉很多代码/功能,然后运行程序并查看它是否崩溃。如果没有,请取消注释某些功能,然后重新运行,依此类推。这样您就可以将问题范围缩小到导致此问题的确切代码。
在大多数情况下,发生这种情况是由于调试版本可以防止某些缓冲区溢出。
Without looking at the code, it is hard to tell what is bad. All the above suggestions are good and helpful but what I have found most helpful fixing this kind of things is to run certain parts of program in chunks. i.e., comment out a lot of code/functionality and then run the program and see if it crashes. If it doesn't, the uncomment some functionality and then re-run again and so on. This way you will be able to narrow down the problem to the exact code that is causing this.
In most of the cases this happens due to some Buffer overruns which Debug builds can guard against.
对我来说,问题是构造函数以错误的顺序初始化 2 个成员变量。即与声明的顺序不同。
我很惊讶初始化顺序实际上有什么不同。
For me, the problem was that a constructor was initializing 2 member variables in the wrong order. i.e. not the same order that they were declared in.
I'm surprised that initialization order actually makes any difference.