GNU Debugger أو GDB: أداة قوية لتصحيح أخطاء الشفرة المصدرية لبرامج لينكس

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

منغول ديباججر، المعروف أيضا بـ غدب، يسمح لنا بالتسلل خلال الشيفرة أثناء تنفيذها أو معرفة ما حاول البرنامج القيام به في اللحظة الأخيرة قبل الانهيار. بشكل أساسي، يساعدنا GDB في القيام بأربعة أشياء رئيسية لاكتشاف العيوب في شفرة المصدر.

  1. بدء تشغيل البرنامج، محدداً الوسائط التي قد تؤثر على السلوك العام.
  2. توقف البرنامج في حالات محددة.
  3. فحص الانهيار أو عند توقف البرنامج.
  4. تغيير الشفرة وتجربة الشفرة المعدلة على الفور.

يمكننا استخدام gdb لتصحيح الأخطاء في البرامج المكتوبة بلغات سي وسي بلس بلس بدون جهد كبير. حتى الآن، الدعم للغات البرمجة الأخرى مثل دي، موديولا-2، فورتران غير كامل.

البدء مع GNU Debugger أو GDB

GDB يتم استدعاؤه باستخدام أمر غدب. عند إصدار غدب، يعرض بعض المعلومات حول المنصة ويضعك في سطر الأوامر (غدب) كما هو موضح أدناه.

[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)

اكتب مساعدة list لعرض فئات الأوامر المتاحة داخل gdb. اكتب مساعدة تليها اسم الفئة للحصول على قائمة الأوامر في تلك الفئة. اكتب مساعدة الكل للحصول على قائمة بجميع الأوامر. يُسمح باختصار أسماء الأوامر إذا كانت واضحة. على سبيل المثال، يمكنك كتابة ن بدلا من كتابة التالي أو ج بدلا من تواصل وهكذا.

أكثر الأوامر استخدامًا في GDB

الأوامر المعتادة لـ gdb مُدرجة في الجدول التالي. يجب استخدام هذه الأوامر من سطر الأوامر الخاص بـ 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

لاحظ الفرق بين الأمرين step و next. الأمر next لا يدخل داخل الدالة إذا كانت السطر التالي داخل استدعاء دالة. بينما يمكن للأمر step الدخول داخل الدالة ومشاهدة ما يحدث هناك.

A sample session with GDB

Consافترض الشيفرة المصدرية التالية.

// 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 باستخدام الأمر file.

$ gdb
(gdb) file sum

يقوم الأمر list بقائمة الأسطر في ملف الشيفرة المصدرية وينقل المؤشر. فسيقوم list أول 10 أسطر بالعرض وسيقوم list بعرض الـ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;

لبدء التنفيذ، قم بإصدار الأمر run . الآن يتم تنفيذ البرنامج بشكل طبيعي. ولكن نحن ننسى أن نقوم بوضع بعض نقاط الوقف في الشيفرة المصدرية للتصحيح، أليس كذلك؟ يمكن تحديد هذه النقاط للدوال أو عن طريق تحديد خطوط محددة.

(gdb) b main

ملاحظة: لقد استخدمت اختصارًا b لـ break.

بعد تعيين نقطة توقف في الدالة الرئيسية، سيتوقف إعادة تشغيل البرنامج عند السطر 11. يمكن تحقيق نفس الأمر إذا كان رقم السطر معروفًا مسبقًا.

(gdb) b sum.c:11

الآن تقدم خطوة بخطوة عبر أسطر الشيفرة باستخدام الأمر التالي أو ن. من المهم أن نلاحظ أن الأمر التالي لا يدخل إلى داخل شيفرة الدالة ما لم يتم تعيين نقطة توقف على الدالة. دعونا نجرب الآن الأمر الطباعة. قم بتعيين نقطة توقف على الدالة 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. هناك طريقتان.

1. عن طريق تحديد معرف العملية مع gdb.

$ gdb -p <pid>

2. باستخدام الأمر attach من gdb.

(gdb) attach <pid>

هذا كل شيء بالنسبة للآن. هذه أساسيات gdb للبدء الجيد في تصحيح الشفرة المصدرية وهو أكثر بكثير مما تم شرحه أعلاه. على سبيل المثال ، يمكننا التصحيح باستخدام معلومات الستاك ، والمتغيرات البيئية وأكثر من ذلك بكثير. حاول أن تستمتع بالتعامل مع كل هذه الأشياء…

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