Chapter 6. Debugging applications


"A bug is a test case you haven't written yet."

Mark Pilgrim - "Dive Into Python"

Writing source code is only the first step in application development. In the real life a programmer is a debugger, not a coder.

6.1. printf approach

The first debugging tool is printf function. Most libjf function returns a "return code" of type int. File jf/jf_errors.h contains all the available return codes, but you probably would a more human readable error code than an integer value. Function jf_strerror returns a description for every return code documented in jf/jf_errors.h. This is a little usage example:

Example 6-1. jf_strerror.c

#include <jf_file.h>

int main()
        int rc;
        jf_file_t jf;

        rc = jf_file_close(&jf);
        if (JF_RC_OK != rc) {
                fprintf(stderr, "libjf error: %s (%d)\n", 
                        jf_strerror(rc), rc);
                return 1;
        return 0;
You can compile it with this command:
libtool --mode=link gcc -Wall-I/opt/libjf/include -L/opt/libjf/lib -ljf \
        -o jf_strerror jf_strerror.c
Trying to execute this foolish program you should get an error like this one:
tiian@linux:~/tutorial> ./jf_strerror
libjf error: ERROR: object is corrupted (-9)

6.1.1. Error codes' rule of thumb

JF_RC_OK is the return code every API should return. Warning values are values larger than JF_RC_OK. Error values are values smaller than JF_RC_OK.


You should never use numeric constant when checking libjf API return codes.