C++ 如果调试运行良好,但发布崩溃怎么办

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4012498/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 14:17:16  来源:igfitidea点击:

what to do if debug runs fine, but release crashes

c++debuggingcrashrelease

提问by Mat

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?

在这种情况下,我可以做些什么来追踪问题?

回答by Montdidier

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.

也许您正在删除一个未初始化的指针。在调试模式下它可以工作,因为指针被清空并且删除 ptr 将在 NULL 上正常工作。在发布时它是一些垃圾,然后删除 ptr 实际上会导致问题。

回答by Daniel Daranas

It could be two things:

这可能是两件事:

  • One or more of your assertions does necessary work apart from the check itself
  • Something else
  • 除了检查本身之外,您的一个或多个断言做了必要的工作
  • 别的东西

To rule out the former, try redefining assertas 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.

要排除前者,请尝试assert在调试版本中重新定义为空操作。如果缺少某些断言导致崩溃,您将看到它。否则,它是别的东西。

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.

最后,即使在调试模式下没有崩溃,运行内存检查器工具也可能有助于发现不正确的内存访问。

回答by Chubsdad

Two steps:

两个步骤:

a) Build release build with debug symbols (possible with VS at least)

b) Build release build without optimization

a) 使用调试符号构建发布版本(至少可以使用 VS)

b) 没有优化的构建发布构建

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.

如果问题发生在优化设置上,那么它真的很困难,必须以特定于情况的方式处理。

回答by StanOverflow

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:

我遇到了这个问题,在 Visual Studio 中发布/调试工作正常,单独调试工作,但单独发布崩溃。调试对我来说不是特别准确,我的解决方案是:

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.

在我的例子中,它传递了一个指向对函数来说太小的数组的指针。

回答by mart

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.

您确定两个版本都使用相同的版本.dll吗?我花了一个小时想知道为什么我的程序在调试模式下编译而不是在发布模式下编译,我只是忘记更新发布文件夹中的 dll。

回答by Grozz

Track down the problem inserting log output here and there right from the beginning of the mainfunction.

main函数一开始就跟踪在此处和此处插入日志输出的问题。

回答by B?ови?

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.

如果不是内存问题,则必须在发布中启用断言。对于内存问题,我希望你有好的单元测试。您可以使用 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.

顺便说一句,为什么人们在发布版本中禁用断言?在 99% 的情况下,它们不会导致性能问题,并且可以很好地检测错误。

回答by Samrat Patil

Take a crash dump using Microsoft debugdiagon 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.

在 Windows 上使用Microsoft debugdiag进行故障转储(它是免费的)并使用相同的方法分析转储。它为崩溃的函数提供了一个很好的调用堆栈。虽然,如果它一直在整个地方崩溃,则可能是堆损坏的问题。然后,您需要将全局标志(或 gflags,它是微软免费调试套件的一部分)与 debugdiag 结合使用。Gflags 将为您提供堆实际损坏的位置。希望有帮助。

回答by Aamir

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.

在大多数情况下,这是由于 Debug 构建可以防止的一些缓冲区溢出。

回答by user3864776

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.

对我来说,问题在于构造函数以错误的顺序初始化 2 个成员变量。即与它们声明的
顺序不同。我很惊讶初始化顺序实际上有任何不同。