C-struktuurin tulostaminen

C-struktuurin dumppaaminen ruudulle ajoaikaisesti on debuggaamisessa toisinaan hyödyksi, mutta hankalaa toteuttaa, koska on mahdotonta kirjoittaa funktiota joka selviäisi minkä tahansa struktuurin tulostamisesta, struktuurin sisäinen rakenne kun tulee tuntea sitä lukiessa tai muuten käsitellessä.

Allaolevalla pikku funktiolla voi homman hoitaa kätevästi gdb-debuggerin avustuksella. Toimintaperiaate on varsin yksinkertainen; gdb liitetään omassa lapsiprosesissa debuggaamaan ajossa olevaa äitiohjelmaa, ja käsketään debuggeria dumppaamaan halutun struktuurin sisältö ajoaikaisesti.

Esimerkkiohjelma voidaan kääntää vaikkapa vivuilla:

 gcc -g -W -Wall -o ohjelma ohjelma.c

ja kun ohjelma käynnistetään, tulostaa se odotetusti:

 0x00007f7ff743c21a in _sys___wait450 () from /usr/lib/libc.so.12
 $1 = {
   breed = 1,
   age = 2
 }
 0x00007f7ff743c21a in _sys___wait450 () from /usr/lib/libc.so.12
 $1 = {
   breed = 3,
   age = 4
 }

Esimerkkiohjelma

Valmis implementaatio näyttää tältä:

 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>

 struct pet {
        int breed;
        int age;
 };

 static void debug_dump_struct(char *s, void *p) {
        char n[1024];

        (void) snprintf(
                n, sizeof(n),
                "gdb -batch "
                " -ex 'set print pretty on'"
                " -ex 'set confirm off'"
                " -ex 'set pagination off'"
                " -ex 'p (struct %s)*%p'"
                " -ex 'quit'"
                " --pid=%d", s, p, getpid());

        (void) system((const char *) n);
 }

 int main() {
        struct pet my_cat;

        my_cat.breed = 1;
        my_cat.age = 2;

        (void) debug_dump_struct("pet", &my_cat);

        my_cat.breed = 3;
        my_cat.age = 4;

        (void) debug_dump_struct("pet", &my_cat);

        exit(0);
 }

~ Jani Salonen, 7.12.2017