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.

Reply via email to