Actions
Bug #8357
openabort(3C) messes up the stack
Status:
New
Priority:
Normal
Assignee:
-
Category:
-
Start date:
2017-06-09
Due date:
% Done:
0%
Estimated time:
Difficulty:
Medium
Tags:
needs-triage
Gerrit CR:
External Bug:
Description
The following simple test case shows the problem:
#include <stdlib.h> #include <ucontext.h> void e() { printstack(1); abort(); } void d() { e(); } void c() { d(); } void b() { c(); } void a() { b(); } int main(void) { a(); }
Running and looking at printstack()
output seems to be OK:
$ ./stack /home/yuri/stack'e+0x10 [0x8050d72] /home/yuri/stack'd+0xb [0x8050d85] /home/yuri/stack'c+0xb [0x8050d92] /home/yuri/stack'b+0xb [0x8050d9f] /home/yuri/stack'a+0xb [0x8050dac] /home/yuri/stack'main+0x16 [0x8050dc4] /home/yuri/stack'_start+0x83 [0x8050bf3] Abort (core dumped)
However (note the frame before abort()
itself, in more complex situations it could be worse, showing totally unrelated function names):
$ pstack core core 'core' of 101258: ./stack feed4857 _lwp_kill (1, 6, c, fef44000, fef44000, 8047c68) + 7 fee667cb raise (6, 0, 8047be0, 0, 0, 0) + 2b fee40fbe abort (fef70530, fef70530, 8047c38, 8050d85, 1f, 8050520) + 10e 08050d7a d (1f, 8050520, 8047c48, 8050d92, 0, 1) 08050d85 d (0, 1, 8047c58, 8050d9f, 0, feffb0a8) + b 08050d92 c (0, feffb0a8, 8047c68, 8050dac, 8060e64, 8047c68) + b 08050d9f b (8060e64, 8047c68, 8047c78, 8050dc4, feffb0a8, 8047c90) + b 08050dac a (feffb0a8) + b 08050dc4 main (feed6237, fef506c8, 8047ca8, 8050bf3, 1, 8047cb4) + 16 08050bf3 _start (1, 8047da0, 0, 8047da8, 8047dd8, 8047de9) + 83
Updated by Andy Fiddaman over 2 years ago
This is actually a problem with any call to a function marked as no-return, such as abort()
and upanic()
. In that case, gcc elides the calling function's epilogue so that the call to the no-return function is last:
> e::dis e: pushq %rbp e+1: movq %rsp,%rbp e+4: movl $0x1,%edi e+9: call -0x1a0 <PLT:printstack> e+0xe: call -0x195 <PLT:abort>
with the result that the return address pushed onto the stack is off the end of the function, e+0x13
in this case, which is the start of d()
.
> e::dis -a 4013f2 pushq %rbp 4013f3 movq %rsp,%rbp 4013f6 movl $0x1,%edi 4013fb call -0x1a0 <PLT=libc.so.1`printstack> 401400 call -0x195 <PLT=libc.so.1`abort> > d::dis -a 401405 pushq %rbp 401406 movq %rsp,%rbp 401409 movl $0x0,%eax 40140e call -0x21 <e> 401413 nop 401414 popq %rbp 401415 ret
Actions