As short as possible primer about using "gdb" to debug SIGSEGV (or any other problem) inside GIMP plugin.

PomocSpisTreści

  1. Debugging normal programs
  2. Debugging GIMP plugin

Debugging normal programs

For normal programs (not GIMP plugins) debugging is relatively simple. You can test it with the sample file below (I named it a.cpp on my disk) that makes a deliberate segmentation fault:

#include <iostream>
using namespace std;

int main(int argc,char *argv[])
{
  int x = 123;
  cout << "Deliberately make segfault now: " << endl;

  /* treating hardcoded "123" as a pointer is nonsense,
     this is an invalid pointer. */
  cout << ((char*)x) << endl;
}

Compile it like

g++ -g a.cpp

If you just run this program as usual:

./a.out

you will get

Deliberately make segfault now: 
Segmentation fault

(If you see the "Segmentation fault" message in Polish, but you would prefer English, you can always do

export LANG=C

first). Now try running the same program in the debugger. In the terminal, do

gdb ./a.out

and you will land in gdb prompt ("(gdb) "). Type

run

and you should get something like

Starting program: /tmp/a.out 
Deliberately make segfault now: 

Program received signal SIGSEGV, Segmentation fault.
0xb7db31cb in strlen () from /lib/i686/cmov/libc.so.6

The messages "Program received signal SIGSEGV" are from gdb. When your program receives SIGSEGV, the gdb immediately stops the program, and you can inspect where in your code did this happen. Actually, the line "... in strlen ..." already tells you when did this happen, but it's not helpful --- strlen is not your procedure. So type inside gdb

backtrace

(or a shortcut "bt"). This will print something like

#0  0xb7db31cb in strlen () from /lib/i686/cmov/libc.so.6
#1  0xb7f5b62c in std::operator<< <std::char_traits<char> > ()
   from /usr/lib/libstdc++.so.6
#2  0x080486e3 in main () at a.cpp:8

Read it from the bottom to the top: this means that your program (a.cpp, line 8) called std::operator<<..., that called strlen, that caused segmentation fault. In this case, the line about your program (a.cpp:8) just tells you exactly when did this happen.

Note that we compiled a.cpp with "-g" parameter for g++, this let's us see this line information.

There is much more you can do with gdb. You can print the value of a particular variable at this point (type "help print" in gdb). Also, you can set your own breakpoints (to stop the program not only when it received the sigsegv error, but at any time you want) --- type "help break" in gdb. You can continue the stopped program by typing "continue" (short "cont"). You can kill it ("kill"), restart it ("run" again) and such. See GDB User Manual. Gdb also has a lot of built-in help (try "help", or "help command").

You can try to do the same in "ddd" (or any other graphical frontend). It's just a graphical frontend to "gdb", which means it does the same thing (internally using gdb library or even gdb program anyway), works the same, you just have graphical buttons instead of the command-line interface. It may be somewhat nicer than using "gdb" directly, but it's a matter of taste. There are many more "gdb" frontends, like "kdbg" and "insight". There are also nice IDEs (editor + debugger and such), like "anjuta" or "kdevelop". (I don't know which ones are installed in university labs.)

Debugging GIMP plugin

Now, next step to learn is how to debug a GIMP plugin. It's a little more complicated than normal programs, since you cannot just run your program ("anl_dialog") directly. You have to let GIMP run it, when you click the menu item with your plugin.

Detailed information is on http://developer.gimp.org/debug-plug-ins.txt. Instructions below are just a practical example.

Remember to add "-g" to the g++ command in the Makefile. Then compile and install your plugin like usual, "make install" (or even "make clean && make install", to force recompiling everything with -g).

In the console type

export GIMP_PLUGIN_DEBUG=anl_dialog

Then in the same console run gimp. From the GIMP click on the menu item of your plugin. You will see that your plugin hangs, and GIMP writes on the console something like

(anl_dialog:9419): LibGimp-DEBUG: Waiting for debugger...

The number "9419" is important --- this is the "pid" (Process IDentifier under Unix). Knowing this pid, you can open a second terminal, and execute gdb there, and "attach" gdb to your running plugin process. So in this second terminal do

gdb anl_dialog

(We pass filename "anl_dialog" as parameter, as you still have to point gdb to the executable file of your program. Remember to "cd" to the right directory first, and type "and_dialog" with full file path.) Inside gdb, do

attach 9419

This will answer with

Attaching to program: .../anl_dialog, process 9419
Reading symbols ....
(a lot of "Reading symbols ...." lines...)

Now, still inside gdb, type

continue

(shortcut "cont"). If you get an answer "Program received signal SIGSTOP", just keep doing "continue". Eventually your plugin will unhang (you will see your plugin dialog).

And then proceed like with a normal program --- press "Ok" on the dialog, and when it will receive SIGSEGV, gdb will stop the program, you will see "Program received signal SIGSEGV" and you can type "backtrace", "print variable_name" and such.