On Tue, 22 Nov 2005, Michael Seele wrote:
hi,
i write on a (java) gui for the perl debugger and have a problem: when i use
the perl debugger i can suspend the execution with CTRL+C. i talk over a
socket with the perl debugger process and the problem is that i can't send
CTRL+C from the java programm to the perl process. for this reason i should
extend the perl debugger: i will send a special command(e.g. SUSPEND) to the
perl debugger and the debugger should execute the method bundeled with
$SIG{INT}(catch() method).
is this possible?
i think i can override the DB method of the debugger and check for the
special command. after checking i would like to call the original DB method.
here are my little try:
PERL5DB={ package DB; our @ISA='DB'; sub DB { } }
but when i doe this i got errors everytime. can you help my how to override
the debugger!?
Are you trying to catch the program in mid-execution and halt it? That
might take a bit of diddling about to do, since the debugger's not reading
from its input filehandle during continuous execution. A watchfunction()
could possibly check for input pending on the debugger's input filehandle
using 3-argument select() and interrupt execution based on that (it can
set $DB::single, which drops the debugger back into single-step mode).
Normally this would be a bad idea (if the user started typing anything,
the program would suddenly stop running), but since the GUI's controlling
access to the debugger, it should work fine. Here's a basic cut at doing
this; you will probably have to tweak it a bit to make sure that it works
properly.
Just before going into continuous execution, execute "$DB::trace |= 4;"
(sending this to the debugger directly is as good as any way to do it).
This tells the debugger to enable the watchfunction.
In your .perldb (or perldb.ini, on Windows), add this:
sub watchfunction {
my $rin = ''; my $rout;
vec($rin,fileno(DB::IN),1)=1;
# Wait 5 milliseconds for input to be present.
$DB::single |= 1
if select($rout=$rin, undef, undef, 0.05);
}
This will define the watchfunction for you (note that this way you need no
mods to the debugger). Here's how it goes:
Normally, you're executing without the watchfunction (the program's not
running continuously). When your interface wants to start continuous
execution (the 'c' command, most likely; possibly if you want to be able
to interrupt the execution of code entered by the user), set $DB::trace to
turn on the watchfunction, and then issue the 'c' command. Before each
statement, the watchfunction looks to see if anything is queued up on
DB::IN, and sets $DB::single (which stops continuous execution), dropping
you back into single-step mode, and giving you control again.
You don't have to create the watchfunction in .perldb; you can actually
send it to the debugger as one long line and define it that way.
I note that the select() documentation notes that this may not work for
buffered filehandles, but as I recall, we unbuffer DB::IN, so this will
probably work fine. I can't guarantee it, but this is probably your best
angle of attack to get things in place with the minimum fuss.
--- Joe M.