Project

General

Profile

Actions

Bug #8357

open

abort(3C) messes up the stack

Added by Yuri Pankov over 6 years ago. Updated about 2 years ago.

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

Actions #1

Updated by Andy Fiddaman about 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

Also available in: Atom PDF