本文來自網易雲社區。html
做者:盛國存linux
問: gdb是什麼? 答: 強大的UNIX下命令行調試工具。 問: gdb能幹什麼? 答: 讓你爲所欲爲的駕馭你的程序;Start、Stop、Examine、Change。 問: 咱們爲何要學習gdb? 答: 欲善其事,必先利其器;利用gdb進一步的定位程序異常。 問: 本次分享的宗旨? 答: gdb的介紹和使用入門,爲你們抓蟲多提供一個選擇。
1.包含有調試信息的可執行文件ios
2.編譯時加-g選項便可,不建議開優化選項c++
gdb <program>gdb <program> coregdb <program> <PID> (gdb) file <program>
1.一、示例程序(example_1.cpp)算法
#include <iostream>#include <string>using namespace std;int foo(int m, int n){ return 1; }int foo(int n){ int result=0; for (int i=0;i<=n;i++) { result+=n; } return result; }int main(){ string s1="dafdf"; char * s2;// s1=s2; int sum =0; for (int i=1;i<=100;i++) { sum+=i; } cout<<"result[1-100]="<<sum<<endl; cout<<"result[1-250]="<<foo(250)<<endl; return 0; }
1.二、調試準備 編譯命令:g++ -g -Wall -o example_1 example_1.cppshell
1.三、啓動gdb多線程
$ gdb example_1 GNU gdb Red Hat Linux (6.3.0.0-1.96rh) Copyright 2004 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "x86_64-redhat-linux-gnu"...Using host libthread_db library "/lib64/tls/libthread_db.so.1".
1.四、輔助性命令架構
(gdb) cd .. Working directory /home/work/testers/sgc. (gdb) shell ls autotest client Makefile spanti spantispam_if.h study(gdb) cd study/ Working directory /home/work/testers/sgc/study. (gdb) pwd Working directory /home/work/testers/sgc/study. (gdb) help run Start debugged program. You may specify arguments to give it. Args may include "*", or "[...]"; they are expanded using "sh". Input and output redirection with ">", "<", or ">>" are also allowed. With no arguments, uses arguments last specified (with "run" or "set args"). To cancel previous arguments and run with no arguments,use "set args" without arguments.
1.五、設置斷點命令app
//查看源代碼信息(gdb) l17 result+=n;18 }19 return result;2021 }2223 int main()24 {2526 string s1="dafdf"; (gdb) l 11 #include <iostream>2 #include <string>345 using namespace std;6 int foo(int m, int n)7 {89 return 1;10(gdb) l example_1.cpp:1611 }12 int foo(int n)13 {14 int result=0;15 for (int i=0;i<=n;i++)16 {17 result+=n;18 }19 return result;20(gdb) l foo(int)8 9 return 1;1011 }12 int foo(int n)13 {14 int result=0;15 for (int i=0;i<=n;i++)16 {17 result+=n;
//設置斷點(gdb) b 17Breakpoint 1 at 0x400c07: file example_1.cpp, line 17.(gdb) b main Breakpoint 2 at 0x400c27: file example_1.cpp, line 26.(gdb) info br Num Type Disp Enb Address What1 breakpoint keep y 0x0000000000400c07 in foo(int) at example_1.cpp:17 2 breakpoint keep y 0x0000000000400c27 in main at example_1.cpp:26
1.六、執行控制命令分佈式
(gdb) r Starting program: /home/work/testers/sgc/study/example_1 Breakpoint 2, main () at example_1.cpp:2626 string s1="dafdf"; (gdb) c Continuing. result[1-100]=5050Breakpoint 1, foo (n=250) at example_1.cpp:1717 result+=n; (gdb) n 15 for (int i=0;i<=n;i++)
1.七、程序信息查看命令
//查看變量信息 (gdb) p result$1 = 250(gdb) p s1$2 = 1431655765 (gdb) disp result1: result = 250(gdb) c Continuing. Breakpoint 1, foo (n=250) at example_1.cpp:1717 result+=n;1: result = 250(gdb) info locals i = 1result = 250//查看棧信息 (gdb) bt#0 foo (n=250) at example_1.cpp:17#1 0x0000000000400cc1 in main () at example_1.cpp:38(gdb) info f Stack level 0, frame at 0x7fbffff8a0: rip = 0x400c07 in foo(int) (example_1.cpp:17); saved rip 0x400cc1 called by frame at 0x7fbffff910 source language c++. Arglist at 0x7fbffff890, args: n=250 Locals at 0x7fbffff890, Previous frame's sp is 0x7fbffff8a0 Saved registers: rbp at 0x7fbffff890, rip at 0x7fbffff898 (gdb) f 0 #0 foo (n=250) at example_1.cpp:17 17 result+=n;
1.八、修改環境命令
(gdb) set var i=97(gdb) p i $5 = 97(gdb) print i=98$6 = 98(gdb) ignore 1 300Will ignore next 300 crossings of breakpoint 1.(gdb) finish Run till exit from #0 foo (n=250) at example_1.cpp:170x0000000000400cc1 in main () at example_1.cpp:3838 cout<<"result[1-250]="<<foo(250)<<endl;Value returned is $8 = 38500 (gdb) quit The program is running. Exit anyway? (y or n) y
問 :Core文件是什麼?
答 :a disk file containing an image of the process's memory at the time of termination問 :Core的做用?
答 :
一、讓你在調試時,不用花費大量等待程序出錯;
二、讓你避免了單步調試的煩惱
三、讓你定位錯誤所在
$ gdb <program> core
一、查看棧信息:bt, f n, up/down,info frame
二、查看變量信息:info args|locals
2.一、示例程序(crash2.c)
#include <string.h>void Strcpy(char *to , char *from){ strcpy(to , from); }int main(){ char *s = NULL; Strcpy(s, "abcdefg"); return 0; }
2.二、查看信息
$ gdb ./crash2 core.19562 GNU gdb Red Hat Linux (6.3.0.0-1.96rh)Copyright 2004 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "x86_64-redhat-linux-gnu"...Using host libthread_db library "/lib64/tls/libthread_db.so.1". Core was generated by `./crash2'. Program terminated with signal 11, Segmentation fault. Reading symbols from /lib64/tls/libc.so.6...done. Loaded symbols for /lib64/tls/libc.so.6 Reading symbols from /lib64/ld-linux-x86-64.so.2...done. Loaded symbols for /lib64/ld-linux-x86-64.so.2 #0 0x000000302af6f9a4 in strcpy () from /lib64/tls/libc.so.6(gdb) bt #0 0x000000302af6f9a4 in strcpy () from /lib64/tls/libc.so.6 #1 0x00000000004004c5 in Strcpy (to=0x0, from=0x4005dc "abcdefg") at crash2.c:5 #2 0x00000000004004e5 in main () at crash2.c:10(gdb) f 0 #0 0x000000302af6f9a4 in strcpy () from /lib64/tls/libc.so.6(gdb) up #1 0x00000000004004c5 in Strcpy (to=0x0, from=0x4005dc "abcdefg") at crash2.c:5 5 strcpy(to , from); (gdb) info args to = 0x0from = 0x4005dc "abcdefg"//至此,已經清楚的發現了問題所在,to指針爲空
$ info <...> // 強大的查看命令,如info threads $ attach/detach <pid> // 掛載到進程 $ thread <thread_no> // 切換到線程 $ thread apply <thread_no_list> <cmd> // 對於list中的thread,執行cmd $ break <linenum> thread <threadno> if ...
3.一、正常的示例程序(good_thread.c)
#include <pthread.h>#include <stdio.h>#include <sys/time.h>#include <string.h>#define MAX 10pthread_t thread[2]; pthread_mutex_t mut;int number=0, i;void *thread1() { printf ("thread1 : I'm thread 1\n"); for (i = 0; i < MAX; i++) { printf("thread1 : number = %d\n",number); pthread_mutex_lock(&mut); number++; pthread_mutex_unlock(&mut); sleep(2); } printf("thread1 :主函數在等我完成任務嗎?\n"); pthread_exit(NULL); }void *thread2() { printf("thread2 : I'm thread 2\n"); for (i = 0; i < MAX; i++) { printf("thread2 : number = %d\n",number); pthread_mutex_lock(&mut); number++; pthread_mutex_unlock(&mut); sleep(3); } printf("thread2 :主函數在等我完成任務嗎?\n"); pthread_exit(NULL); }void thread_create(void) { int temp; memset(&thread, 0, sizeof(thread)); //comment1 /*建立線程*/ if((temp = pthread_create(&thread[0], NULL, thread1, NULL)) != 0) //comment2 printf("線程1建立失敗!\n"); else printf("線程1被建立\n"); if((temp = pthread_create(&thread[1], NULL, thread2, NULL)) != 0) //comment3 printf("線程2建立失敗"); else printf("線程2被建立\n"); }void thread_wait(void) { /*等待線程結束*/ if(thread[0] !=0) { //comment4 pthread_join(thread[0],NULL); printf("線程1已經結束\n"); } if(thread[1] !=0) { //comment5 pthread_join(thread[1],NULL); printf("線程2已經結束\n"); } }int main() { /*用默認屬性初始化互斥鎖*/ pthread_mutex_init(&mut,NULL); printf("我是主函數哦,我正在建立線程,呵呵\n"); thread_create(); printf("我是主函數哦,我正在等待線程完成任務阿,呵呵\n"); thread_wait(); return 0; }
網易雲免費體驗館,0成本體驗20+款雲產品!
更多網易研發、產品、運營經驗分享請訪問網易雲社區。
相關文章:
【推薦】 最小化局部邊際的合併聚類算法(中篇)
【推薦】 網易美學-系統架構系列1-分佈式與服務化
【推薦】 Android模擬器下載、編譯及調試