(linenum→info "unix/slp.c:2238")

glibc/2.7/debug/backtrace.c

    1: /* Return backtrace of current program state.  Generic version.
    2:    Copyright (C) 1998, 2000, 2002, 2004, 2005 Free Software Foundation, Inc.
    3:    This file is part of the GNU C Library.
    4:    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
    5: 
    6:    The GNU C Library is free software; you can redistribute it and/or
    7:    modify it under the terms of the GNU Lesser General Public
    8:    License as published by the Free Software Foundation; either
    9:    version 2.1 of the License, or (at your option) any later version.
   10: 
   11:    The GNU C Library is distributed in the hope that it will be useful,
   12:    but WITHOUT ANY WARRANTY; without even the implied warranty of
   13:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   14:    Lesser General Public License for more details.
   15: 
   16:    You should have received a copy of the GNU Lesser General Public
   17:    License along with the GNU C Library; if not, write to the Free
   18:    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   19:    02111-1307 USA.  */
   20: 
   21: #include <execinfo.h>
   22: #include <signal.h>
   23: #include <frame.h>
   24: #include <sigcontextinfo.h>
   25: #include <bp-checks.h>
   26: #include <ldsodefs.h>
   27: 
   28: /* This implementation assumes a stack layout that matches the defaults
   29:    used by gcc's `__builtin_frame_address' and `__builtin_return_address'
   30:    (FP is the frame pointer register):
   31: 
   32:           +-----------------+     +-----------------+
   33:     FP -> | previous FP --------> | previous FP ------>...
   34:           |                 |     |                 |
   35:           | return address  |     | return address  |
   36:           +-----------------+     +-----------------+
   37: 
   38:   */
   39: 
   40: /* Get some notion of the current stack.  Need not be exactly the top
   41:    of the stack, just something somewhere in the current frame.  */
   42: #ifndef CURRENT_STACK_FRAME
   43: # define CURRENT_STACK_FRAME  ({ char __csf; &__csf; })
   44: #endif
   45: 
   46: /* By default we assume that the stack grows downward.  */
   47: #ifndef INNER_THAN
   48: # define INNER_THAN <
   49: #endif
   50: 
   51: /* By default assume the `next' pointer in struct layout points to the
   52:    next struct layout.  */
   53: #ifndef ADVANCE_STACK_FRAME
   54: # define ADVANCE_STACK_FRAME(next) BOUNDED_1 ((struct layout *) (next))
   55: #endif
   56: 
   57: /* By default, the frame pointer is just what we get from gcc.  */
   58: #ifndef FIRST_FRAME_POINTER
   59: # define FIRST_FRAME_POINTER  __builtin_frame_address (0)
   60: #endif
   61: 
   62: int
   63: __backtrace (array, size)
   64:      void **array;
   65:      int size;
   66: {
   67:   struct layout *current;
   68:   void *__unbounded top_frame;
   69:   void *__unbounded top_stack;
   70:   int cnt = 0;
   71: 
   72:   top_frame = FIRST_FRAME_POINTER;
   73:   top_stack = CURRENT_STACK_FRAME;
   74: 
   75:   /* We skip the call to this function, it makes no sense to record it.  */
   76:   current = BOUNDED_1 ((struct layout *) top_frame);
   77:   while (cnt < size)
   78:     {
   79:       if ((void *) current INNER_THAN top_stack
   80:           || !((void *) current INNER_THAN __libc_stack_end))
   81:        /* This means the address is out of range.  Note that for the
   82:           toplevel we see a frame pointer with value NULL which clearly is
   83:           out of range.  */
   84:         break;
   85: 
   86:       array[cnt++] = current->return_address;
   87: 
   88:       current = ADVANCE_STACK_FRAME (current->next);
   89:     }
   90: 
   91:   return cnt;
   92: }
   93: weak_alias (__backtrace, backtrace)
   94: libc_hidden_def (__backtrace)
Syntax (Markdown)