diff options
author | Jarkko Hietaniemi <jhi@iki.fi> | 2014-06-03 08:39:56 -0400 |
---|---|---|
committer | Jarkko Hietaniemi <jhi@iki.fi> | 2014-06-07 21:26:59 -0400 |
commit | 470dd224e4b587137a482c6db3d765860bcba19c (patch) | |
tree | a54e1dc2948089c51d297db55fa14fc575c02517 /util.h | |
parent | 26c014b2af00ac88008218a92a598f8644e0d236 (diff) | |
download | perl-470dd224e4b587137a482c6db3d765860bcba19c.tar.gz |
Add C backtrace API.
Useful for at least debugging.
Supported in Linux and OS X (possibly to some extent in *BSD).
See perlhacktips for details.
Diffstat (limited to 'util.h')
-rw-r--r-- | util.h | 72 |
1 files changed, 72 insertions, 0 deletions
@@ -85,6 +85,78 @@ typedef struct PERL_DRAND48_T perl_drand48_t; #define Perl_drand48_init(seed) (Perl_drand48_init_r(&PL_random_state, (seed))) #define Perl_drand48() (Perl_drand48_r(&PL_random_state)) +#ifdef USE_C_BACKTRACE + +typedef struct { + /* The number of frames returned. */ + UV frame_count; + /* The total size of the Perl_c_backtrace, including this header, + * the frames, and the name strings. */ + UV total_bytes; +} Perl_c_backtrace_header; + +typedef struct { + void* addr; /* the program counter at this frame */ + + /* We could use Dl_info (as used by dladdr()) for many of these but + * that would be naughty towards non-dlfcn systems (hi there, Win32). */ + + void* symbol_addr; /* symbol address (hint: try symbol_addr - addr) */ + void* object_base_addr; /* base address of the shared object */ + + /* The offsets are from the beginning of the whole backtrace, + * which makes the backtrace relocatable. */ + STRLEN object_name_offset; /* pathname of the shared object */ + STRLEN object_name_size; /* length of the pathname */ + STRLEN symbol_name_offset; /* symbol name */ + STRLEN symbol_name_size; /* length of the symbol name */ + STRLEN source_name_offset; /* source code file name */ + STRLEN source_name_size; /* length of the source code file name */ + STRLEN source_line_number; /* source code line number */ + + /* OS X notes: atos(1) (more recently, "xcrun atos"), but the C + * API atos() uses is unknown (private "Symbolicator" framework, + * might require Objective-C even if the API would be known). + * Currently we open read pipe to "xcrun atos" and parse the + * output - quite disgusting. And that won't work if the + * Developer Tools isn't installed. */ + + /* Win32 notes: as moral equivalents of backtrace() + dladdr(), + * one could possibly first use GetCurrentProcess() + + * SymInitialize(), and then CaptureStackBackTrace() + + * SymFromAddr(). */ + + /* Note that using the compiler optimizer easily leads into much + * of this information, like the symbol names (think inlining), + * and source code locations getting lost or confused. In many + * cases keeping the debug information (-g) is necessary. + * + * Note that for example with gcc you can do both -O and -g. + * + * Note, however, that on some platforms (e.g. OSX + clang (cc)) + * backtrace() + dladdr() works fine without -g. */ + + /* For example: the mere presence of <bfd.h> is no guarantee: e.g. + * OS X has that, but BFD does not seem to work on the OSX executables. + * + * Another niceness would be to able to see something about + * the function arguments, however gdb/lldb manage to do that. */ +} Perl_c_backtrace_frame; + +typedef struct { + Perl_c_backtrace_header header; + Perl_c_backtrace_frame frame_info[1]; + /* After the header come: + * (1) header.frame_count frames + * (2) frame_count times the \0-terminated strings (object_name + * and so forth). The frames contain the pointers to the starts + * of these strings, and the lengths of these strings. */ +} Perl_c_backtrace; + +#define Perl_free_c_backtrace(bt) Safefree(bt) + +#endif /* USE_C_BACKTRACE */ + /* * Local variables: * c-indentation-style: bsd |