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, 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 Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the 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    Lesser General Public License for more details.
00014 
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with the GNU C Library; if not, write to the Free
00017    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018    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             | (unused)       |        | return address  |
00032             +----------------+        +-----------------+
00033 */
00034 struct layout
00035 {
00036   struct layout *__unbounded next;
00037   void *__unbounded return_address;
00038 };
00039 
00040 int
00041 __backtrace (void **array, int size)
00042 {
00043   struct layout *current;
00044   int count;
00045 
00046   /* Force gcc to spill LR.  */
00047   asm volatile ("" : "=l"(current));
00048 
00049   /* Get the address on top-of-stack.  */
00050   asm volatile ("lwz %0,0(1)" : "=r"(current));
00051   current = BOUNDED_1 (current);
00052 
00053   for (                            count = 0;
00054        current != NULL &&   count < size;
00055        current = BOUNDED_1 (current->next), count++)
00056     array[count] = current->return_address;
00057 
00058   /* It's possible the second-last stack frame can't return
00059      (that is, it's __libc_start_main), in which case
00060      the CRT startup code will have set its LR to 'NULL'.  */
00061   if (count > 0 && array[count-1] == NULL)
00062     count--;
00063 
00064   return count;
00065 }
00066 weak_alias (__backtrace, backtrace)
00067 libc_hidden_def (__backtrace)