diff options
author | Jarkko Hietaniemi <jhi@iki.fi> | 2014-06-11 18:41:07 -0400 |
---|---|---|
committer | Jarkko Hietaniemi <jhi@iki.fi> | 2014-06-11 20:47:28 -0400 |
commit | 0762e42f1c0731c98425010a106230c563c6e563 (patch) | |
tree | 4c366a431805d7b617cf9b96fe502d29b0983af0 | |
parent | 747b6130a9063e3d9656d6f06910fa7f17e1f986 (diff) | |
download | perl-0762e42f1c0731c98425010a106230c563c6e563.tar.gz |
C backtrace tweaks.
Rename the environment variable that triggers the backtrace before
warns and croaks as PERL_USE_C_BACKTRACE_ON_ERROR (and correspondingly,
the define as USE_C_BACKTRACE_ON_ERROR).
Pod cleanups and updates, and move the needed #includes from perl.h
to util.c since that's the only place where they are needed.
-rw-r--r-- | perl.h | 10 | ||||
-rw-r--r-- | pod/perlhacktips.pod | 42 | ||||
-rw-r--r-- | util.c | 34 | ||||
-rw-r--r-- | util.h | 6 |
4 files changed, 57 insertions, 35 deletions
@@ -5860,16 +5860,6 @@ extern void moncontrol(int); #define PERL_PV_PRETTY_DUMP PERL_PV_PRETTY_ELLIPSES|PERL_PV_PRETTY_QUOTE #define PERL_PV_PRETTY_REGPROP PERL_PV_PRETTY_ELLIPSES|PERL_PV_PRETTY_LTGT|PERL_PV_ESCAPE_RE|PERL_PV_ESCAPE_NONASCII -#if defined(USE_C_BACKTRACE) && defined(I_BFD) -# define USE_BFD -# ifdef PERL_DARWIN -# undef USE_BFD /* BFD is useless in OS X. */ -# endif -# ifdef USE_BFD -# include <bfd.h> -# endif -#endif - /* (KEEP THIS LAST IN perl.h!) diff --git a/pod/perlhacktips.pod b/pod/perlhacktips.pod index c93a80b413..5cd04e4463 100644 --- a/pod/perlhacktips.pod +++ b/pod/perlhacktips.pod @@ -1399,40 +1399,46 @@ Note: you can define up to 20 conversion shortcuts in the gdb section. =head2 C backtrace -Starting from Perl 5.21.1, on some platforms Perl supports retrieving -the C level backtrace (similar to what symbolic debuggers like gdb do). +On some platforms Perl supports retrieving the C level backtrace +(similar to what symbolic debuggers like gdb do). The backtrace returns the stack trace of the C call frames, with the symbol names (function names), the object names (like "perl"), and if it can, also the source code locations (file:line). -The supported platforms are Linux and OS X (some *BSD might work at -least partly, but they have not yet been tested). +The supported platforms are Linux, and OS X (some *BSD might +work at least partly, but they have not yet been tested). + +This feature hasn't been tested with multiple threads, but it will +only show the backtrace of the thread doing the backtracing. The feature needs to be enabled with C<Configure -Dusecbacktrace>. -The C<-Dusecbacktrace> also enables keeping the debug information -when compiling. Many compilers/linkers do support having both -optimization and keeping the debug information. The debug information -is needed for the symbol names and the source locations. +The C<-Dusecbacktrace> also enables keeping the debug information when +compiling/linking (often: C<-g>). Many compilers/linkers do support +having both optimization and keeping the debug information. The debug +information is needed for the symbol names and the source locations. + +Static functions might not be visible for the backtrace. Source code locations, even if available, can often be missing or -misleading if the compiler has e.g. inlined code. +misleading if the compiler has e.g. inlined code. Optimizer can +make matching the source code and the object code quite challenging. =over 4 =item Linux You B<must> have the BFD (-lbfd) library installed, otherwise C<perl> will -fail to link. The BFD is usually distributed as part of the binutils. +fail to link. The BFD is usually distributed as part of the GNU binutils. Summary: C<Configure ... -Dusecbacktrace> and you need C<-lbfd>. =item OS X -The source code locations are supported only if you have both C<-g> -and have the Developer Tools installed. +The source code locations are supported B<only> if you have +the Developer Tools installed. (BFD is B<not> needed.) Summary: C<Configure ... -Dusecbacktrace> and installing the Developer Tools would be good. @@ -1440,17 +1446,17 @@ and installing the Developer Tools would be good. =back Optionally, for trying out the feature, you may want to enable -automatic dumping of the backtrace just before a warning message -is emitted (this includes coincidentally croaking) by adding -C<-Accflags=-DUSE_C_BACKTRACE_ON_WARN> for Configure. +automatic dumping of the backtrace just before a warning or croak (die) +message is emitted, by adding C<-Accflags=-DUSE_C_BACKTRACE_ON_ERROR> +for Configure. Unless the above additional feature is enabled, nothing about the backtrace functionality is visible, except for the Perl/XS level. Furthermore, even if you have enabled this feature to be compiled, you need to enable it in runtime with an environment variable: -C<PERL_C_BACKTRACE_ON_WARN=10>. It must be an integer higher -than zero, and it tells the desired frame count. +C<PERL_C_BACKTRACE_ON_ERROR=10>. It must be an integer higher +than zero, telling the desired frame count. Retrieving the backtrace from Perl level (using for example an XS extension) would be much less exciting than one would hope: normally @@ -1458,7 +1464,7 @@ you would see C<runops>, C<entersub>, and not much else. This API is intended to be called B<from within> the Perl implementation, not from Perl level execution. -The C API for the backtrace is as follows (see L<perlintern>) for details). +The C API for the backtrace is as follows: =over 4 @@ -51,8 +51,16 @@ int putenv(char *); # endif #endif -/* <bfd.h> will have been included, if necessary, by "perl.h" */ #ifdef USE_C_BACKTRACE +# ifdef I_BFD +# define USE_BFD +# ifdef PERL_DARWIN +# undef USE_BFD /* BFD is useless in OS X. */ +# endif +# ifdef USE_BFD +# include <bfd.h> +# endif +# endif # ifdef I_DLFCN # include <dlfcn.h> # endif @@ -1361,12 +1369,12 @@ Perl_mess_sv(pTHX_ SV *basemsg, bool consume) dVAR; SV *sv; -#if defined(USE_C_BACKTRACE) && defined(USE_C_BACKTRACE_ON_WARN) +#if defined(USE_C_BACKTRACE) && defined(USE_C_BACKTRACE_ON_ERROR) { char *ws; int wi; /* The PERL_C_BACKTRACE_ON_WARN must be an integer of one or more. */ - if ((ws = PerlEnv_getenv("PERL_C_BACKTRACE_ON_WARN")) && + if ((ws = PerlEnv_getenv("PERL_C_BACKTRACE_ON_ERROR")) && (wi = atoi(ws)) > 0) { Perl_dump_c_backtrace(aTHX_ Perl_debug_log, wi, 1); } @@ -5506,8 +5514,11 @@ Perl_drand48_r(perl_drand48_t *random_state) #ifdef USE_BFD typedef struct { + /* abfd is the BFD handle. */ bfd* abfd; + /* bfd_syms is the BFD symbol table. */ asymbol** bfd_syms; + /* bfd_text is handle to the the ".text" section of the object file. */ asection* bfd_text; /* Since opening the executable and scanning its symbols is quite * heavy operation, we remember the filename we used the last time, @@ -5611,10 +5622,20 @@ static void bfd_symbolize(bfd_context* ctx, * use high-level stuff. Thanks, Apple. */ typedef struct { + /* tool is set to the absolute pathname of the tool to use: + * xcrun or atos. */ const char* tool; + /* format is set to a printf format string used for building + * the external command to run. */ const char* format; + /* unavail is set if e.g. xcrun cannot be found, or something + * else happens that makes getting the backtrace dubious. Note, + * however, that the context isn't persistent, the next call to + * get_c_backtrace() will start from scratch. */ bool unavail; + /* fname is the current object file name. */ const char* fname; + /* object_base_addr is the base address of the shared object. */ void* object_base_addr; } atos_context; @@ -5750,7 +5771,6 @@ static void atos_symbolize(atos_context* ctx, * We could play tricks with atos by batching the stack * addresses to be resolved: atos can either take multiple * addresses from the command line, or read addresses from - * * a file (though the mess of creating temporary files would * probably negate much of any possible speedup). * @@ -5875,9 +5895,9 @@ Perl_get_c_backtrace(pTHX_ int depth, int skip) /* We use dladdr() instead of backtrace_symbols() because we want * the full details instead of opaque strings. This is useful for * two reasons: () the details are needed for further symbolic - * digging (2) by having the details we fully control the output, - * which in turn is useful when more platforms are added: - * we can keep out output "portable". */ + * digging, for example in OS X (2) by having the details we fully + * control the output, which in turn is useful when more platforms + * are added: we can keep out output "portable". */ /* We want a single linear allocation, which can then be freed * with a single swoop. We will do the usual trick of first @@ -121,6 +121,12 @@ typedef struct { * output - quite disgusting. And that won't work if the * Developer Tools isn't installed. */ + /* FreeBSD notes: execinfo.h exists, but probably would need also + * the library -lexecinfo. BFD exists if the pkg devel/binutils + * has been installed, but there seems to be a known problem that + * the "bfd.h" getting installed refers to "ansidecl.h", which + * doesn't get installed. */ + /* Win32 notes: as moral equivalents of backtrace() + dladdr(), * one could possibly first use GetCurrentProcess() + * SymInitialize(), and then CaptureStackBackTrace() + |