summaryrefslogtreecommitdiff
path: root/util.h
diff options
context:
space:
mode:
authorJarkko Hietaniemi <jhi@iki.fi>2014-06-03 08:39:56 -0400
committerJarkko Hietaniemi <jhi@iki.fi>2014-06-07 21:26:59 -0400
commit470dd224e4b587137a482c6db3d765860bcba19c (patch)
treea54e1dc2948089c51d297db55fa14fc575c02517 /util.h
parent26c014b2af00ac88008218a92a598f8644e0d236 (diff)
downloadperl-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.h72
1 files changed, 72 insertions, 0 deletions
diff --git a/util.h b/util.h
index 34dc760269..57a3ad0b65 100644
--- a/util.h
+++ b/util.h
@@ -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