C++ 查找bad_alloc原因的调试策略
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2481933/
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
Debugging strategy to find the cause of bad_alloc
提问by Salami
I have a fairly serious bug in my program - occasional calls to new() throw a bad_alloc.
我的程序中有一个相当严重的错误 - 偶尔调用 new() 会抛出一个 bad_alloc。
From the documentation I can find on bad_alloc, it seems to be thrown for these reasons:
从我可以在 bad_alloc 上找到的文档中,它似乎由于以下原因被抛出:
When the computer runs out of memory (which definitely isn't happening, I have 4GB of RAM, program throws bad_alloc when using less than 5MB (checked in taskmanager) with nothing serious running in the background).
If the memory becomes too fragmented to allocate new blocks (which, again, is unlikely - the largest sized block I ever allocate would be about 1KB, and that doesn't get done more than 100 times before the crash occurs).
当计算机内存不足时(这绝对不会发生,我有 4GB 的 RAM,程序在使用小于 5MB(在任务管理器中检查)时抛出 bad_alloc,后台没有任何严重运行)。
如果内存变得太碎片化而无法分配新块(这也是不太可能的 - 我曾经分配的最大大小的块大约为 1KB,并且在崩溃发生之前不会超过 100 次)。
Based on these descriptions, I don't really have anywhere in which a bad_alloc could be thrown.
根据这些描述,我真的没有可以抛出 bad_alloc 的任何地方。
However, the application I am running runs more than one thread, which could possibly be contributing to the problem. By testing all of the objects on a single thread, everything seems to be working smoothly. The only other thing that I can think of that is going on here could be some kind of race-condition caused by calling new() in more than one place at the same time, but I've tried adding mutexes to prevent that behaviour to no effect.
但是,我正在运行的应用程序运行多个线程,这可能是导致问题的原因。通过在单个线程上测试所有对象,一切似乎都在顺利进行。我能想到的唯一另一件事可能是同时在多个地方调用 new() 引起的某种竞争条件,但我已经尝试添加互斥锁来防止这种行为没有效果。
Because the program is several hundred lines and I have no idea where the problem actually lies, I'm not sure of what, if any, code snippets to post. Instead, I was wondering if there were any tools that will help me test for this kind of thing, or if there are any general strategies that can help me with this problem.
因为程序有几百行,我不知道问题究竟出在哪里,所以我不确定要发布什么代码片段(如果有的话)。相反,我想知道是否有任何工具可以帮助我测试此类事情,或者是否有任何通用策略可以帮助我解决这个问题。
I'm using Microsoft Visual Studio 2008, with Poco for threading.
我正在使用 Microsoft Visual Studio 2008 和 Poco 进行线程处理。
采纳答案by Brooks Moses
Another possible problem is that, while you mention that the program is using less than 5MB, you don't mention how much space it's trying to allocate. You could have some race condition that's corrupting the value that you use to determine the allocation size, and it could be trying to allocate 37TB or somesuch nonsense.
另一个可能的问题是,虽然您提到程序使用的空间少于 5MB,但您没有提到它试图分配多少空间。你可能有一些竞争条件破坏了你用来确定分配大小的值,它可能试图分配 37TB 或一些类似的废话。
Not particularly likely, I suppose, but worth checking.
我想不太可能,但值得检查。
回答by John Knoeller
bad_alloc can also be thrown when you have a bug that is overwriting the pointers that the heap uses to manage the pool of memory that it uses to allocate from.
当您有一个错误覆盖堆用来管理它用来分配的内存池的指针时,也可能抛出 bad_alloc 。
The most common cause of that is that you are writing past the end of an allocated block of memory, (or before the start, but that's less common). Almost as common is writing to a memory block after it has been freed. This is called heap corruption.
最常见的原因是您写入的内容超过了已分配内存块的末尾(或在开始之前,但这种情况不太常见)。几乎同样常见的是在释放内存块后写入内存块。这称为堆损坏。
Also, I should note, a 32 bit process in Windows has at most 2GB of address space (3GB for large-address-aware programs). This is regardless of how much RAM you have installed, the memory is virtual, and allocations don't fail until you run out of address space, even if you only have 1GB of RAM.
另外,我应该注意到,Windows 中的 32 位进程最多具有 2GB 的地址空间(对于大型地址感知程序为 3GB)。这与您安装了多少 RAM 无关,内存是虚拟的,并且分配不会失败,直到您用完地址空间,即使您只有 1GB 的 RAM。
Here is a good discussion of memory corruption in C++ http://www.eventhelix.com/RealtimeMantra/Basics/debugging_software_crashes_2.htm
这是 C++ 中内存损坏的一个很好的讨论http://www.eventhelix.com/RealtimeMantra/Basics/debugging_software_crashes_2.htm
回答by aJ.
Few clarifications:
几点说明:
Every process in windows gets 4GB virtual memory, out of which 2GB is for user space and remaining for kernel space. The 4GB of RAM won't contribute to the virtual memory but it is for physical memory.
Windows 中的每个进程都有 4GB 的虚拟内存,其中 2GB 用于用户空间,其余用于内核空间。4GB 的 RAM 不会用于虚拟内存,但用于物理内存。
In the 2GB memory, all EXE, DLL gets loaded and hardly 1.6 - 1.7GB available for memory allocation. In this memory if there is no contiguous memory for allocation then the memory allocation fails.
在 2GB 内存中,所有 EXE、DLL 都被加载,几乎没有 1.6 - 1.7GB 可用于内存分配。在此内存中,如果没有连续的内存可供分配,则内存分配失败。
回答by Zan Lynx
bad_alloc can be thrown by other code as well.
bad_alloc 也可以被其他代码抛出。
I've seen it used by a limiting memory pool designed for use with STL containers. When the size limit was hit, it threw bad_alloc and the software just had to handle it.
我已经看到它被设计用于 STL 容器的限制内存池使用。当达到大小限制时,它会抛出 bad_alloc 并且软件只需要处理它。
回答by Timmmm
I've actually had this problem before and it was fixed by cleaning and rebuilding the project. Always worth a try when you have weird behaviour (unless it is a huge project that takes hours to compile).
我以前实际上遇到过这个问题,它通过清理和重建项目来解决。当你有奇怪的行为时总是值得一试(除非它是一个需要数小时编译的大型项目)。
回答by AndyJost
A strategy for debugging this would be to set a catchpoint in the debugger. In gdb one would say “catch throw” to ask the debugger you stop whenever the program throws an exception. You can refine that to catch only std::bad_alloc if the program throws and catches lots of exceptions in its normal course of business. The debugger will stop inside whichever allocation function generates std::bad_alloc, allowing you to poke around. In this case, you would quickly learn that number of bytes requested is not what you expect.
调试这个的策略是在调试器中设置一个捕获点。在 gdb 中,有人会说“catch throw”来要求调试器在程序抛出异常时停止。如果程序在其正常业务过程中抛出并捕获大量异常,您可以对其进行改进以仅捕获 std::bad_alloc 。调试器将在任何生成 std::bad_alloc 的分配函数内停止,允许您四处查看。在这种情况下,您会很快了解到请求的字节数不是您所期望的。