מנתח קוד מקור עוצמתי עבור תוכניות Linux

A debugger plays a vital role in any software development system. Nobody can write a bug-free code all at once. During the course of development, bugs are being raised and needs to be solved for further enhancement. A development system is incomplete without a debugger. Considering the open source developers community, GNU Debugger is their best choice. It is also used for commercial software development on UNIX type platforms.

Debugging source code with GNU Debugger

מנתח GNU, ידוע גם כ- gdb, מאפשר לנו לשקף דרך הקוד בזמן ביצועו או מה תוכנית ניסתה לעשות ברגע לפני שהתקעה התרחשה. gdb מסייע לנו בעיקר בארבעה דברים ראשיים כדי לתפוס תקלות בקוד המקור.

  1. להתחיל את התוכנית, תוך ציון ארגומנטים שעשויים להשפיע על ההתנהגות הכללית.
  2. לעצור את התוכנית על תנאים מסוימים.
  3. לבחון את התקלה או העצירה של התוכנית.
  4. לשנות את הקוד ולנסח בניסיון עם הקוד ששונה באופן מיידי.

ניתן להשתמש ב-gdb לאיתור באגים בתוכניות שנכתבו ב-C וב-C++ בלי מאמץ רב. בימינו, תמיכה בשפות תכנות נוספות כמו D, Modula-2, Fortran היא חלקית.

התחלה עם מנתח GNU או ג'י.די.בי.

GDB נקרא באמצעות פקודת ה- gdb. כאשר מוצאים gdb, התוכנית מציגה מידע מסוים על הפלטפורמה ומפנה אותך אל תוך ה- (gdb) prompt כפי שמוצג להלן.

[root@fedora20 ~]# gdb
פלט מדגם
GNU gdb (GDB) Fedora 7.6.50.20130731-19.fc20 
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-redhat-linux-gnu". 
Type "show configuration" for configuration details. 
For bug reporting instructions, please see: 
<http://www.gnu.org/software/gdb/bugs/>. 
Find the GDB manual and other documentation resources online at: 
<http://www.gnu.org/software/gdb/documentation/>. 
For help, type "help". 
Type "apropos word" to search for commands related to "word". 
(gdb)

הקלד עזרה רשימה כדי לראות את הקטגוריות השונות של הפקודות הזמינות בפנים gdb. הקלד עזרה ואז את שם הקטגוריה כדי לקבל רשימת פקודות בקטגוריה זו. הקלד אזרחות כל בשביל רשימת כל הפקודות. החצים של שמות הפקודות מותרים אם הם בלתי רותחים. לדוגמה, ניתן להקליד הבא במקום להקליד הבא או תמיכה במקום המשך וכו'.

הפקודות הנפוצות ביותר ב-GDB

הפקודות gdb הנפוצות מופיעות בטבלה שלמטה. יש להשתמש בפקודות אלו ממסך ה-prompt של gdb (gdb).

Command
Description
run
Start a program execution
quit
Quit gdb
print expr
Print expression where expr may be a variable name too
next
Go to next line
step
Step into next line
continue
Continue from the current line till the end of program or next break point

שימו לב להבדל בין שתי הפקודות צעד ו־הבא. פקודת הבא אינה נכנסת לפונקציה אם השורה הבאה היא קריאת פונקציה. בניגוד לכך, פקודת צעד יכולה להיכנס לתוך הפונקציה ולראות מה קורה שם.

A sample session with GDB

שקול את קוד המקור הבא.

// sum.c
#include <stdio.h> 

int sum (int a, int b) { 
	int c; 
	c = a + b; 
	return c; 
} 

int main() { 
	int x, y, z; 
	printf("\nEnter the first number: "); 
	scanf("%d", &x); 
	printf("Enter the second number: "); 
	scanf("%d", &y); 
	z = sum (x, y); 
	printf("The sum is %d\n\n", z); 
	return 0; 
}

כדי לאתר את קובץ הפלט במצב דיבאג, עלינו לקומפל אותו עם אפשרות -g ל־gcc באופן הבא.

$ gcc -g sum.c -o sum

קובץ הפלט sum ניתן לציוד ל-gdb באמצעות אחת משתי הדרכים הבאות:

1. על ידי ציון קובץ הפלט כארגומנט ל־gdb.

$ gdb sum

2. הפעלת קובץ הפלט ב־gdb בעזרת הפקודה קובץ.

$ gdb
(gdb) file sum

הפקודה רשימה מציגה שורות בקובץ קוד המקור ומעבירה את הסמן. אז ראשית רשימה תציג את השורות הראשונות 10 ובהמשך רשימה תציג 10 הבאות וכן הלאה.

(gdb) list
1	#include <stdio.h>   
2	 
3	int sum (int a, int b) { 
4		int c; 
5		c = a + b; 
6		return c; 
7	} 
8	 
9	int main() { 
10		int x, y, z;

להתחיל בביצועים, נתן את הפקודה הרץ . עכשיו התוכנית מבוצעת באופן רגיל. אך שכחנו להכניס מקומות עצירה בקוד המקור למטרת דיבאג. אפשר לציין מקומות עצירה אלו עבור פונקציות או בשורות מסוימות.

(gdb) b main

הערה: שימרתי קיצור דרך b עבור שבירה.

לאחר שהוגדר נקודת העצירה במרכז הפונקציה, הרצת התוכנית תעצור בשורה 11. דבר זה ניתן לעשות גם אם מספר השורה ידוע מראש.

(gdb) b sum.c:11

עכשיו ניתן לדלג דרך השורות בקוד באמצעות פקודת הבא או n. חשוב לשים לב שפקודת הבא לא תכנס לקוד הפונקציה אלא אם נקבע נקודת עצירה על הפונקציה. בואו ננסה את הפקודה הדפס עכשיו. הגדר נקודת עצירה על הפונקציה sum כמצוין מטה.

(gdb) b sum 
Breakpoint 1 at 0x4005aa: file sum.c, line 5. 
(gdb) r 
Starting program: /root/sum 

Enter the first number: 2 
Enter the second number: 3 

Breakpoint 1, sum (a=2, b=3) at sum.c:5 
5		c = a + b; 
(gdb) p a 
$1 = 2 
(gdb) p b 
$2 = 3
(gdb) c 
Continuing. 
The sum is 5 

[Inferior 1 (process 3444) exited normally]

אם התוכנית שזזזת דורשת פרמטרי קו מפקודה, יש לספק אותם יחד עם הפקודה רוץ כפי שמופיע.

(gdb) run   . . .

ניתן לראות את קבצי הספריה המשותפים שקשורים לתוכנית הרצה כעת.

(gdb) info share 
From                To                  Syms Read   Shared Object Library 
0x00000035a6000b10  0x00000035a6019c70  Yes         /lib64/ld-linux-x86-64.so.2 
0x00000035a641f560  0x00000035a6560bb4  Yes         /lib64/libc.so.6

שינוי משתנים

GDB מסוגל גם לשנות משתנים במהלך הרצת התוכנית. בואו ננסה זאת. כפי שציינו למעלה, הגדר נקודת עצירה בשורה 16 והרץ את התוכנית.

(gdb) r 
Starting program: /root/sum 

Enter the first number: 1 
Enter the second number: 2 

Breakpoint 1, main ( ) at sum.c:16 
16		printf("The sum is %d\n\n", z); 
(gdb) set z=4 
(gdb) c 
Continuing. 
The sum is 4

עכשיו a = 1, b = 2 והתוצאה צריכה להיות z = 3. אך כאן שינינו את התוצאה הסופית ל z = 4 במרכז הפונקציה. באמצעות כך אפשר לאפשר תיקונים באמצעות gdb.

הפעל/נטרל נקודות עצירה

כדי לקבל את רשימת כל נקודות העצירה, יש להקליד מידע על נקודות העצירה.

(gdb) info breakpoints 
Num     Type           Disp Enb Address            What 
1       breakpoint     keep y   0x00000000004005c2 in main at sum.c:11

כאן יש רק נקודת עצירה אחת וזו To. כדי להפעיל או להשבית נקודות העצירה יש לציין את מספר הנקודה יחד עם הפקודה נטרל. כדי להפעיל מאוחר יותר, יש להשתמש בפקודה הפעל.

(gdb) disable 1 
(gdb) info breakpoints 
Num     Type           Disp Enb Address            What 
1       breakpoint     keep n   0x00000000004005c2 in main at sum.c:11

אתה יכול גם למחוק את הנקודות שביוסוף המחיקה עם פקודת delete‏.

פיתוח תהליכים בריצה

ייתכן שתהליכים רבים מריצים ברקע במערכת GNU/Linux. על מנת לפתח תהליך בריצה ראשית עלינו למצוא את מזהה התהליך של התהליך הספציפי הזה. pidof הפקודה נותנת לך את מזהה התהליך.

$ pidof <process_name>

כעת עלינו לקשור את מזהה התהליך הזה ל-gdb. ישנן 2 דרכים.

1. על ידי ציון מזהה התהליך יחד עם gdb.

$ gdb -p <pid>

2. באמצעות הפקודה attach מ-gdb.

(gdb) attach <pid>

זו כל התוכן עד כאן. אלו רק היסודות של gdb כדי להתחיל בצורה טובה בפיתוח קוד מקור וזה הרבה יותר מהדברים שנסבירו למעלה. לדוגמה, נוכל לפתח באמצעות המידע שבתוך ה-stack, משתנים סביבתיים ועוד הרבה. נסה לשחק עם כל הרכיבים אלה…‏

Source:
https://www.tecmint.com/debug-source-code-in-linux-using-gdb/