valgrind 未检测到的 malloc_consolidate (malloc.c) 中的分段错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6725164/
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
Segmentation fault in malloc_consolidate (malloc.c) that valgrind doesn't detect
提问by Jir
My program goes in segmentation faults, and I cannot find the cause. The worst part is, the function in question does not always lead to segfault.
我的程序出现分段错误,我找不到原因。最糟糕的是,有问题的函数并不总是导致段错误。
GDB confirms the bug and yields this backtrace:
GDB 确认了这个错误并产生了这个回溯:
Program received signal SIGSEGV, Segmentation fault.
0xb7da6d6e in malloc_consolidate (av=<value optimized out>) at malloc.c:5169
5169 malloc.c: No such file or directory.
in malloc.c
(gdb) bt
#0 0xb7da6d6e in malloc_consolidate (av=<value optimized out>) at malloc.c:5169
#1 0xb7da9035 in _int_malloc (av=<value optimized out>, bytes=<value optimized out>) at malloc.c:4373
#2 0xb7dab4ac in __libc_malloc (bytes=525) at malloc.c:3660
#3 0xb7f8dc15 in operator new(unsigned int) () from /usr/lib/i386-linux-gnu/libstdc++.so.6
#4 0xb7f72db5 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Rep::_S_create(unsigned int, unsigned int, std::allocator<char> const&) ()
from /usr/lib/i386-linux-gnu/libstdc++.so.6
#5 0xb7f740bf in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Rep::_M_clone(std::allocator<char> const&, unsigned int) ()
from /usr/lib/i386-linux-gnu/libstdc++.so.6
#6 0xb7f741f1 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::reserve(unsigned int) () from /usr/lib/i386-linux-gnu/libstdc++.so.6
#7 0xb7f6bfec in std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >::overflow(int) () from /usr/lib/i386-linux-gnu/libstdc++.so.6
#8 0xb7f70e1c in std::basic_streambuf<char, std::char_traits<char> >::xsputn(char const*, int) () from /usr/lib/i386-linux-gnu/libstdc++.so.6
#9 0xb7f5b498 in std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<unsigned long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, unsigned long) const () from /usr/lib/i386-linux-gnu/libstdc++.so.6
#10 0xb7f5b753 in std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::do_put(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, unsigned long) const () from /usr/lib/i386-linux-gnu/libstdc++.so.6
#11 0xb7f676ac in std::basic_ostream<char, std::char_traits<char> >& std::basic_ostream<char, std::char_traits<char> >::_M_insert<unsigned long>(unsigned long) ()
from /usr/lib/i386-linux-gnu/libstdc++.so.6
#12 0xb7f67833 in std::basic_ostream<char, std::char_traits<char> >::operator<<(unsigned int) () from /usr/lib/i386-linux-gnu/libstdc++.so.6
#13 0x08049c42 in sim::Address::GetS (this=0xbfffec40) at address.cc:27
#14 0x0806a499 in sim::UserGenerator::ProcessEvent (this=0x80a1af0, e=...) at user-generator.cc:59
#15 0x0806694b in sim::Simulator::CommunicateEvent (this=0x809f970, e=...) at simulator.cc:144
#16 0x0806685d in sim::Simulator::ProcessNextEvent (this=0x809f970) at simulator.cc:133
#17 0x08065d76 in sim::Simulator::Run (seed=0) at simulator.cc:53
#18 0x0807ce85 in main (argc=1, argv=0xbffff454) at main.cc:75
(gdb) f 13
#13 0x08049c42 in sim::Address::GetS (this=0xbfffec40) at address.cc:27
27 oss << m_address;
(gdb) p this->m_address
= 1
Method GetS
of class Address translates a number (uint32_t m_address
) into a string and returns it. The code (very simple) is the following:
GetS
类 Address 的方法将数字 ( uint32_t m_address
) 转换为字符串并返回。代码(非常简单)如下:
std::string
Address::GetS () const
{
std::ostringstream oss;
oss << m_address;
return oss.str ();
}
Besides, as can be seen in the backtrace, m_address
is properly defined.
此外,正如在回溯中所见,m_address
是正确定义的。
Now, I have tried to run my program using valgrind.
The program doesn't crash, likely due to the fact that valgrind replaces malloc ()
among other functions.
现在,我尝试使用 valgrind 运行我的程序。程序不会崩溃,可能是因为 valgrind 替换malloc ()
了其他函数。
The error summary shows no memory leaking:
错误摘要显示没有内存泄漏:
LEAK SUMMARY:
definitely lost: 0 bytes in 0 blocks
indirectly lost: 0 bytes in 0 blocks
possibly lost: 4,367 bytes in 196 blocks
still reachable: 9,160 bytes in 198 blocks
suppressed: 0 bytes in 0 blocks
All possibly lost
refer to backtraces like this:
都possibly lost
指的是这样的回溯:
80 bytes in 5 blocks are possibly lost in loss record 3 of 26
at 0x4024B64: operator new(unsigned int) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
by 0x40DBDB4: std::string::_Rep::_S_create(unsigned int, unsigned int, std::allocator<char> const&) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16)
by 0x40DE077: char* std::string::_S_construct<char const*>(char const*, char const*, std::allocator<char> const&, std::forward_iterator_tag) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16)
by 0x40DE1E5: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16)
by 0x806AF62: sim::UserGenerator::CreateUser(unsigned int) (user-generator.cc:152)
I don't think this is related to the bug. However, the code in question can be found following this link.
我不认为这与错误有关。但是,可以在此链接后找到相关代码。
I am thinking of a bug in libstdc++
. However, how likely would that be?
I have also upgraded such library. Here's the versions currently installed on my system.
我在想一个错误libstdc++
。然而,这种可能性有多大?我也升级了这样的库。这是我系统上当前安装的版本。
$ dpkg -l | grep libstdc
ii libstdc++5 1:3.3.6-23 The GNU Standard C++ Library v3
ii libstdc++6 4.6.1-1 GNU Standard C++ Library v3
ii libstdc++6-4.1-dev 4.1.2-27 The GNU Standard C++ Library v3 (development files)
ii libstdc++6-4.3-dev 4.3.5-4 The GNU Standard C++ Library v3 (development files)
ii libstdc++6-4.4-dev 4.4.6-6 GNU Standard C++ Library v3 (development files)
ii libstdc++6-4.5-dev 4.5.3-3 The GNU Standard C++ Library v3 (development files)
ii libstdc++6-4.6-dev 4.6.1-1 GNU Standard C++ Library v3 (development files)
Now the thing is, I am not sure which version g++
uses, and whether there's some means to enforce the use of a particular version.
现在的问题是,我不确定g++
使用哪个版本,以及是否有某种方法可以强制使用特定版本。
What I am pondering is to modify GetS
. But this is the only method I know. Do you suggest any alternative?
我正在考虑的是修改GetS
. 但这是我知道的唯一方法。你有什么替代方案吗?
Eventually, I am even considering to replace std::string
with simpler char*
.
Maybe a little drastic, but I wouldn't set it aside.
最终,我什至考虑std::string
用更简单的char*
. 也许有点激烈,但我不会把它放在一边。
Any thought in merit?
有什么值得思考的吗?
Thank you all in advance.
谢谢大家。
Best, Jir
最好的,吉尔
回答by Martin York
Ok. This is NOTthe problem:
好的。这不是问题:
I am thinking of a bug in libstdc++
我在想 libstdc++ 中的一个错误
The problem is that you overwrote some memory buffer and corrupted one of the structures used by the memory manager. The hard part is going to be finding it. Does not valgrind give you information about writting past the end of an allocated piece of memory.
问题是您覆盖了一些内存缓冲区并损坏了内存管理器使用的结构之一。困难的部分将是找到它。valgrind 不会为您提供有关写入已分配内存的末尾的信息。
Don't do this:
不要这样做:
Eventually, I am even considering to replace std::string with simpler char*. Maybe a little drastic, but I wouldn't set it aside.
最终,我什至考虑用更简单的 char* 替换 std::string。也许有点激烈,但我不会把它放在一边。
You already have enough problems with memory management. This will just add more problems. There is absolutely NOTHINGwrong with std::string or the memory management routines. They are heavily tested and used. If there was something wrong people all over the world would start screaming (it would be big news).
您已经在内存管理方面遇到了足够多的问题。这只会增加更多的问题。std::string 或内存管理例程绝对没有错。它们经过大量测试和使用。如果出了什么问题,全世界的人都会开始尖叫(这将是个大新闻)。
Reading your code at http://mercurial.intuxication.org/hg/lte_sim/file/c2ef6e0b6d41/src/
it seems like you are still stuck in a C style of writting code (C with Classes
). So you have the power of C++ to automate (the blowing up of your code) but still have all the problems associated with C.
阅读您的代码http://mercurial.intuxication.org/hg/lte_sim/file/c2ef6e0b6d41/src/
似乎您仍然停留在编写代码的 C 风格中 ( C with Classes
)。所以你有 C++ 的力量来自动化(炸毁你的代码),但仍然有与 C 相关的所有问题。
You need to re-look at your code in terms of ownership. You pass things around by pointer way too much. As a result it is hard to follow the ownership of the pointer (and thus who is responsible for deleting it).
您需要根据所有权重新审视您的代码。你通过指针传递的东西太多了。因此,很难跟踪指针的所有权(以及谁负责删除它)。
I think you best bet at finding the bug is to write unit tests for each class. Then run the unit tests through val-grind. I know its a pain (but you should have done it to start with now you have the pain all in one go).
我认为找到错误的最好办法是为每个类编写单元测试。然后通过 val-grind 运行单元测试。我知道这很痛苦(但你应该一开始就这样做,现在你一下子就痛了)。