in reply to Is there any way of determining the current line number of a child process while it is running?
Getting a bit uglier, here's a hack that takes a rather different approach: it uses 'gdb' to attach to the process with the given pid, and queries perl's internal structures.
Use with caution. :)
#!/usr/bin/perl -w my $perl = $^X; my $pid; my $tmpfile = "/tmp/attachperl-$$"; if (@ARGV == 1) { ($pid) = @ARGV; } elsif (@ARGV == 2) { ($perl, $pid) = @ARGV; } else { die "Usage: $0 [ /path/to/perl ] <pid>\n"; } # construct the gdb script open F, ">$tmpfile" or die "$tmpfile: $!\n"; print F <<GDB; p ((COP*)PL_curcop)->cop_line p ((XPVGV*)((COP*)PL_curcop)->cop_filegv->sv_any)->xgv_name quit GDB close F; my $call = "gdb -q -x $tmpfile $perl $pid 2>/dev/null"; my @data = map /^\$\d+ = (.*)$/ ? $1 : (), `$call`; my $line = $data[0] =~ /^\d+$/ ? $data[0] : 'unknown'; my $file = $data[1] =~ /^0x\w+ "_<(.*)"$/ ? $1 : 'unknown'; print "pid $pid: line $line of file '$file'\n"; unlink $tmpfile;
A brief explanation: PL_curcop is a variable used in perl to hold details about the current execution state, including the last seen line number and a reference to the glob for the file the code came from. Note that occasionally PL_curcop may be null, in which case this'll just print "unknown". Also, when the execution is inside code evalled from a string, it'll show something like:
.. which may not be supremely useful if your code spends a lot of time in such things.pid 9256: line 1 of file '(eval 1)'
I should stress that this is a quick hack - doing it properly would at the very least involve using a safer approach for temporary files. I'm also not sure how recent a version of gdb is required for this, though it works ok for me with "GNU gdb 5.0rh-5 Red Hat Linux 7.1".
Hope it helps,
Hugo
|
|---|