检测堆栈耗尽与Sigsegv的其他来源
在POSIX环境中,当一个过程耗尽其堆栈时,它会收到sigsegv
信号。
就我而言,我的程序用手工编写的递归下降解析器来解析其输入,如果输入文件具有特别深度嵌套的语法结构(想想编程语言的语法和输入文件,则可以耗尽其堆栈像f(f(f(f(f(f(f(y。)))))))
)。
我的程序可以选择使用此类情况以增加堆栈尺寸运行它,但是我想处理sigsegv
建议当sigsegv的原因时,建议用户使用该选项。 /代码>是堆栈耗尽。
是否有任何方法可以说该程序已收到sigsegv
,因为这个原因而不是其他错误?
In POSIX environments, when a process exhausts its stack it receives a SIGSEGV
signal.
In my case, my program parses its input with a hand-written recursively descent parser which can exhaust its stack if the input file has a particularly deeply nested grammatical structure (think of the grammar of a programming language and an input file with very deep nested calls like f(f(f(f(f(f(....))))))
).
My program has an option to run it with an increased stack size for cases like this, but I would like to handle SIGSEGV
to suggest the user to use that option when the cause of the SIGSEGV
is stack exhaustion.
Is there any way to tell that the program has received a SIGSEGV
because of this reason instead of any other bug?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
是的。
main(Main()
中记录当前的堆栈尺寸限制,使用 getrlimit (rlimit_stack
,...)。将其存储在某个全球。main()
中记录局部变量的地址,将其存储在另一个全局中。(char*)ptr_to_local_in_main-(char*)ptr_to_to_local_in_parser
。如果当前的堆栈使用情况在(例如)限制的4-8KIB内,则您处于危险区域。那时,您可以:
in_danger_zone
flag,请通过sigsegv
处理程序检查。另外,您只需记录
ptr_to_local_in_parser
,在您的信号处理程序中查看ptr_to_to_local_in_ {main,parser}
之间的delta是否足够大,以至于可能堆叠堆积。在信号处理程序中,可以检查
ucontext_t
传递到其中,拆卸指令,弄清楚该指令是否操纵堆栈(例如push> push
,call
,mov 0x ...(%rsp)
等)并做出更精确的确定,但是复杂性可能是可能不值得您获得的额外准确性方式。Yes.
main()
, using getrlimit(RLIMIT_STACK
, ...). Store it in some global.main()
, store it in another global.(char*)ptr_to_local_in_main - (char*)ptr_to_local_in_parser
.IFF the current stack usage is within (say) 4-8KiB of the limit, you are in the danger zone. At that point you could:
in_danger_zone
flag, to be checked bySIGSEGV
handler.Alternatively, you could just record
ptr_to_local_in_parser
, and in your signal handler see whether the delta betweenptr_to_local_in_{main,parser}
is large enough that stack overflow is likely.It's possible in the signal handler to examine
ucontext_t
passed into it, disassemble the instruction, figure out whether that instruction manipulates the stack (e.g.PUSH
,CALL
,MOV 0x...(%RSP)
, etc.) and make a more precise determination, but the complexity is probably not worth the additional accuracy you would get this way.