2007-09-20 06:52:22 +00:00
|
|
|
.\" Copyright (C) 2007 Michael Kerrisk <mtk.manpages@gmail.com>
|
2007-06-10 22:44:52 +00:00
|
|
|
.\" drawing on material by Justin Pryzby <pryzbyj@justinpryzby.com>
|
|
|
|
.\"
|
|
|
|
.\" 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
|
2008-06-11 13:43:34 +00:00
|
|
|
.TH BACKTRACE 3 2008-06-14 GNU "Linux Programmer's Manual"
|
2007-06-10 22:44:52 +00:00
|
|
|
.SH NAME
|
|
|
|
backtrace, backtrace_symbols, backtrace_symbols_fd \- support
|
|
|
|
for application self-debugging
|
|
|
|
.SH SYNOPSIS
|
|
|
|
.B #include <execinfo.h>
|
|
|
|
|
|
|
|
.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
|
2007-06-21 22:55:04 +00:00
|
|
|
by
|
2007-06-10 22:44:52 +00:00
|
|
|
.BR backtrace_symbols (),
|
|
|
|
and must be freed by the caller.
|
2008-05-09 13:06:00 +00:00
|
|
|
(The strings pointed to by the array of pointers
|
2007-06-10 22:44:52 +00:00
|
|
|
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 .
|
2008-04-18 15:41:11 +00:00
|
|
|
.BR backtrace_symbols_fd ()
|
2007-06-10 22:44:52 +00:00
|
|
|
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.
|
2008-06-11 13:43:34 +00:00
|
|
|
.SH VERSIONS
|
|
|
|
.BR backtrace (),
|
|
|
|
.BR backtrace_symbols (),
|
|
|
|
and
|
|
|
|
.BR backtrace_symbols_fd ()
|
2008-06-26 13:45:39 +00:00
|
|
|
are provided in glibc since version 2.1.
|
2007-06-10 22:44:52 +00:00
|
|
|
.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
|
intro.1, time.1, adjtimex.2, capget.2, eventfd.2, fcntl.2, getrlimit.2, getsockopt.2, gettimeofday.2, intro.2, ioctl_list.2, ioperm.2, mlock.2, pivot_root.2, poll.2, prctl.2, ptrace.2, sched_setscheduler.2, select_tut.2, semget.2, sigaltstack.2, signalfd.2, sysctl.2, timer_settime.2, timerfd_create.2, wait.2, CPU_SET.3, argz_add.3, assert_perror.3, atexit.3, backtrace.3, bcmp.3, clearenv.3, ctime.3, dl_iterate_phdr.3, dlopen.3, ecvt.3, errno.3, error.3, ether_aton.3, exit.3, fenv.3, ferror.3, finite.3, flockfile.3, fnmatch.3, fpathconf.3, fpclassify.3, ftime.3, ftok.3, ftw.3, fwide.3, getaddrinfo.3, gethostbyname.3, getlogin.3, getnameinfo.3, getnetent.3, getopt.3, getprotoent.3, getrpcent.3, getservent.3, glob.3, hsearch.3, inet.3, isalpha.3, iswalnum.3, iswalpha.3, iswblank.3, iswcntrl.3, iswctype.3, iswdigit.3, iswgraph.3, iswlower.3, iswprint.3, iswpunct.3, iswspace.3, iswupper.3, iswxdigit.3, longjmp.3, lsearch.3, malloc.3, matherr.3, mblen.3, mbsinit.3, mbtowc.3, on_exit.3, printf.3, pthread_attr_init.3, pthread_attr_setaffinity_np.3, pthread_attr_setdetachstate.3, pthread_attr_setguardsize.3, pthread_attr_setinheritsched.3, pthread_attr_setschedparam.3, pthread_attr_setschedpolicy.3, pthread_attr_setscope.3, pthread_attr_setstack.3, pthread_attr_setstackaddr.3, pthread_attr_setstacksize.3, pthread_cancel.3, pthread_cleanup_push.3, pthread_equal.3, pthread_getattr_np.3, pthread_getcpuclockid.3, pthread_setaffinity_np.3, pthread_setcancelstate.3, pthread_setconcurrency.3, pthread_setschedparam.3, pthread_setschedprio.3, ptsname.3, putenv.3, putgrent.3, raise.3, rcmd.3, regex.3, rexec.3, rpc.3, rpmatch.3, rtnetlink.3, scandir.3, sem_init.3, setaliasent.3, setbuf.3, setenv.3, setjmp.3, signbit.3, stdio_ext.3, strtod.3, strtol.3, strtoul.3, system.3, termios.3, timeradd.3, tzset.3, ualarm.3, wctomb.3, xdr.3, st.4, tty_ioctl.4, core.5, elf.5, proc.5, bootparam.7, capabilities.7, icmp.7, ip.7, ipv6.7, math_error.7, mdoc.samples.7, mq_overview.7, pthreads.7, raw.7, regex.7, socket.7, tcp.7, tzselect.8: Global fix: s/non-zero/nonzero/
The tendency in English, as prescribed in style guides like
Chicago MoS, is towards removing hyphens after prefixes
like "non-" etc.
Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
2010-01-16 16:40:55 +00:00
|
|
|
nonzero optimization levels) may cause these assumptions to be
|
2007-06-10 22:44:52 +00:00
|
|
|
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
|
2007-12-19 06:57:44 +00:00
|
|
|
.in +4n
|
2007-06-10 22:44:52 +00:00
|
|
|
|
eventfd.2, execve.2, getdents.2, ioprio_set.2, mprotect.2, signalfd.2, timerfd_create.2, wait.2, backtrace.3, clock_getcpuclockid.3, end.3, fmemopen.3, fopencookie.3, frexp.3, getdate.3, getgrouplist.3, getprotoent_r.3, getservent_r.3, gnu_get_libc_version.3, inet.3, inet_pton.3, makecontext.3, malloc.3, matherr.3, offsetof.3, pthread_attr_init.3, pthread_create.3, pthread_getattr_np.3, sem_wait.3, strftime.3, strtok.3, strtol.3, core.5, proc.5, cpuset.7, mq_overview.7: Global fix: Format user input in shell sessions in boldface
Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
2008-10-28 15:37:22 +00:00
|
|
|
.RB "$" " cc \-rdynamic prog.c \-o prog"
|
|
|
|
.RB "$" " ./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]
|
2007-06-10 22:44:52 +00:00
|
|
|
.in
|
|
|
|
.fi
|
eventfd.2, getdents.2, mprotect.2, signalfd.2, timerfd_create.2, wait.2, backtrace.3, clock_getcpuclockid.3, end.3, fmemopen.3, fopencookie.3, getdate.3, getgrouplist.3, getprotoent_r.3, getservent_r.3, gnu_get_libc_version.3, inet.3, inet_pton.3, makecontext.3, matherr.3, offsetof.3, pthread_attr_init.3, pthread_create.3, pthread_getattr_np.3, sem_wait.3, strtol.3, core.5: global fix: Add ".SS Program source" to EXAMPLE
Add ".SS Program source" to clearly distinguish shell session and
descriptive text from actual program code.
Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
2008-10-28 15:51:05 +00:00
|
|
|
.SS Program source
|
eventfd.2, getdents.2, mprotect.2, signalfd.2, timerfd_create.2, wait.2, backtrace.3, clock_getcpuclockid.3, end.3, fmemopen.3, fopencookie.3, frexp.3, getaddrinfo.3, getdate.3, getgrouplist.3, getprotoent_r.3, getservent_r.3, gnu_get_libc_version.3, inet.3, inet_pton.3, makecontext.3, matherr.3, offsetof.3, pthread_attr_init.3, pthread_create.3, pthread_getattr_np.3, sem_wait.3, strftime.3, strtok.3, strtol.3, core.5: srcfix
s/\.R " "/\\\&/ as a way of getting a blank line after a .SS heading.
(Suggested by Sam Varshavchik <mrsam@courier-mta.com>)
Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
2008-11-05 01:42:45 +00:00
|
|
|
\&
|
2007-06-10 22:44:52 +00:00
|
|
|
.nf
|
|
|
|
#include <execinfo.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2008-06-09 15:49:35 +00:00
|
|
|
static void /* "static" means don\(aqt export the symbol... */
|
2007-06-10 22:44:52 +00:00
|
|
|
myfunc2(void)
|
|
|
|
{
|
|
|
|
myfunc3();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
myfunc(int ncalls)
|
|
|
|
{
|
|
|
|
if (ncalls > 1)
|
2007-06-20 21:39:45 +00:00
|
|
|
myfunc(ncalls \- 1);
|
2007-06-10 22:44:52 +00:00
|
|
|
else
|
|
|
|
myfunc2();
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
main(int argc, char *argv[])
|
|
|
|
{
|
|
|
|
if (argc != 2) {
|
2007-06-20 21:39:45 +00:00
|
|
|
fprintf(stderr, "%s num\-calls\\n", argv[0]);
|
2007-06-10 22:44:52 +00:00
|
|
|
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)
|