Programowanie w systemie UNIX/gdb

Z Wikibooks, biblioteki wolnych podręczników.
logo gdb

Odpluskwianie czyli debugowanie programu[1]

Programy:

  • Gnu debugger czyli gdb[2]

Polecenia[edytuj]

  • lista poleceń[3]
  • zbadaj typ wyrażenia za pomocą ptype [4]
  • print

Przykładowa sesja[edytuj]

ekran z zapisem innej sesji

Mamy program w postaci jednego plik z kodem źródłowym C, o nazwie (przykładowej) c.c.[5]

Standardowa kompilacja:

gcc c.c

i uruchomienie:

./a.out

W celu uzyskania dodatkowych informacji kompilujemy z opcją g:

gcc -g c.c

Następnie uruchamiamy debuger gdb:[6]

gdb a.out

pokazuje się informacja o gdb:


GNU gdb (GDB) 7.6.1-ubuntu
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...

następnie informacje o uruchomionym programie:

Reading symbols from /home/a/c/mandel/unroll/new/m2/a.out...done.

i symbol gotowości gdb (otwarta sesja gdb):

(gdb)

Wpisujemy komendę uruchomienia programu:

run

W celu zakończenia sesji wpisujemy

quit

Program upewnia się:

A debugging session is active.

	Inferior 1 [process 3605] will be killed.

Quit anyway? (y or n) y

potwierdzamy (yes) wpisując:

y

co powoduje zakończenie sesji i powrót to basha.

Znajdowanie źródła problemu[edytuj]

przykłady [7]

Przykład nr 1[edytuj]

Mamy prosty program:[8]

int main() { int x = 1/0; }

kompilujemy standardowo:

gcc t.c

wynik:

t.c: In function ‘main’:
t.c:3:14: warning: division by zero [-Wdiv-by-zero]
    int x = 1/0;    
             ^

uruchamiamy program pod gdb:

gdb -q ./a.out
Reading symbols from /home/a/cn/gdb/1/a.out...(no debugging symbols found)...done.
(gdb) run
Starting program: /home/a/cn/gdb/1/./a.out 
Program received signal SIGFPE, Arithmetic exception.
0x00000000004004fc in main ()
(gdb) quit
A debugging session is active.
Inferior 1 [process 5477] will be killed.
Quit anyway? (y or n) y

Teraz kompilujemy z opcją g:

gcc -g t.c
t.c: In function ‘main’:
t.c:3:14: warning: division by zero [-Wdiv-by-zero]
    int x = 1/0;    


i uruchamiamy pod gdb:

gdb -q ./a.out
Reading symbols from /home/a/cn/gdb/1/a.out...done.
(gdb) run
Starting program: /home/a/cn/gdb/1/./a.out 

Program received signal SIGFPE, Arithmetic exception.
0x00000000004004fc in main () at t.c:3
3	    int x = 1/0;    
(gdb) quit
A debugging session is active.

	Inferior 1 [process 5488] will be killed.

Quit anyway? (y or n) y

Otrzymujemy więcej informacji

Przerwania[edytuj]

Uruchamiamy sesję:

gdb a.out

Jeśli podejrzewamy w którym miejscu w czasie wykonywania programu powstaje błąd, to możemy ręcznie przerwać wykonywanie przed wykonaniem błędnego kodu. Pozwoli to nam na dokładniejszą analizę ( krok po kroku). Przed uruchomieniem programu w czasie sesji debuggera ustanawiamy przerwanie.

Mamy do wyboru przerwanie przed:[9]

  • linią kodu: break source_filename:line_number (przykład: break c.c:8)
  • funkcją: break source_filename:function_name (przykład: break m.c:GivePeriod)
  • instrukcją: break *PC (przykład: break *0x1f7b ustanawia przerwanie przed instrukcją main)

Informacja o przerwaniach:

info breakpoint

i przykładowa odpowiedź:

Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x0000000000400b3b in GivePeriod at m.c:132
	breakpoint already hit 1 time

Usuwanie przerwań:

clear m.c:8

Kontynuację działania programu po przerwaniu uzyskujemy za pomocą instrukcji continue lub skrótowo c

c

Kod maszynowy[edytuj]

Zobacz również[edytuj]

inne narzędzia

  • elfutils released in version 0.178, 2019-11
  • systemtap automatic via elfutils
  • dwarves automatic via elfutils
  • dwgrep automatic via elfutils
  • ltrace automatic via elfutils
  • libabigail automatic via elfutils
  • QT Creator perfparser automatic via elfutils
  • binutils released in version 2.34, 2020-02
  • gdb released in version 10.1, 2020-10
  • dyninst released in version 11.0 2021-04
  • valgrind released in version 3.17.0, 2021-03
  • annocheck released in version 9.03, 2020-01
  • delve released in version 1.7.2, 2021-09
  • llvm symbolizer merged, server merged, lldb help wanted, see also
  • bpftrace released in version 0.21.0, 2021-07
  • perf released in linux 5.10, 2021-01
  • systemd-coredumpd help wanted
  • retrace/abrt/faf in progress amerey@redhat.com
  • vtune help wanted
  • pixie help wanted
  • sentry symbolicator partly released partly help wanted
  • VS Code automatic via gdb
  • WinDbg released in version 1.2104.13002.0, 2021-04
  • UDB released in version 6.5
  • parca released in version 0.8.0, 2022-02

Źródła[edytuj]

  1. eric lippert: how-to-debug-small-programs
  2. beej guide gdb
  3. GDB commands by function - simple guide by Jim Binkley
  4. learning-c-with-gdb by Alan O'Donnell
  5. How to Debug C Program using gdb in 6 Simple Steps by by SathiyaMoorthy on March 15, 2010
  6. Tutorial of gcc and gdb by Steven Swanson
  7. Locating a segmentation fault (by ElieDeBrauwer)
  8. stackexchange: Linux GCC compiler options
  9. Tutorial of gcc and gdb by Steven Swanson
  10. Source and Machine Code from gdb doc
  11. How can I force GDB to disassemble?