Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

Journal of jjore (6662)

Monday July 20, 2009
10:48 AM

Add remote debugging terminal to mod_perl

[ #39325 ]

Occasionally my mod_perl servers go sour and it's useful to attach a remote debugger. There's typically no useful console and production doesn't run under the debugger. I'm forced into two things: force load the debugger with Enbugger and then have it connect to a remote terminal.

Works great BTW and is almost identical to http://use.perl.org/~jjore/journal/39319. The only real difference is we're eval()ing something different. This is also documented as a "cookbook" recipe in at http://search.cpan.org/dist/Enbugger.

Step 1: Start a remote terminal. I like netcat. I'll just start a Terminal and have it listen on port 8000. Anything that connect there will show up and I'll be able to type to it, etc.

nc -l 8000

Step 2: Attach GDB to mod_perl. Assuming my process ID is 765, I can attach with the simple command:

gdb -p 765

It's occasionally useful to know if there's anything "interesting" going on so get a quick backtrace of the current call stack:

(gdb) backtrace
#0  0xb7f7b919 in poll () from /lib/tls/libc.so.6
#1  0xb7da57ff in apr_poll () from /opt/apache/das/lib/libapr-0.so.0
#2  0x080b2050 in child_main ()
#3  0x080b231e in make_child ()
#4  0x080b2393 in startup_children ()
#5  0x080b279c in ap_mpm_run ()
#6  0x080b93c9 in main ()

Step 3: As in http://use.perl.org/~jjore/journal/39319, I need to know whether there's a thread context to pass into eval().

(gdb) print $thread_context = (void*)Perl_get_context()
$1 = (void *) 0x0

OR

(gdb) print $thread_context = (void*)Perl_get_context()
$1 = (void *) 0x800000

Step 4: Install the debugger. If you've got a $thread_context, it goes before the eval string (eval_pv($ctx,"...",0)).

(gdb) call (void*)Perl_eval_pv("eval { require Enbugger; print STDERR qq{stopping\\n}; $ENV{PERLDB_OPTS} = 'RemotePort=localhost:4000'; Enbugger->stop;}; print STDERR $@; print STDERR qq{stopped?\\n};", 0)

Step 5: profit:

jjore$ nc -l -p 4000
 
Loading DB routines from perl5db.pl version 1.28
Editor support available.
 
Enter h or `h h' for help, or `man perldebug' for more help.
 
x
main::((eval 982):1):    print STDERR $@
  DB<1> 0  0
  DB<1>

Step 6: Now detach to resume your program. You've interrupted your program at two levels. First at perl, so run "c" to continue out from the perl debugger. Second, in gdb so "detach" or "quit" to continue the process.

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.