Another way to see a trace of the running
code is to use a debugger such as gdb (the GNU
debugger). It's supposed to work on any platform
that supports the GNU development tools. Its purpose is to allow you
to see what is going on inside a program while it executes, or what
it was doing at the moment it failed.

To trace the execution of a process, gdb needs to
know the PID and the path to the binary that the process is
executing. For Perl code, it's
/usr/bin/perl (or whatever the path to your Perl
is). For httpd processes, it's
the path to your httpd executable—often
the binary is called httpd, but
there's really no standard location for it.

Here are a few examples using gdb. First,
let's go back to our last locking example, execute
it as before, and attach to the process that didn't
get the lock:

panic% gdb /usr/bin/perl 3037

After starting the debugger, we execute the
where command to see the trace:

That's not what we may have expected to see (i.e., a
Perl stack trace). And now it's a different trace
from the one we saw when we were using strace.
Here we see the current state of the call stack, with main(
) at the bottom of the stack and flock(
) at the top.

We have to find out the place the code was called
from—it's possible that the code calls
flock( ) in several places, and we
won't be able to locate the place in the code where
the actual problem occurs without having this information. Therefore,
we again use the curinfo macro after loading it
from the .gdbinit file:

As we can see, the program was stuck at line 9 of
/home/httpd/perl/excl_lock.pl and
that's the place to look at to resolve the problem.

When you attach to a running process with gdb, the
program stops executing and control of the program is passed to the
debugger. You can continue the normal program run with the
continue command or execute it step by step with
the next and step commands,
which you type at the gdb prompt.
(next steps over any function calls in the
source, while step steps into them.)

The use of C/C++ debuggers is a large topic, beyond the scope of this
book. The gdb man and info pages are quite good.
You might also want to check ddd (the Data Display
Debugger), which provides a visual interface to
gdb and other debuggers. It even knows how to
debug Perl programs.

For completeness, let's see the
gdb trace of the httpd
process that's hanging in the
while(1) loop of the first example in this
section: