Nie taki GDB straszny - wprowadzenie do debuggera

Aby zacząć używać GDB (GNU Project Debugger) powinniśmy skompilować nasz kod z opcją -ggdb, co powoduje dodanie symboli dla debuggera. Podczas debuggowania nie używamy żadnych opcji optymalizacji kodu, które potencjalnie mogą mocno zmodyfikować sposób i kolejność wykonywania instrukcji.

Na początek podstawowe komendy gdb i sposób uruchamiania procesów via gdb:

Jako dwóch przykładów użyję kodu example1/example2 z artykułu o strace (który bardzo polecam - nie zawsze mamy możliwość komfortowej kompilacji i pracy z GDB, a często strace może okazać się wystarczający w diagnozowaniu problemu).

W przypadku example1.c nie zaobserwujemy żadnych problemów, program wykona się poprawnie.

Na przykładzie kodu example2.c przetestujemy szukanie błędu w programie. Program próbuje połączyć się na localhost:5000 i wysłać tam dane (*send_data):

Po uruchomieniu example2 nie zwraca żadnego błędu. Ciekawy jest natomiast kod wyjścia z programu:

Jako kod wyjścia dostajemy 141, zamiast 0 (które oznacza prawidłowe zakończenie procesu). Pójdźmy zatem dalej, kompilując example2.c z opcją -ggdb i śledząc przebieg wykonywania:

Okazuje się że w linii 33 (example2.c:33) dostajemy SIGPIPE, czyli sygnał próby zapisu do potoku, do którego pisać się nie da (w tym wypadku chodzi o niepowodzenie funkcji connect z linii 30). Wniosek: connect powinien zostać obłożony warunkiem, na przykład tak:

Na koniec należy dodać, że nigdy nie powinno się korzystać z kodu skompilowanego z opcjami debuggowania w środowisku docelowym, produkcyjnym - może to wpłynąć negatywnie na wydajność aplikacji. Dodatkowo można go strippować (komenda strip), usuwając wszystkie zbędne przy wykonywaniu informacje - co zmniejsza rozmiar pliku wykonywalnego i teoretycznie może poprawić szybkość wykonywania kodu.

  • Paweł

    Jaki z tego morał?? :) ,że żaden IF z nie wiadomo jak poważnie zapisanymi warunkami które potencjalnie potrafią przewidzieć wszystko nie zastąpi prostego ..... else :)

  • rosek

    Hej, fajny artykuł, ale przydało by się jeszcze coś o tym do czego debugger jest najczęściej używany, czyli wyszukiwanie miejsca wystąpienia błędu. Fajnie by było dodać chociaż jakieś informacje o breakpointach, poleceniach continue, next, setep i jeszcze o tym, że można stosować skróty; c, n, s, b, r itd.

    pozdr,
    Krzysiek

  • Marcin Sawicki

    Masz rację. To miał być wstęp do tematu, a dużo konkretniejsza część druga leży w szkicach :)