本文介绍了vallocind不检测的malloc_consolidate(malloc.c)中的分段错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 我的程序进入分段错误,我找不到原因。 GDB确认错误并产生回溯: 编程接收信号SIGSEGV,分段故障。 0xb7da6d6e在malloc.c中的malloc_consolidate(av =< value optimized out>):5169 5169 malloc.c:没有这样的文件或目录。 in malloc.c (gdb)bt #0 0xb7da6d6e in malloc_consolidate(av =< value optimized out>)at malloc.c:5169 #1 0xb7da9035 in _int_malloc在malloc.c:4373 #2 0xb7dab4ac在__libc_malloc(字节= 525)中在malloc.c:3660 处理(av =< value optimized out>,bytes =< value optimized out> 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&)()来自/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)()来自/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)()来自/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 $地址:: GetS(this = 0xbfffec40)at address.cc:27 27 oss<< b $ b(gdb)f 13 #13 0x08049c42 m_address; (gdb)p this-> m_address $ 1 = 1 class Address的 GetS 将一个数字( uint32_t m_address )转换为字符串并返回。代码(非常简单)如下: std :: string Address :: GetS b $ b { std :: ostringstream oss; oss<< m_address; return oss.str();此外,从backtrace可以看出, m_address 已正确定义。 现在,我尝试使用valgrind运行我的程序。 程序不会崩溃,可能是因为valgrind替换了 malloc()以及其他函数。 错误摘要显示没有内存泄漏: 漏洞摘要:绝对丢失:0字节块间接丢失:0块在0块可能丢失:4,367字节在196块仍然可达:198块在198块抑制:0块0块 所有可能丢失 / p> 在0x4024B64的5个块中的80个字节可能丢失在$ 26 的丢失记录3中:operator new(unsigned int) (在/usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) by 0x40DBDB4:std :: string :: _ Rep :: _ S_create(unsigned int,unsigned int,std :: allocator< char> const& )(在/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)(在/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&)(在/usr/lib/i386-linux-gnu/libstdc++.so.6.0.16中) by 0x806AF62:sim: :UserGenerator :: CreateUser(unsigned int)(user-generator.cc:152) 此链接之后找到相关代码。 / p> 我想到了 libstdc ++ 中的错误。然而,这有多可能? 我也升级了这样的库。以下是我的系统目前安装的版本。 $ dpkg -l | grep libstdc ii libstdc ++ 5 1:3.3.6-23 GNU标准C ++库v3 ii libstdc ++ 6 4.6.1-1 GNU标准C ++库v3 ii libstdc + + 6-4.1-dev 4.1.2-27 GNU标准C ++库v3(开发文件) ii libstdc ++ 6-4.3-dev 4.3.5-4 GNU标准C ++库v3(开发文件) ii libstdc ++ 6-4.4-dev 4.4.6-6 GNU标准C ++库v3(开发文件) ii libstdc ++ 6-4.5-dev 4.5.3-3 GNU标准C ++库v3 (开发文件) ii libstdc ++ 6-4.6-dev 4.6.1-1 GNU标准C ++库v3(开发文件) 现在的事情是,我不知道哪个版本 g ++ 使用,是否有一些方法强制使用特定的版本。 我想要的是修改 GetS 。但这是我知道的唯一的方法。你建议任何替代方案吗? 最后,我甚至考虑用简单的 std :: string c $ c> char * 。 任何有价值的想法? $ b 先谢谢大家。 Best, Jir 解决方案好的。这是不的问题: 我想到libstdc ++中的错误 问题是你覆盖了一些内存缓冲区并损坏了内存管理器使用的一个结构。困难的部分将要找到它。 不要这样做: 最后,我甚至考虑用更简单的char *替换std :: string。也许有点激烈,但我不会放在一边。 您已经有足够的内存管理问题。这只会增加更多的问题。有std :: string或内存管理例程的绝对 NOTHING 错误。他们经过严格测试和使用。 在 http://读取您的代码。 mercurial.intuxication.org/hg/lte_sim/file/c2ef6e0b6d41/src / 似乎你仍然停留在C风格的写代码( C with Classes )。所以你有C ++的力量自动化(代码的爆炸),但仍然有与C相关的所有问题。 你需要重新看看你的代码的所有权。你用指针方式传递东西太多了。因此,很难跟踪指针的所有权(因此谁负责删除它)。 我认为你最好打赌,找到的错误是写单元测试每个类。然后通过val-grind运行单元测试。我知道它的痛苦(但你应该已经开始,现在你有痛苦所有一次)。 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:Program received signal SIGSEGV, Segmentation fault.0xb7da6d6e in malloc_consolidate (av=<value optimized out>) at malloc.c:51695169 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:2727 oss << m_address;(gdb) p this->m_address$1 = 1Method GetS of class Address translates a number (uint32_t m_address) into a string and returns it. The code (very simple) is the following:std::stringAddress::GetS () const{ std::ostringstream oss; oss << m_address; return oss.str ();}Besides, as can be seen in the backtrace, m_address is properly defined.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.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 blocksAll possibly lost refer to backtraces like this: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.$ dpkg -l | grep libstdcii libstdc++5 1:3.3.6-23 The GNU Standard C++ Library v3ii libstdc++6 4.6.1-1 GNU Standard C++ Library v3ii 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.What I am pondering is to modify GetS. But this is the only method I know. Do you suggest any alternative?Eventually, I am even considering to replace std::string with simpler char*.Maybe a little drastic, but I wouldn't set it aside.Any thought in merit?Thank you all in advance.Best,Jir 解决方案 Ok. This is NOT the problem: I am thinking of a bug in 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.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.You already have enough problems with memory management. This will just add more problems. There is absolutely NOTHING wrong 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).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.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). 这篇关于vallocind不检测的malloc_consolidate(malloc.c)中的分段错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
09-03 05:30