libc
on Solaris 9 and later, provides a useful function called
printstack
, to print a symbolic stack trace to the specified file descriptor. This is useful for reporting errors from an application during run-time.
If the stack trace appears corrupted, or if the stack cannot be read,
printstack()
returns -1.
Programmatic example:
% more printstack.c
#include <stdio.h>
#include <ucontext.h>
int callee(int file) {
printstack(file);
return (0);
}
int caller() {
int a;
a = callee (fileno(stdout));
return (a);
}
int main() {
caller();
return (0);
}
% cc -o stacktrace stacktrace.c
% ./stacktrace
/tmp/stacktrace:callee+0x18
/tmp/stacktrace:caller+0x22
/tmp/stacktrace:main+0x14
/tmp/stacktrace:0x6d2
The
printstack()
function uses
dladdr1()
to obtain symbolic symbol names. As a result, only global symbols are reported as symbol names by
printstack()
.
% CC -o stacktrace stacktrace.c
% ./stacktrace
/tmp/stacktrace:__1cGcallee6Fi_i_+0x18
/tmp/stacktrace:__1cGcaller6F_i_+0x22
/tmp/stacktrace:main+0x14
/tmp/stacktrace:0x91a
The stack trace from a C++ program, will have all the symbols in their mangled form. So as of now, the programmers may need to have their own wrapper functions to print the stack trace in unmangled form.
There has been an RFE (Request For Enhancement) in place against Solaris'
libc
to print the stack trace in unmangled form, when
printstack()
has been called from a C++ program. This will be released as a
libc
patch for Solaris
8, 9 & 10 some time in the near future.
% elfdump -CsN.symtab libc.so | grep printstack
[5275] 0x00052629 0x00000051 FUNC GLOB D 0 .text _printstack
[6332] 0x00052629 0x00000051 FUNC WEAK D 0 .text printstack
Since the object code is automatically linked with
libc
during the creation of an executable or a dynamic library, the programmer need not specify
-lc
on the compile line.
Suggested Reading:
Man page of
walkcontext
or
printstack