First steps to debug PyCLIPS using GDB

Help
2006-03-21
2013-04-25
  • Hi,

    I noticed that, under some circumstances, the released PyCLIPS versions still produce some sometimes mysterious bugs. Of course the module can be prone to errors, although I tried to write a test suite that takes into account every single provided function. Sometimes I also extend the test suite with calls resulting from test cases that have been provided by PyCLIPS users, in order to make sure that old bugs aren't reintroduced by mistake.

    Often these bugs show up as a segmentation fault, and this is the case when a debugger is particularly useful.

    However sometimes bugs show up in situations that are difficult to reproduce, or for which it is very difficult to submit a test case. In these situations it can be useful for users to perform the first debug steps in order to better isolate the problem. Once these steps are performed and you have submitted the debugger's output, then we can decide together what to do next. I'll refer these simple instructions to the GDB debugger, as you can find a suitable version for each operating system that is supported by the GNU toolchain.

    All debugging should be done using the latest RCS version of PyCLIPS (be it CVS or SVN, at the time of writing it is still CVS) for the release to be tested. At the moment there is only the 1.0 version, so there should be no doubt about what to use for debugging - that is, the only available CVS HEAD revision. In case there will be more than one actively maintained version, then we'll refer to the CVS HEAD for each. This is because it's almost useless to debug non-development versions, as some issues can occur as results of previously examined bugs. Normally the CVS HEAD revision contains many improvements with respect to the released versions. To obtain the CVS HEAD revision, just type the following commands at the prompt - of course, "prompt$" is the command prompt itself and should not be typed :-)

    prompt$ cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/pyclips login
    (... press ENTER at the request for password ...)
    prompt$ cvs -z3 -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/pyclips co -P pyclips_module
    (... wait for the checkout to complete ...)
    prompt$

    If everything succeeded, you can cd to "pyclips_module/pyclips" and build the module as usual - or, even better, with debug support.

    1) Compiling PyCLIPS with debug support

    As explained in the documentation for distutils, you can force the build system to include debug support. This is done using the following command:

    prompt$ python setup.py build -g install

    Of course, in order to install the module you should have administrative rights on the local Python installation, so you probably should do this as root (eg. su -c "...").

    2) Invoking gdb

    As you are debugging a Python module, actually the program you load is the Python interpreter. Once the program is loaded, you can pass your test case script (or the application that causes the issue) as an argument. So, assuming that Python is installed in /usr/bin, you will invoke

    prompt$ gdb /usr/bin/python
    GNU gdb 5.2.1
    Copyright 2002 Free Software Foundation, Inc.
    (... more information ...)
    (gdb)

    The last line is the GDB prompt. I will assume that your program does not require user interaction, though I think thing should not change much otherwise. At the GDB prompt, you can load your (possibly main) script as follows:

    (gdb) set args /path/to/my_script.py --any-options and arguments

    That is, you pass to Python the whole set of arguments you need, starting with your script and then what it will read from the command line using sys.argv: after this you will be ready to run the program.

    3) Running the program

    Now that Python knows what to load when it starts, you can simply issue the "run" command at the GDB prompt:

    (gdb) run
    (... program output ...)
    Program received signal SIGSEGV, Segmentation fault.
    (... details about the call stack ...)
    (gdb)

    4) Gathering more information

    After step 3, the Python interpreter is in a "frozen" state, exactly where the error occurred. In order to get some more information you can require GDB to perform a "full backtrace" at the prompt, as follows:

    (gdb) bt full
    #0  0x0000002a9577f9e2 in EnvValidInstanceAddress (theEnv=0x520530, iptr=0x4554415254535f48) at ./clipssrc/inscom.c:648
    No locals.
    #1  0x0000002a9574a41a in g_getNextInstanceInClassAndSubclasses (self=0x520530, args=0x0) at clipsmodule.c:5760
            p = (clips_InstanceObject *) 0x2a955c7290
            q = (clips_InstanceObject *) 0x2a955c72b0
            c = (clips_DefclassObject *) 0x2a955c52b8
            o = {supplementalInfo = 0x0, type = 4, value = 0x522cd0, begin = 1, end = 4294967295, next = 0x0}
            ptr = (void *) 0x4554415254535f48
    #2  0x0000003f0218973f in _PyEval_SliceIndex () from /usr/lib64/libpython2.3.so.1.0
    No symbol table info available.

    The sample output is taken from the case shown in a bug that has been fixed using GDB, and should be similar to what you get. This is exactly the kind of information that is needed to start investigating the case, so you should copy all this output and send it to me (possibly using the SF.net tracker services).

    If you follow this simple procedure, I will have enough information to start addressing a bug, and will probably be quicker in finding out the cause. Or at least it will be much easier for me to figure out the debugging steps that should follow in order to help solve the problem.

    Thank you in advance,

    F.