linux – gnu C库在向量分配期间卡在循环中
运行
linux内核3.6.6-1,gcc 4.7.2-2,以下程序:
1 #include <vector> 2 using namespace std; 3 int main () 4 { 5 vector<size_t> a (1 << 24); 6 return 0; 7 } 永远不会从第5行返回. 当我在gdb中运行时,我发现它在第743/744行被卡在stl_algobase.h中: 0x000000000040101c in std::__fill_n_a<unsigned long*,unsigned long,unsigned long> (__first=0x7fffeffd8060,__n=16777216,__value=@0x7fffffffe0a8: 0) at /usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/bits/stl_algobase.h:743 740 __fill_n_a(_OutputIterator __first,_Size __n,const _Tp& __value) 741 { 742 const _Tp __tmp = __value; 743 for (__decltype(__n + 0) __niter = __n; 744 __niter > 0; --__niter,++__first) 745 *__first = __tmp; 746 return __first; 747 } __niter只保持值1,永远不会倒数到0. 仅在我的系统运行一段时间后才会出现此问题.当它发生时,整个系统似乎都被淹没了.也就是说,gui很快停止响应,但我可以ssh并做一些事情,但最终整个系统变得无法使用,我重新启动. 重新启动后,上述程序按预期运行. 显然,问题不在于我的程序.这只是一个更大问题的症状. 我的问题是:接下来我该怎么办? 我检查了所有错误日志,什么也没找到.我没有得到硬件异常或类似的东西,所以我很难确切知道我的系统何时进入这种状态. 我没有想法,所以任何帮助都会非常感激. 编辑: 我将编译器选项更改为-g -Wall并获得相同的结果. 这是__fill_n_a的反汇编(带有新选项): 1 0x00000000004010bd <+0>: push %rbp 2 0x00000000004010be <+1>: mov %rsp,%rbp 3 0x00000000004010c1 <+4>: mov %rdi,-0x18(%rbp) 4 0x00000000004010c5 <+8>: mov %rsi,-0x20(%rbp) 5 0x00000000004010c9 <+12>: mov %rdx,-0x28(%rbp) 6 0x00000000004010cd <+16>: mov -0x28(%rbp),%rax 7 0x00000000004010d1 <+20>: mov (%rax),%rax 8 0x00000000004010d4 <+23>: mov %rax,-0x10(%rbp) 9 0x00000000004010d8 <+27>: mov -0x20(%rbp),%rax 10 0x00000000004010dc <+31>: mov %rax,-0x8(%rbp) 11 0x00000000004010e0 <+35>: jmp 0x4010f7 <std::__fill_n_a<unsigned long*,unsigned long>(unsigned long*,unsigned long const&)+58> 12 0x00000000004010e2 <+37>: mov -0x18(%rbp),%rax 13 0x00000000004010e6 <+41>: mov -0x10(%rbp),%rdx 14 0x00000000004010ea <+45>: mov %rdx,(%rax) 15 0x00000000004010ed <+48>: subq $0x1,-0x8(%rbp) 16 0x00000000004010f2 <+53>: addq $0x8,-0x18(%rbp) 17 0x00000000004010f7 <+58>: cmpq $0x0,-0x8(%rbp) 18 0x00000000004010fc <+63>: setne %al 19 0x00000000004010ff <+66>: test %al,%al 20 0x0000000000401101 <+68>: jne 0x4010e2 <std::__fill_n_a<unsigned long*,unsigned long const&)+37> 21 0x0000000000401103 <+70>: mov -0x18(%rbp),%rax 22 0x0000000000401107 <+74>: pop %rbp 23 0x0000000000401108 <+75>: retq 我还运行了我的系统内存诊断工具,没有任何错误,并且正如DL建议的那样,运行memtest86没有错误. 编辑: 我已经确认,通过在不同的计算机上运行相同的代码,这不是硬件问题.另一台机器安装了相同的内核和编译器软件,它以同样的方式失败. 我对ImageMagick很怀疑.这似乎只有在我运行了很多ImageMagick转换调用的脚本之后才会发生.我以前遇到过ImageMagick的问题,不得不设置shell变量MAGICK_THREAD_LIMIT = 1. 解决方法
您描述的整体症状听起来像是内存耗尽.如果系统内存使用读数不高,这可能是由于某种RAM问题,正如评论者所指出的那样.
你说:
但这没有多大意义 – __niter应该从16777216开始并倒数到0.如果你要随机进入这个程序,它几乎肯定会在这个循环中,但__niter的值几乎肯定不会1,如果你逐步完成循环,它似乎只是循环.我非常怀疑gcc 4.7发布的调试信息(实际上,自gcc 4.0以来它几乎是一个问题),因为gdb经常会打印出局部变量的错误值,但是如果你检查代码并看看和内存/寄存器直接你可以看到正确的值.如果这就是这里发生的事情,你的问题可能与这个程序无关;它的系统不稳定(可能是由于硬件问题)表现为悬挂,例如这个程序.鉴于此程序的作用,挂起可能发生在触及先前未触及的页面(获取页面错误)并且内核尝试分配页面时.这表明存在内存问题,但您注意到您已经运行了内存诊断程序.还要确保没有任何超频或超出规格的东西. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |