diff --git a/man3/backtrace.3 b/man3/backtrace.3 new file mode 100644 index 000000000..3ee5692c8 --- /dev/null +++ b/man3/backtrace.3 @@ -0,0 +1,245 @@ +.\" Copyright (C) 2007 Michael Kerrisk +.\" drawing on material by Justin Pryzby +.\" +.\" Permission is hereby granted, free of charge, to any person obtaining +.\" a copy of this software and associated documentation files (the +.\" "Software"), to deal in the Software without restriction, including +.\" without limitation the rights to use, copy, modify, merge, publish, +.\" distribute, sublicense, and/or sell copies of the Software, and to +.\" permit persons to whom the Software is furnished to do so, subject to +.\" the following conditions: +.\" +.\" The above copyright notice and this permission notice shall be +.\" included in all copies or substantial portions of the Software. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +.\" IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +.\" CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +.\" TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +.\" SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +.\" +.\" References: +.\" glibc manual and source +.TH BACKTRACE 3 "2007-06-22" GNU +.SH NAME +backtrace, backtrace_symbols, backtrace_symbols_fd \- support +for application self-debugging +.SH SYNOPSIS +.B #include + +.B int backtrace(void +.BI ** buffer , +.B int +.IB size ); + +.B char **backtrace_symbols(void *const +.BI * buffer , +.B int +.IB size ); + +.B void backtrace_symbols_fd(void *const +.BI * buffer , +.B int +.IB size , +.B int +.IB fd ); +.SH DESCRIPTION +.BR backtrace () +returns a backtrace for the calling program, +in the array pointed to by +.IR buffer . +A backtrace is the series of currently active function calls for +the program. +Each item in the array pointed to by +.I buffer +is of type \fIvoid *\fP, and is the return address from +the corresponding stack frame. +The +.I size +argument specifies the maximum number of addresses +that can be stored in +.IR buffer . +If the backtrace is larger than +.IR size , +then the addresses corresponding to the +.I size +most recent function calls are returned; +to obtain the complete backtrace, make sure that +.I buffer +and +.I size +are large enough. + +Given the set of addresses returned by +.BR backtrace () +in +.IR buffer , +.BR backtrace_symbols () +translates the addresses into an array of strings that describe +the addresses symbolically. +The +.I size +argument specifies the number of addresses in +.IR buffer . +The symbolic representation of each address consists of the function name +(if this can be determined), a hexadecimal offset into the function, +and the actual return address (in hexadecimal). +The address of the array of string pointers is returned +as the function result of +.BR backtrace_symbols (). +This array is +.BR malloc (3)ed +by +.BR backtrace_symbols (), +and must be freed by the caller. +(The strings pointed to by +.IR strings +need not and should not be freed.) + +.BR backtrace_symbols_fd () +takes the same +.I buffer +and +.I size +arguments as +.BR backtrace_symbols (), +but instead of returning an array of strings to the caller, +it writes the strings, one per line, to the file descriptor +.IR fd . +.BR backtrace_symbols () +does not call +.BR malloc (3), +and so can be employed in situations where the latter function might fail. +.SH "RETURN VALUE" +.BR backtrace () +returns the number of addresses returned in +.IR buffer , +which is not greater than +.IR size . +If the return value is less than +.IR size , +then the full backtrace was stored; if it is equal to +.IR size , +then it may have been truncated, in which case the addresses of the +oldest stack frames are not returned. + +On success, +.BR backtrace_symbols () +returns a pointer to the array +.BR malloc (3)ed +by the call; +on error, NULL is returned. +.SH CONFORMING TO +These functions are GNU extensions. +.SH NOTES +These functions make some assumptions about how a function's return +address is stored on the stack. +Note the following: +.IP * 3 +Omission of the frame pointers (as +implied by any of +.BR gcc (1)'s +non-zero optimization levels) may cause these assumptions to be +violated. +.IP * +Inlined functions do not have stack frames. +.IP * +Tail-call optimization causes one stack frame to replace another. +.PP +The symbol names may be unavailable without the use of special linker +options. +For systems using the GNU linker, it is necessary to use the +.I \-rdynamic +linker option. +Note that names of "static" functions are not exposed, +and won't be available in the backtrace. +.SH EXAMPLE +The program below demonstrates the use of +.BR backtrace () +and +.BR backtrace_symbols (). +The following shell session shows what we might see when running the +program: +.nf +.in +0.25i + + $ cc -rdynamic prog.c -o prog + $ ./prog 3 + backtrace() returned 8 addresses + ./prog(myfunc3+0x5c) [0x80487f0] + ./prog [0x8048871] + ./prog(myfunc+0x21) [0x8048894] + ./prog(myfunc+0x1a) [0x804888d] + ./prog(myfunc+0x1a) [0x804888d] + ./prog(main+0x65) [0x80488fb] + /lib/libc.so.6(__libc_start_main+0xdc) [0xb7e38f9c] + ./prog [0x8048711] +.in +.fi +.nf + +#include +#include +#include +#include + +void +myfunc3(void) +{ + int j, nptrs; +#define SIZE 100 + void *buffer[100]; + char **strings; + + nptrs = backtrace(buffer, SIZE); + printf("backtrace() returned %d addresses\\n", nptrs); + + /* The call backtrace_symbols_fd(buffer, nptrs, STDOUT_FILENO) + would produce similar output to the following: */ + + strings = backtrace_symbols(buffer, nptrs); + if (strings == NULL) { + perror("backtrace_symbols"); + exit(EXIT_FAILURE); + } + + for (j = 0; j < nptrs; j++) + printf("%s\\n", strings[j]); + + free(strings); +} + +static void /* 'static' means don't export the symbol... */ +myfunc2(void) +{ + myfunc3(); +} + +void +myfunc(int ncalls) +{ + if (ncalls > 1) + myfunc(ncalls - 1); + else + myfunc2(); +} + +int +main(int argc, char *argv[]) +{ + if (argc != 2) { + fprintf(stderr, "%s num-calls\\n", argv[0]); + exit(EXIT_FAILURE); + } + + myfunc(atoi(argv[1])); + exit(EXIT_SUCCESS); +} +.fi +.SH SEE ALSO +.BR gcc (1), +.BR ld (1), +.BR dlopen (3), +.BR malloc (3) diff --git a/man3/backtrace_symbols.3 b/man3/backtrace_symbols.3 new file mode 100644 index 000000000..936a6b9f6 --- /dev/null +++ b/man3/backtrace_symbols.3 @@ -0,0 +1 @@ +.so man3/backtrace.3 diff --git a/man3/backtrace_symbols_fd.3 b/man3/backtrace_symbols_fd.3 new file mode 100644 index 000000000..936a6b9f6 --- /dev/null +++ b/man3/backtrace_symbols_fd.3 @@ -0,0 +1 @@ +.so man3/backtrace.3