刚进入函数时什么会导致段错误?
输入的函数如下所示:
21: void eesu3(Matrix & iQ)
22: {
其中 Matrix 是一个 struct。当使用 GDB 运行时,回溯产生:
(gdb) backtrace
#0 eesu3 (iQ=...) at /home/.../eesu3.cc:22
#1 ...
GDB 没有说明什么是iQ。 ... 确实存在。
什么会导致这个?
海湾合作委员会:(Ubuntu/Linaro 4.6.3-1ubuntu5)4.6.3
使用-O3 -g构建的程序
来电者是这样的:
Matrix q;
// do some stuff with q
eesu3(q);
这里没什么特别的
我用 valgrind 重新运行程序:
valgrind --tool=memcheck --leak-check=yes --show-reachable=yes --num-callers=20 --track-fds=yes <prgname>
输出:
==2240== Warning: client switching stacks? SP change: 0x7fef7ef68 --> 0x7fe5e3000
==2240== to suppress, use: --max-stackframe=10076008 or greater
==2240== Invalid write of size 8
==2240== at 0x14C765B: eesu3( Matrix &) (eesu3.cc:22)
...
==2240== Address 0x7fe5e3fd8 is on thread 1's stack
==2240==
==2240== Can't extend stack to 0x7fe5e2420 during signal delivery for thread 1:
==2240== no stack segment
==2240==
==2240== Process terminating with default action of signal 11 (SIGSEGV)
==2240== Access not within mapped region at address 0x7FE5E2420
==2240== at 0x14C765B: eesu3( Matrix&) (eesu3.cc:22)
==2240== If you believe this happened as a result of a stack
==2240== overflow in your program's main thread (unlikely but
==2240== possible), you can try to increase the size of the
==2240== main thread stack using the --main-stacksize= flag.
==2240== The main thread stack size used in this run was 8388608.
看起来它是一个损坏的堆栈。
Dump of assembler code for function eesu3( Matrix & ):
0x00000000014c7640 <+0>: push %rbp
0x00000000014c7641 <+1>: mov %rsp,%rbp
0x00000000014c7644 <+4>: push %r15
0x00000000014c7646 <+6>: push %r14
0x00000000014c7648 <+8>: push %r13
0x00000000014c764a <+10>: push %r12
0x00000000014c764c <+12>: push %rbx
0x00000000014c764d <+13>: and $0xfffffffffffff000,%rsp
0x00000000014c7654 <+20>: sub $0x99b000,%rsp
=> 0x00000000014c765b <+27>: mov %rdi,0xfd8(%rsp)
好吧,说清楚一点:Matrix 的数据存在于堆中。它基本上包含一个指向数据的指针。该结构很小,只有 32 个字节。 (刚刚检查过)
现在,我用不同的优化选项重建了程序:
-O0:错误不显示。
-O1:确实显示错误。
-O3:确实显示错误。
--更新
-O3 -fno-inline -fno-inline-functions: 错误不显示。
这就解释了。函数内联过多导致堆栈使用过多。
问题是由于堆栈溢出
最佳答案
What can cause a segmentation fault when just entering a function?
最常见的原因是堆栈耗尽。做(gdb) disas在崩溃点。如果崩溃的指令是在 %rsp 之后第一次读取或写入堆栈位置已经递减,那么堆栈耗尽几乎肯定是原因。
解决方案通常涉及创建具有更大堆栈的线程,将一些大变量从堆栈移动到堆,或两者兼而有之。
另一个可能的原因:如果Matrix包含非常大的数组,您不能将它放在堆栈上:内核不会将堆栈扩展到当前堆栈之外超过 128K(大约,我不记得确切的值)。如果Matrix大于这个限制,你不能把它放在堆栈上。
更新:
0x00000000014c7654 <+20>: sub $0x99b000,%rsp
=> 0x00000000014c765b <+27>: mov %rdi,0xfd8(%rsp)
这个反汇编证实了诊断。
此外,您在堆栈上保留了 0x99b000 字节(几乎是 10MB)。在 eesu3 中一定有一些您试图在堆栈上定位的巨大对象常规。不要那样做。
What do you mean by "the kernel will not extend stack beyond current by more than"
当您扩展堆栈(递减 %rsp )时,例如1MB,然后尝试触摸该堆栈位置,内存将不可访问(内核按需增长堆栈)。这将生成一个硬件陷阱,并将控制权转移到内核。当内核决定做什么时,它会查看
%rsp 如果故障地址低于当前 %rsp ,但在 128K(或其他类似大小的常量)内,内核只是扩展堆栈(前提是这种扩展不会超过堆栈限制)。
如果故障地址比当前地址低 128K 以上 %rsp (就像这里的情况一样),你得到 SIGSEGV .
这对大多数程序来说都很好:即使它们在递归过程中使用大量堆栈,它们通常也会以小块的形式扩展堆栈。但是试图在单个例程中保留所有堆栈的等效程序会崩溃。
无论如何,做(gdb) info locals在崩溃点,看看本地人可能需要 10MB 的堆栈。然后将它们移动到堆中。
更新 2:
No locals
啊,程序可能还没有进入 eesu3因为有本地人。
when building with -O0 the error disappears. GCC bug?
这可能是 GCC 错误,但更有可能是 GCC 将许多其他例程内联到 eesu3 中。 ,并且每个内联例程都需要自己的 N KB 堆栈。如果构建包含 eesu3 的源代码,问题是否会消失?与 -fno-inline ?
不幸的是,对此类行为进行分类并找出适当的解决方法或修复 GCC,需要编译器专业知识。您可以先使用 -fdump-tree-all 进行编译并查看生成的 <source>.*t.*文件。这些包含编译过程各个阶段的 GCC 内部表示的文本转储。您可能能够充分理解它以取得进一步的进步。
关于c++ - 输入函数时的 SIGSEGV,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10499400/
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
我正在尝试用ruby中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了
我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin
如何在Ruby中按名称传递函数?(我使用Ruby才几个小时,所以我还在想办法。)nums=[1,2,3,4]#Thisworks,butismoreverbosethanI'dlikenums.eachdo|i|putsiend#InJS,Icouldjustdosomethinglike:#nums.forEach(console.log)#InF#,itwouldbesomethinglike:#List.iternums(printf"%A")#InRuby,IwishIcoulddosomethinglike:nums.eachputs在Ruby中能不能做到类似的简洁?我可以只
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时
已经有一个问题回答了如何将“America/Los_Angeles”转换为“PacificTime(US&Canada)”。但是我想将“美国/太平洋”和其他过时的时区转换为RailsTimeZone。我无法在图书馆中找到任何可以帮助我完成此任务的东西。 最佳答案 来自RailsActiveSupport::TimeZonedocs:TheversionofTZInfobundledwithActiveSupportonlyincludesthedefinitionsnecessarytosupportthezonesdefinedb
我需要一个通过输入字符串进行计算的方法,像这样function="(a/b)*100"a=25b=50function.something>>50有什么方法吗? 最佳答案 您可以使用instance_eval:function="(a/b)*100"a=25.0b=50instance_evalfunction#=>50.0请注意,使用eval本质上是不安全的,尤其是当您使用外部输入时,因为它可能包含注入(inject)的恶意代码。另请注意,a设置为25.0而不是25,因为如果它是整数a/b将导致0(整数)。
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我