Back to index

glibc  2.9
backtrace.c
Go to the documentation of this file.
00001 /* Return backtrace of current program state.
00002    Copyright (C) 1998, 2000, 2002, 2005 Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004 
00005    The GNU C Library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public License as
00007    published by the Free Software Foundation; either version 2 of the
00008    License, or (at your option) any later version.
00009 
00010    The GNU C Library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public
00016    License along with the GNU C Library; see the file COPYING.LIB.  If not,
00017    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00018    Boston, MA 02111-1307, USA.  */
00019 
00020 #include <execinfo.h>
00021 #include <stddef.h>
00022 #include <bp-checks.h>
00023 
00024 /* This is the stack layout we see with every stack frame.
00025    Note that every routine is required by the ABI to lay out the stack
00026    like this.
00027 
00028             +----------------+        +-----------------+
00029     %r1  -> | %r1 last frame--------> | %r1 last frame--->...  --> NULL
00030             |                |        |                 |
00031             | cr save        |        | cr save    |
00032             |                |        |                 |
00033             | (unused)       |        | return address  |
00034             +----------------+        +-----------------+
00035 */
00036 struct layout
00037 {
00038   struct layout *__unbounded next;
00039   long condition_register;
00040   void *__unbounded return_address;
00041 };
00042 
00043 int
00044 __backtrace (void **array, int size)
00045 {
00046   struct layout *current;
00047   int count;
00048 
00049   /* Force gcc to spill LR.  */
00050   asm volatile ("" : "=l"(current));
00051 
00052   /* Get the address on top-of-stack.  */
00053   asm volatile ("ld %0,0(1)" : "=r"(current));
00054   current = BOUNDED_1 (current);
00055 
00056   for (                            count = 0;
00057        current != NULL &&   count < size;
00058        current = BOUNDED_1 (current->next), count++)
00059     array[count] = current->return_address;
00060 
00061   /* It's possible the second-last stack frame can't return
00062      (that is, it's __libc_start_main), in which case
00063      the CRT startup code will have set its LR to 'NULL'.  */
00064   if (count > 0 && array[count-1] == NULL)
00065     count--;
00066 
00067   return count;
00068 }
00069 weak_alias (__backtrace, backtrace)
00070 libc_hidden_def (__backtrace)