Back to index

glibc  2.9
backtrace.c
Go to the documentation of this file.
00001 /* Return backtrace of current program state.  Generic version.
00002    Copyright (C) 1998, 2000, 2002, 2004, 2005 Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
00005 
00006    The GNU C Library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Lesser General Public
00008    License as published by the Free Software Foundation; either
00009    version 2.1 of the License, or (at your option) any later version.
00010 
00011    The GNU C Library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Lesser General Public License for more details.
00015 
00016    You should have received a copy of the GNU Lesser General Public
00017    License along with the GNU C Library; if not, write to the Free
00018    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00019    02111-1307 USA.  */
00020 
00021 #include <execinfo.h>
00022 #include <signal.h>
00023 #include <frame.h>
00024 #include <sigcontextinfo.h>
00025 #include <bp-checks.h>
00026 #include <ldsodefs.h>
00027 
00028 /* This implementation assumes a stack layout that matches the defaults
00029    used by gcc's `__builtin_frame_address' and `__builtin_return_address'
00030    (FP is the frame pointer register):
00031 
00032          +-----------------+     +-----------------+
00033     FP -> | previous FP --------> | previous FP ------>...
00034          |                 |     |                 |
00035          | return address  |     | return address  |
00036          +-----------------+     +-----------------+
00037 
00038   */
00039 
00040 /* Get some notion of the current stack.  Need not be exactly the top
00041    of the stack, just something somewhere in the current frame.  */
00042 #ifndef CURRENT_STACK_FRAME
00043 # define CURRENT_STACK_FRAME  ({ char __csf; &__csf; })
00044 #endif
00045 
00046 /* By default we assume that the stack grows downward.  */
00047 #ifndef INNER_THAN
00048 # define INNER_THAN <
00049 #endif
00050 
00051 /* By default assume the `next' pointer in struct layout points to the
00052    next struct layout.  */
00053 #ifndef ADVANCE_STACK_FRAME
00054 # define ADVANCE_STACK_FRAME(next) BOUNDED_1 ((struct layout *) (next))
00055 #endif
00056 
00057 /* By default, the frame pointer is just what we get from gcc.  */
00058 #ifndef FIRST_FRAME_POINTER
00059 # define FIRST_FRAME_POINTER  __builtin_frame_address (0)
00060 #endif
00061 
00062 int
00063 __backtrace (array, size)
00064      void **array;
00065      int size;
00066 {
00067   struct layout *current;
00068   void *__unbounded top_frame;
00069   void *__unbounded top_stack;
00070   int cnt = 0;
00071 
00072   top_frame = FIRST_FRAME_POINTER;
00073   top_stack = CURRENT_STACK_FRAME;
00074 
00075   /* We skip the call to this function, it makes no sense to record it.  */
00076   current = BOUNDED_1 ((struct layout *) top_frame);
00077   while (cnt < size)
00078     {
00079       if ((void *) current INNER_THAN top_stack
00080          || !((void *) current INNER_THAN __libc_stack_end))
00081        /* This means the address is out of range.  Note that for the
00082          toplevel we see a frame pointer with value NULL which clearly is
00083          out of range.  */
00084        break;
00085 
00086       array[cnt++] = current->return_address;
00087 
00088       current = ADVANCE_STACK_FRAME (current->next);
00089     }
00090 
00091   return cnt;
00092 }
00093 weak_alias (__backtrace, backtrace)
00094 libc_hidden_def (__backtrace)