diff options
author | Ulrich Drepper <drepper@redhat.com> | 1998-06-12 07:36:49 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 1998-06-12 07:36:49 +0000 |
commit | ecdc196cac5e9e4b783cd77bb709eb6742a0184e (patch) | |
tree | de17c14556d0a4ffbeff5649a27ef2283fff60c7 /sysdeps/generic/backtrace.c | |
parent | b07d03e000b5c073e7768a6ca2e30578ac51f318 (diff) | |
download | glibc-ecdc196cac5e9e4b783cd77bb709eb6742a0184e.zip glibc-ecdc196cac5e9e4b783cd77bb709eb6742a0184e.tar.gz glibc-ecdc196cac5e9e4b783cd77bb709eb6742a0184e.tar.bz2 |
Update.
1998-06-11 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* sysdeps/generic/getenv.c: Fix last change.
1998-06-10 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* sysdeps/generic/backtrace.c: Provide generic implementation.
1998-06-10 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* configure.in: Give visual feedback of the default directories we
added.
1998-06-11 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* io/fts.c (fts_build): Define oflag only if needed.
1998-06-11 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* sysdeps/libm-ieee754/w_exp10.c: Add missing close comment.
Diffstat (limited to 'sysdeps/generic/backtrace.c')
-rw-r--r-- | sysdeps/generic/backtrace.c | 59 |
1 files changed, 54 insertions, 5 deletions
diff --git a/sysdeps/generic/backtrace.c b/sysdeps/generic/backtrace.c index 26bf9d4..7ac1d5f 100644 --- a/sysdeps/generic/backtrace.c +++ b/sysdeps/generic/backtrace.c @@ -1,4 +1,4 @@ -/* Return backtrace of current program state. +/* Return backtrace of current program state. Generic version. Copyright (C) 1998 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. @@ -21,14 +21,63 @@ #include <execinfo.h> +/* This is a global variable set at program start time. It marks the + highest used stack address. */ +extern void *__libc_stack_end; + + +/* This implementation assumes a stack layout that matches the defaults + used by gcc's `__builtin_frame_address' and `__builtin_return_address' + (FP is the frame pointer register): + + +-----------------+ +-----------------+ + FP -> | previous FP --------> | previous FP ------>... + | | | | + | return address | | return address | + +-----------------+ +-----------------+ + + */ + +/* Get some notion of the current stack. Need not be exactly the top + of the stack, just something somewhere in the current frame. */ +#ifndef CURRENT_STACK_FRAME +# define CURRENT_STACK_FRAME ({ char __csf; &__csf; }) +#endif + +struct layout +{ + struct layout *next; + void *return_address; +}; + int __backtrace (array, size) void **array; int size; { - /* We don't generally have the possibility to determine the stack - trace. Even gcc's `__builtin_return_address' feature cannot help - since it requires a constant argument. */ - return 0; + struct layout *current; + void *top_frame; + void *top_stack; + int cnt = 0; + + top_frame = __builtin_frame_address (0); + top_stack = CURRENT_STACK_FRAME; + + /* We skip the call to this function, it makes no sense to record it. */ + current = (struct layout *) top_frame; + while (cnt < size) + { + if ((void *) current < top_stack || (void *) current > __libc_stack_end) + /* This means the address is out of range. Note that for the + toplevel we see a frame pointer with value NULL which clearly is + out of range. */ + break; + + array[cnt++] = current->return_address; + + current = current->next; + } + + return cnt; } weak_alias (__backtrace, backtrace) |