Here's a silly little tool that I've used for a long time to help
debug various programs. I just added perl support to it, so I thought
I'd announce it in case anyone got some use out of it.

To use it, save it into your $PATH somewhere. Then, instead of running
"./someapplication args...", run "debug ./someapplication args..."
instead. If "someapplication" is a compiled binary other than perl, it
will bring up an emacs window with gdb running the application within
it. If "someapplication" is either perl or an executable perl script,
it will bring up an emacs window running perldb with the application
loaded (and it also chdirs to the correct path, instead of perldb's
usual annoying behavior).

There are some environment variables that you can use to control
whether the application will be running under GDB when the window pops
up (the default), or whether it will just set the arguments and give
you a chance to run it yourself. Read the source for details.

Note that this won't help much if you're debugging something that
exec's the thing you really want to debug, but you can usually work
around that by changing the exec to put "debug" in front of the actual
command. This, in fact, is the "killer application" for this script,
since it will then pop up windows no matter how deeply buried the
interesting invocation is, and the whole environment should be set up
nicely.

If you're trying to use this, or perldb in general, to debug the perl6
driver program, watch out -- perl6 uses *massive* amounts of stack
space, so to get anything useful you'll probably need to set the max
stack depth to 1000 instead of the default 100.

  BEGIN { $DB::deep = 1000 }

should do it, I think. (Once again, my notes on that are at home.)

Let me know if you find this useful, or think I'm stupid for not
knowing a much nicer way of doing this.
#!/bin/bash -f

# This script opens up an emacs window with the given program running
# under a debugger, all automagic-like.
#
# Usage: debug <program> <args>...
#
# Various environment variables can affect the operation. Let's see...
#   $DBG : set to qr/EXPRESSION/ to only fire up emacs for programs
#          that match the given regex.
#   $GDB_INITFILE : gdb will execute this file when it starts up.
#          There are better ways of doing this, you know.
#   $GDB_INITSTRING : execute the given gdb command at startup.
#   $GDB_INTERACTIVE : set this to any nonempty value to have gdb
#          pause before running the program.
#
# Most of those options don't work or aren't relevant for the perl
# debugger.

COMMAND=$(echo $1 | perl -lpe 's!//!/!g')
shift

# Check whether we should skip debugging this invocation
# (if DBG is set to qr/something/ that doesn't match the command line)
if perl -e '$args=join(" ",@ARGV); print "MATCHING $ENV{DBG} AGAINST $args\n"; if 
($ENV{DBG} !~ /^qr/) { exit(1); } else { $match=eval $ENV{DBG}; exit(($args =~ $match) 
? 1 : 0); }' $COMMAND $*; then
    exec $COMMAND $*
fi

function debug_perl () {
    CWD=`pwd`
    exec emacs --eval "(progn (perldb \"perl $*\") (insert-string \"chdir('$CWD')\") 
(comint-send-input))"
}

if [ $COMMAND = perl ]; then
    debug_perl $*
elif file $COMMAND | grep "perl script"; then
    debug_perl "$COMMAND" $*
fi

# Set the arguments
INIT_EVAL="(insert-string \"set args $*\") (comint-send-input) (insert-string \"cd 
$(pwd)\") (comint-send-input)"

# If env var GDB_INITFILE set, load it into gdb on startup
if [ ! "x$GDB_INITFILE" = x ]; then
        echo Loading init file $GDB_INITFILE >&2
        INIT_EVAL="$INIT_EVAL (insert-string \"source $GDB_INITFILE\") 
(comint-send-input) "
fi

# If env var GDB_INITSTRING set, give it to gdb
if [ ! "x$GDB_INITSTRING" = x ]; then
        echo Sending gdb command $GDB_INITSTRING >&2
        INIT_EVAL="$INIT_EVAL (insert-string \"$GDB_INITSTRING\") (comint-send-input) "
fi

# If env var GDB_INTERACTIVE or DBG eq 'wait', let the user run the gdb session
if [ "x$GDB_INTERACTIVE" = x ] && [ ! "x$DBG" = xwait ]; then
        echo Running gdb immediately >&2
        INIT_EVAL="$INIT_EVAL (insert-string \"run\") (comint-send-input) "
        echo INIT_EVAL="$INIT_EVAL"
fi

exec emacs --eval "(progn (gdb \"gdb $COMMAND\") $INIT_EVAL)"

# Copyright (c) 2002-3 by Steve Fink. All rights reserved.
#
# You may do anything you want with this script, as long as you don't
# use it to directly or indirectly cause harm to any mythical
# creatures. Only real creatures may be harmed by the running of this
# script. Oh, and you can't remove my copyright notice either, no
# matter how much you mutate the script itself.
#
# But if you're nice, you'll properly document all the funky options,
# clean it up, and send it back to me at [EMAIL PROTECTED] And you seem
# like a really nice person to me.

Reply via email to