GNU Debugger, הידוע יותר בשמו GDB, הוא מנפה השגיאות הסטנדרטי למערכת התוכנה של גנו. זהו מנפה שגיאות מרובה פלטפורמות שרץ על מערכות דמויות יוניקס רבות ועובד עם שפות תכנות רבות, כגון C, C++, ו-Fortran. זוהי תוכנה חופשית אשר מופצת תחת רישיון GPL (גרסה 3).
GDB מציע אמצעים נרחבים למעקב ושינוי של הרצת תוכנה. המשתמש יכול לפקח ולשנות את הערכים של המשתנים הפנימיים של התוכנית ואפילו לקרוא לפונקציה ללא תלות בהתנהגות הנורמלית של התוכנית.
GDB לא כולל ממשק גרפי למשתמש משל עצמו וכברירת המחדל הוא פועל מממשק שורת פקודה. אולם, מספר ממשקים גרפיים נבנו בשבילו, כגון DDD, "מצב GUD" ב-Emacs, ו-KDevelop. אלה מציעים אמצעים דומים אשר למנפי שגיאות המופיעים בסביבות פיתוח משולבות.
מספר כלי ניפוי אחרים עוצבו כדי לעבוד עם GDB, כגון גלאי דליפת זיכרון.
GDB מציע מגוון פיצ'רים שמאפשרים מעקב אחרי ריצה של תוכנית, כמו גם שינוי שלה. למשל, ניתן לעקוב אחר ערכים של משתנים פנימיים בתוכנית ואף לקרוא לפונקציות באופן יזום, ללא תלות בריצת התוכנית.
מספר רב של מעבדים נתמכים על ידי GDB (נכון ל-2003): Alpha, ARM, H8/300, System/370, System 390, X86, X86-64, איטניום, מוטורולה 68000, MIPS, PA-RISC, PowerPC, SuperH, SPARC, VAX, Nios ועוד. מעבדים פחות ידועים אשר נתמכים על ידי הגרסה הסטנדרטי של GDB כוללים את : A29K, ARC, AVR, CRIS, D10V, D30V, FR-30, FR-V, Intel i960, M32R, 68HC11, Motorola 88000, MCORE, MN10200, MN10300, NS32K, Stormy16, V850, VAX, ו-Z8000 (גרסאות חדשות יותר ככל הנראה לא יכללו חלק מהם).
GDB מציע אפשרות לבצע ניפוי שגיאות מרוחק. במצב זה, GDB רץ במכונה אחת, ואילו התהליך שממנו מנופות השגיאות (התהליך ה"מדובג") רץ במכונה אחרת. שימוש במצב זה נעשה בעיקר כאשר מנפים שגיאות במערכת משובצת מחשב.
$ gdb program
(gdb) run
(gdb) break
(gdb) info registers
(gdb) disassemble func
עבור הקוד הבא שנכתב בשפת C:
#include <stdio.h> #include <stdlib.h> #include <string.h> size_t foo_len( const char *s ) { return strlen( s ); } int main( int argc, char *argv[] ) { const char *a = NULL; printf( "size of a = %lu\n", foo_len(a) ); exit( 0 ); }
הקוד הנ"ל מהודר באמצעות GCC בלינוקס. על מנת שיהיה ניתן לבצע ניפוי שגיאות עבורו באמצעות GDB, יש לקמפל אותו תוך שימוש בדגל g- (במצב זה הקובץ הבינארי שייווצר יכלול debug information). בהתאם, יש לעשות שימוש בפקודה הבאה: כעת ניתן להפעיל את הקובץ הבינארי:
g-
$ ./example Segmentation fault
כפי שניתן לראות, כאשר מריצים את הקוד לדוגמה מתרחשת שגיאת סגמנטציה. ניתן להשתמש ב-GDB כדי לבדוק את הבעיה ולנפות את השגיאות.
$ gdb ./example GNU gdb (GDB) Fedora (7.3.50.20110722-13.fc16) Copyright (C) 2011 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <https://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-redhat-linux-gnu". For bug reporting instructions, please see: <https://www.gnu.org/software/gdb/bugs/>... Reading symbols from /path/example...done. (gdb) run Starting program: /path/example Program received signal SIGSEGV, Segmentation fault. 0x0000000000400527 in foo_len (s=0x0) at example.c:7 7 return strlen (s); (gdb) print s $1 = 0x0
הבעיה נמצאת בשורה 7, ומתרחשת בעת קריאה לפונקציה strlen (מכיוון שהיא מקבלת כקלט משתנה שהוא NULL ). על מנת לתקן את הבעיה, המשתנה a (בפונקציה main ) חייב להכיל מחרוזת חוקית. הנה גרסה מתוקנת של הקוד:
strlen
NULL
a
main
#include <stdio.h> #include <stdlib.h> #include <string.h> size_t foo_len( const char *s ) { return strlen(s); } int main( int argc, char *argv[] ) { const char *a = "This is a test string"; printf( "size of a = %lu\n", foo_len(a) ); exit( 0 ); }
כעת ניתן להדר את הגרסה המתוקנת של הקוד ולהריץ:
$ gdb ./example GNU gdb (GDB) Fedora (7.3.50.20110722-13.fc16) Copyright (C) 2011 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <https://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-redhat-linux-gnu". For bug reporting instructions, please see: <https://www.gnu.org/software/gdb/bugs/>... Reading symbols from /path/example...done. (gdb) run Starting program: /path/example size of a = 21 [Inferior 1 (process 14290) exited normally]