GNU Debugger ຫຼື GDB: ເຄື່ອງມືແກ້ໄຂລະຫັດແຫຼ່ງທີ່ມີປະສິດທິພາບ ສຳ ລັບ Linux Program


debugger ມີບົດບາດ ສຳ ຄັນໃນລະບົບພັດທະນາ software. ບໍ່ມີໃຜສາມາດຂຽນລະຫັດທີ່ບໍ່ມີຂໍ້ບົກພ່ອງໄດ້ໃນເວລາດຽວກັນ. ໃນໄລຍະການພັດທະນາ, ແມງໄມ້ ກຳ ລັງຖືກຍົກຂຶ້ນມາແລະ ຈຳ ເປັນຕ້ອງໄດ້ຮັບການແກ້ໄຂເພື່ອໃຫ້ມີການປັບປຸງເພີ່ມເຕີມ. ລະບົບການພັດທະນາແມ່ນບໍ່ຄົບຖ້ວນໂດຍບໍ່ມີເຄື່ອງແກ້ຕົວ. ພິຈາລະນາຊຸມຊົນນັກພັດທະນາແຫຼ່ງເປີດ, GNU Debugger ແມ່ນທາງເລືອກທີ່ດີທີ່ສຸດຂອງພວກເຂົາ. ມັນຍັງຖືກ ນຳ ໃຊ້ເພື່ອພັດທະນາຊອບແວການຄ້າໃນເວທີປະເພດ UNIX.

GNU Debugger, ເຊິ່ງເອີ້ນກັນວ່າ gdb, ຊ່ວຍໃຫ້ພວກເຮົາແຊກແຊງລະຫັດໃນຂະນະທີ່ມັນ ດຳ ເນີນການຫຼືສິ່ງທີ່ໂປແກຼມໃດ ໜຶ່ງ ພະຍາຍາມເຮັດໃນເວລານີ້ກ່ອນທີ່ມັນຈະລົ້ມລົງ. ໂດຍພື້ນຖານແລ້ວ GDB ຊ່ວຍໃຫ້ພວກເຮົາເຮັດ 4 ສິ່ງທີ່ ສຳ ຄັນເພື່ອຈັບຂໍ້ບົກພ່ອງໃນລະຫັດແຫຼ່ງ.

<

  • ເລີ່ມຕົ້ນໂຄງການ, ການລະບຸການໂຕ້ຖຽງທີ່ອາດຈະສົ່ງຜົນກະທົບຕໍ່ພຶດຕິ ກຳ ທົ່ວໄປ.
  • ຢຸດເຊົາໂຄງການຕາມເງື່ອນໄຂທີ່ລະບຸໄວ້.
  • ກວດເບິ່ງອຸປະຕິເຫດຫຼືເມື່ອໂປຣແກຣມຖືກຢຸດ.
  • ປ່ຽນລະຫັດແລະທົດລອງກັບລະຫັດທີ່ຖືກແກ້ໄຂທັນທີ.
  • ພວກເຮົາສາມາດໃຊ້ gdb ເພື່ອແກ້ໄຂບັນດາໂປແກຼມທີ່ຂຽນໄວ້ໃນ C ແລະ C ++ ໂດຍບໍ່ມີຄວາມພະຍາຍາມຫຼາຍ. ໃນປັດຈຸບັນສະຫນັບສະຫນູນພາສາການຂຽນໂປຼແກຼມອື່ນໆເຊັ່ນ D, Modula-2, Fortran ແມ່ນບາງສ່ວນ.

    ເລີ່ມຕົ້ນດ້ວຍ GNU Debugger ຫຼື GDB

    GDB ຖືກຮຽກຮ້ອງໂດຍໃຊ້ ຄຳ ສັ່ງ gdb . ກ່ຽວກັບການອອກ gdb , ມັນສະແດງຂໍ້ມູນບາງຢ່າງກ່ຽວກັບເວທີແລະລົງໃຫ້ທ່ານເຂົ້າໄປໃນ ( gdb ) ວ່ອງໄວດັ່ງທີ່ສະແດງຢູ່ຂ້າງລຸ່ມ.

     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. ພິມ ຄວາມຊ່ວຍເຫຼືອ ຕາມດ້ວຍຊື່ຫ້ອງຮຽນ ສຳ ລັບລາຍຊື່ ຄຳ ສັ່ງໃນຊັ້ນນັ້ນ. ພິມ ຊ່ວຍເຫຼືອທັງ ໝົດ ສຳ ລັບລາຍຊື່ ຄຳ ສັ່ງທັງ ໝົດ. ຊື່ຫຍໍ້ຂອງ ຄຳ ສັ່ງແມ່ນຖືກອະນຸຍາດຖ້າມັນບໍ່ຖືກຕ້ອງ. ຍົກຕົວຢ່າງ, ທ່ານສາມາດພິມ n ແທນທີ່ຈະພິມ ຕໍ່ໄປ ຫຼື c ສຳ ລັບ ສືບຕໍ່ ແລະອື່ນໆ.

    ຄຳ ສັ່ງ gdb ທີ່ໃຊ້ກັນທົ່ວໄປແມ່ນຖືກລະບຸຢູ່ໃນຕາຕະລາງຕໍ່ໄປນີ້. ຄຳ ສັ່ງເຫລົ່ານີ້ແມ່ນໃຊ້ຈາກ ຄຳ ສັ່ງ gdb ( 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

    ເອກະສານຜົນຜະລິດ ຜົນລວມ ສາມາດຕິດກັບ 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 . ມັນເປັນສິ່ງສໍາຄັນທີ່ຈະສັງເກດວ່າ ຖັດໄປ ຄໍາສັ່ງບໍ່ໄດ້ເຂົ້າໄປພາຍໃນລະຫັດຫນ້າທີ່ເວັ້ນເສຍແຕ່ວ່າຈຸດທີ່ຕັ້ງຢູ່ໃນຫນ້າທີ່ກໍານົດ. ລອງໃຊ້ ຄຳ ສັ່ງ ພິມ ດຽວນີ້. ກຳ ນົດຈຸດພັກຜ່ອນກ່ຽວກັບຜົນບວກຂອງ ໜ້າ ທີ່ດັ່ງລຸ່ມນີ້.

    (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

    ໃນທີ່ນີ້ມີພຽງແຕ່ຈຸດພັກຜ່ອນແລະມັນແມ່ນເພື່ອ. ເຮັດໃຫ້ການປິດການ ທຳ ງານຈຸດແຍກໄດ້ລະບຸ ຈຳ ນວນຈຸດແຍກພ້ອມກັບ ຄຳ ສັ່ງ ປິດ . ເພື່ອເປີດໃຊ້ພາຍຫລັງໃຊ້ ຄຳ ສັ່ງ ສາມາດ .

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

    ທ່ານຍັງສາມາດລຶບຈຸດແບ່ງອອກດ້ວຍ ຄຳ ສັ່ງ ລຶບ .

    ມີຫຼາຍຂະບວນການທີ່ ກຳ ລັງເຮັດວຽກຢູ່ໃນພື້ນຫລັງໃນລະບົບ GNU/Linux. ເພື່ອແກ້ໄຂຂັ້ນຕອນການເຮັດວຽກກ່ອນອື່ນ ໝົດ ພວກເຮົາຕ້ອງຊອກຫາ id process ຂອງຂະບວນການສະເພາະນັ້ນ. ຄຳ ສັ່ງ pidof ໃຫ້ທ່ານ pid ຂອງຂັ້ນຕອນໃດ ໜຶ່ງ.

    $ pidof <process_name>

    ຕອນນີ້ພວກເຮົາ ຈຳ ເປັນຕ້ອງຕິດ pid ນີ້ໃສ່ gdb. ມີ 2 ວິທີ.

    1. ໂດຍການ ກຳ ນົດ pid ພ້ອມກັບ gdb.

    $ gdb -p <pid>

    2. ການໃຊ້ ຄຳ ສັ່ງ ແນບ ຈາກ gdb.

    (gdb) attach <pid>

    ດຽວນີ້ ໝົດ ແລ້ວ. ເຫຼົ່ານີ້ແມ່ນພຽງແຕ່ພື້ນຖານຂອງ gdb ເທົ່ານັ້ນທີ່ຈະເລີ່ມຕົ້ນທີ່ດີໃນລະຫັດແຫຼ່ງຂໍ້ມູນ debugging ແລະມັນມີຫຼາຍກວ່າສິ່ງທີ່ໄດ້ອະທິບາຍຂ້າງເທິງ ຕົວຢ່າງ, ພວກເຮົາສາມາດ debug ໂດຍໃຊ້ຂໍ້ມູນ stack, ຕົວແປສະພາບແວດລ້ອມແລະອື່ນໆ. ພະຍາຍາມທີ່ຈະຫລິ້ນຮອບກັບສິ່ງເຫຼົ່ານີ້ທັງ ໝົດ …