develooper Front page | perl.perl5.porters | Postings from October 2015

[perl #126273] [PATCH] WIP add save stack caller tracing

bulk88 via RT
October 17, 2015 01:32
[perl #126273] [PATCH] WIP add save stack caller tracing
Message ID:
On Tue Oct 06 03:22:43 2015, davem wrote:
> Um, this seems a bit invasive. Would it be possible instead, to
> 1. If you're just interested in finding when a particular SS frame of
> interest was pushed:
> On debugging builds, have a var, PL_savestack_serial say, which is
> incremented and pushed onto the SS at the same time the SS action is.
> Then to find where a particular frame comes from, look at the serial
> number, then rerun the program with a watchppoint to trigger when
> PL_savestack_serial gets that value.

-Doesn't identify more than 1 location per process run unless you use multiple == and || in the expression
-Doesn't work if the process wont crash when running inside a C debugger and all you have a dump file
-Conditional breakpoints require -O0 code, not -O1/-O2, unless you know assembly and disable ASLR (you have to recompile for SS_DEBUG, but it can be used independent of DEBUGGING perl, and I think DEBUGGING perl is -O2 by default), so it is a little bit more steps to use them typically than absolute breakpoints or waiting for sigsegv to fire

> 2. If you need to do more general introspection (e.g. a full stack dump
> showing where each frame came from):
> On debugging builds, have a fake save type, SAVEt_DEBUGINFO say, along with
> an associated save function and macro, that can be used to push that info
> on the savestack; e.g.
>     #ifdef DEBUGGING
>     #  define SAVEDEBUGINFO() save_debuginfo(__LINE__, __FILE__)
>     Perl_save_debuginfo(pTHX_ char *file, int line)
>     {
>         dSS_ADD;
>         SS_ADD_PTR(file);
>         SS_ADD_INT(line);
>         SS_ADD_END(3);
>     }
>     #else
>     #  define SAVEDEBUGINFO() NOOP;
>     #endif
> Then just update the SAVEFOO macros to be, e.g.
> #define SAVEI8(i)	save_I8((I8*)&(i)); SAVEDEBUGINFO

There is no clear separation between SS_ADD/SSPUSH your own kind of type sandwich, SAVE***** macros and save_***** functions. perlapi lists save_***** funcs. lists the SAVE*****. cpangrep shows SAVE****** being the standard on CPAN, but core has a bunch of with save_****** usage. Since core uses save_****** calls in a bunch of places, the save_***** calls must be hooked, not the all caps macros.

With your proposal, there are many ways SS frames can slip through the cracks and not get their context recorded since having a context SS frame is completely optional instead of absolutely required or very quick failure. If bad CPAN code makes their own SS sandwich with SSPUSH*, it won't record the context.

With my design, failing to correctly code for SS_DEBUG (have the file and line entries next to the type entry) will quickly cause a SEGV in SS_DEBUG perl in Perl_leave_scope since the file and line slots are missing. Plus random memory corruption might wipe or replace the file char *, and make the printable char test assert fail, failing sooner. If the context frame is blindly skipped like SAVEt_ALLOC in Perl_leave_scope, it might have been corrupted but it isn't known. Also having SSPUSHTYPE instead of SSPUSHUV for the type slot makes the reading the source code easier.

There will be further revisions to the code since it fails on most build permutations, and I have them already on another machine. The concept of each SAVEt_* gets a file and line slot will remain. The invasiveness of patch is limited to scope.c/scope.h/embed.fnc/ No source code changes in the other files unless they directly pop or push SS slots and refuse to use the abstraction in scope.c for whatever reason.

bulk88 ~ bulk88 at

via perlbug:  queue: perl5 status: open Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About