Ticket #1273 (closed todo: fixed)

Opened 5 years ago

Last modified 4 years ago

Provide a parrot 'backtrace' with assertion failures.

Reported by: Austin_Hastings Owned by:
Priority: normal Milestone:
Component: none Version: 1.7.0
Severity: medium Keywords:
Cc: Language:
Patch status: Platform:

Description

When an assertion fails, a C stack trace is provided which is not particularly valuable for determining how to reproduce the problem (short of re-running whatever enormous codeset produces the first failure). For example:

src/string/api.c:549: failed assertion '(b)->charset'
Backtrace - Obtained 16 stack frames (max trace depth is 32).
/usr/local/lib/libparrot.so.1.7.0 [0x400d3d62]
/usr/local/lib/libparrot.so.1.7.0(Parrot_confess+0x9a) [0x400d3eca]
/usr/local/lib/libparrot.so.1.7.0(Parrot_str_append+0x17c) [0x4005477c]
/usr/local/lib/libparrot.so.1.7.0(Parrot_str_join+0x160) [0x40054cf0]
/usr/local/lib/libparrot.so.1.7.0 [0x4007985f]
/usr/local/lib/libparrot.so.1.7.0 [0x4011f34e]
/usr/local/lib/libparrot.so.1.7.0 [0x4011d8af]
/usr/local/lib/libparrot.so.1.7.0 [0x400f589f]
/usr/local/lib/libparrot.so.1.7.0 [0x400f5cb0]
/usr/local/lib/libparrot.so.1.7.0(Parrot_runops_fromc_args+0xc6) [0x400f6a56]
/usr/local/lib/libparrot.so.1.7.0(Parrot_runcode+0x15e) [0x400d09ce]
/usr/local/lib/libparrot.so.1.7.0 [0x402bf313]
/usr/local/lib/libparrot.so.1.7.0(imcc_run+0x39c) [0x402bff0c]
/usr/local/bin/parrot [0x8048938]
/lib/libc.so.6(__libc_start_main+0xe5) [0x403c6775]
/usr/local/bin/parrot [0x80487d1]
make: *** [test-attributes] Aborted (core dumped)

I propose that the assertion-failure code should be extended to also provide a "backtrace" (a la the backtrace opcode) of the Parrot stack, so that developers can find the particular areas of their code that are experiencing the failure.

Cotto suggested in IRC that the Parrot_confess routine would be the place to make this change.

Change History

Changed 4 years ago by jkeenan

Changed 4 years ago by cotto

I'm tempted to reject this as wontfix. To add PDB_backtrace to Parrot_confess would require access to the interp, and getting that would mean modifying everything that uses any variant of PARROT_ASSERT. There are a lot of them. We also don't want to impose the constraint that an interp must be available before a condition can be asserted. If someone has a sane way to do provide a pir-level backtrace on an assertion failure, I'm all ears. If not, I'll reject this.

Changed 4 years ago by Austin_Hastings

Without knowing anything about the internals, it seems to me that having the pdb-backtrace code check the stack for a key subroutine in the interpreter (possibly named "dispatch" or something) and magically "turning sideways" to dump the interp stack of that routine would work. It would also have the benefit of handling nested runloops. Of course, I have no idea how pdb-backtrace would do such a thing...

Changed 4 years ago by NotFound

The problem I see is that an assertion failure is used for completely unexpected cases. Thus you can't know if the interpreter, the context, or anything is barely usable, and attempts to use or explore it can lead to even more incomprehensible failures and traces.

Changed 4 years ago by cotto

My thinking is to provide a best effort attempt to get a pir-level backtrace, i.e. we'll try to provide a backtrace, but if it breaks you don't get to complain. It's true that we can't assume that the interp is in a usable state (or even that it exists), but if it does it'll be helpful to provide as much information as possible.

I added this functionality to Parrot_print_backtrace in the pir-bt-on-crash branch in parrot.git. Below is what the output looks like when I purposefully trigger a crash in oofib.pir. I'd appreciate another pair of eyeballs looking over the code.

cotto@cotto-linux-desktop:/usr/src/parrot-git-master @pir-bt-on-crash 3 $ ./parrot crashfib.pir 
src/ops/core_ops.c:23476: failed assertion '0'
Backtrace - Obtained 12 stack frames (max trace depth is 32).
/usr/src/parrot-git-master/blib/lib/libparrot.so.3.0.0(+0xc3c0a) [0xcf3c0a]
/usr/src/parrot-git-master/blib/lib/libparrot.so.3.0.0(Parrot_confess+0x9a) [0xcf3bca]
/usr/src/parrot-git-master/blib/lib/libparrot.so.3.0.0(+0xa3b11) [0xcd3b11]
/usr/src/parrot-git-master/blib/lib/libparrot.so.3.0.0(+0x116c81) [0xd46c81]
/usr/src/parrot-git-master/blib/lib/libparrot.so.3.0.0(+0x115cea) [0xd45cea]
/usr/src/parrot-git-master/blib/lib/libparrot.so.3.0.0(+0xe370f) [0xd1370f]
/usr/src/parrot-git-master/blib/lib/libparrot.so.3.0.0(Parrot_pcc_invoke_from_sig_object+0x19b) [0xd0dadb]
/usr/src/parrot-git-master/blib/lib/libparrot.so.3.0.0(Parrot_pcc_invoke_sub_from_c_args+0x11e) [0xd0d3be]
/usr/src/parrot-git-master/blib/lib/libparrot.so.3.0.0(Parrot_api_run_bytecode+0x236) [0xced6f6]
./parrot() [0x8049272]
/lib/libc.so.6(__libc_start_main+0xe7) [0x7d2ce7]
./parrot() [0x8048f31]
Attempting to get PIR backtrace.  No guarantees.  Here goes...
current instr.: 'parrot;B;fibB' pc 200 (crashfib.pir:103)
called from Sub 'parrot;A;fib' pc 103 (crashfib.pir:60)
called from Sub 'parrot;A;fibA' pc 138 (crashfib.pir:76)
called from Sub 'parrot;A;fib' pc 91 (crashfib.pir:56)
called from Sub 'parrot;A;fibA' pc 138 (crashfib.pir:76)
called from Sub 'parrot;A;fib' pc 91 (crashfib.pir:56)
called from Sub 'parrot;A;fibA' pc 138 (crashfib.pir:76)
called from Sub 'parrot;A;fib' pc 91 (crashfib.pir:56)
called from Sub 'parrot;A;fibA' pc 138 (crashfib.pir:76)
called from Sub 'parrot;A;fib' pc 91 (crashfib.pir:56)
called from Sub 'parrot;A;fibA' pc 138 (crashfib.pir:76)
called from Sub 'parrot;A;fib' pc 91 (crashfib.pir:56)
called from Sub 'parrot;A;fibA' pc 138 (crashfib.pir:76)
called from Sub 'parrot;A;fib' pc 91 (crashfib.pir:56)
called from Sub 'parrot;A;fibA' pc 138 (crashfib.pir:76)
called from Sub 'parrot;A;fib' pc 91 (crashfib.pir:56)
called from Sub 'parrot;A;fibA' pc 138 (crashfib.pir:76)
called from Sub 'parrot;A;fib' pc 91 (crashfib.pir:56)
called from Sub 'parrot;A;fibA' pc 138 (crashfib.pir:76)
called from Sub 'parrot;A;fib' pc 91 (crashfib.pir:56)
called from Sub 'parrot;A;fibA' pc 138 (crashfib.pir:76)
called from Sub 'parrot;A;fib' pc 91 (crashfib.pir:56)
called from Sub 'bench' pc 44 (crashfib.pir:30)
Aborted

Changed 4 years ago by cotto

  • status changed from new to closed
  • resolution set to fixed

After a bit of cleanup and documentation, I merged this into master at 67af9e4f. Happy debugging!

Note: See TracTickets for help on using tickets.