Parrot's capabalities are increasing steadily, programs written for
Parrot especially those emitted from compilers are getting bigger and
bigger.
Debugging Parrot programs didn't keep up with the pace and is becoming a
PITA.
Some notes.
*) tracing or debugging an interpreter shall not influence that debugee.
This implies that any code executed during tracing or debugging is run
in a distinct interpreter. [1] [2]
This leads to some questions of how we created interpreter clones or
better: which interpreter vars and structures are how global. [3]
*) we should have distinct trace flag options, e.g.
--trace HLL_src | PIR_src | opcodes | subroutines
*) getting HLL source into Parrot
This is basically the same scheme as used for PASM/PIR source code.
- the lexer parses #line "file" comments
- this info is stored in a 2nd debug segment
*) src/debug.c and ops/debug.ops
I don't think that we should reinvent wheels and have a separate command
language for debugging (e.g. PDB_cond). Instead I'm in favor of having
just one opcode: debug_break and a Debugger PMC with methods to get e.g.
register contents/lexicals/globals from the debugee. E.g. a conditional
break point hook:
# break if I5 == 5
.sub break_i5 method
i = getattribute self, "debugee"
$I0 = self."get_reg"(i, "I5")
unless $I0 == 5 goto cont
self."break"()
cont:
cc = getattribute self, "cont"
i.cc() # invoke return continuation in debugee
.end
*) pdb - the interactive debugger [4]
pdb is basically unmaintained, buggy and outdated.
leo
[1] e.g. trace_op_dump uses PIO_eprintf which allocates mainly STRING*
resources which changes DOD/GC counts of the interpreter. This can lead
to the execution of different code paths and thus influences the running
interpreter.
[2] see USE_TRACE_DEBUG in src/runops_cores.c
[3] src/global_setup.c:init_world()
[4] make world or make pdb