Using the GNU Debugger

GNU Debugger (gdb) is an application for debugging programs. It is very powerful and can help identify the root cause of a problem. To install gdb on a Debain system, use the following command:

  # apt-get install gdb

Debugging Segmentation Faults

So you're running gatewayavd and it dies with the message: "Segmentation fault". The only error message less useful is the '?' in ed. We have no obvious way of knowing if the error happened in gatewayavd, cshampoo, or some place else. Luckily, gdb can show us exactly where the error occured. Run the following command to start debugging gatewayavd:

  # gdb ./gatewayavd

This loads the debugger and prepares it to run gatewayavd, but the debugging process has not yet begun. We have to tell gdb what command line arguments to pass to gatewayavd with set args. The command below demonstrates how to do that:

  (gdb) set args --port=10000 -f

Note the -f option. That should be used to keep gatewayavd from fork()'ing and to force it to stay in the foreground. You can start gatewayavd with the following command:

  (gdb) run

When it crashes you will be back at the (gdb) prompt. Run the backtrace command to display the stack trace.

  (gdb) bt
  #0  0xb7dde44b in strlen () from /lib/tls/i686/cmov/libc.so.6
  #1  0xb7db2164 in vfprintf () from /lib/tls/i686/cmov/libc.so.6
  #2  0xb7dadc83 in cuserid () from /lib/tls/i686/cmov/libc.so.6
  #3  0xb7dae88f in vfprintf () from /lib/tls/i686/cmov/libc.so.6
  #4  0xb7ec13b7 in daemon_log () from /usr/lib/libdaemon.so.0
  #5  0x0804a25d in virus_scan ()
  #6  0xb7f44bc2 in soap_server_find_router () from /usr/lib/libcsoap.so.1
  #7  0xb7f38ecf in httpd_send_internal_error () from /usr/lib/libnanohttp.so.1
  #8  0xb7ea9240 in start_thread () from /lib/tls/i686/cmov/libpthread.so.0
  #9  0xb7e3e4ae in clone () from /lib/tls/i686/cmov/libc.so.6

From the trace we can see that a call to daemon_log() in our function virus_scan() lead to the segmentation fault. We look at the daemon_log() calls in virus_scan() and find this:

  daemon_log(LOG_INFO, "(%u:%s) Scan Request Received", __FILE__, __LINE__);

We see that __LINE__ is an unsigned integer that is getting formatted as a string. We fix the problem as shown below:

  daemon_log(LOG_INFO, "(%s:%u) Scan Request Received", __FILE__, __LINE__);

After fixing the issue and re-compiling gatewayavd, we test to make sure that the bug was fixed.