自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

用gdb分析core文件及常見gdb命令操作示例

開發(fā) 開發(fā)工具
本文以一個實際的程序為例,介紹了用gdb分析core文件的方法和步驟,同時演示了常見gdb命令的操作方法。

1.概述

在實際的軟件開發(fā)項目中,程序出現(xiàn)問題是在所難免的。遙想本人參加工作之后***遇到程序的情景,至今還歷歷在目。之前的經(jīng)驗告訴我,我們越是驚慌失措,問題就越是解決不了。我們要先讓自己平靜下來,然后再尋找解決程序問題的辦法。

軟件開發(fā)

Linux下做開發(fā)的朋友,想必都與core文件打過交道。當看到自己的程序運行之后出現(xiàn)core時,很多人都慌亂了,仿佛天快要塌下來一樣。其實,我們大可不必如此,只要我們掌握了用gdb調(diào)試core文件的辦法,依然可以很快定位程序問題,一舉將bug消滅掉。有關(guān)Linux core文件的更多介紹,請閱讀此文:http://www.cnblogs.com/dongzhiquan/archive/2012/01/20/2328355.html

本文以一個實際的程序為例,介紹了用gdb分析core文件的方法和步驟,同時演示了常見gdb命令的操作方法。如果大家想對相關(guān)gdb命令有更多的了解,請自行百度之。

2.示例程序

  1. /********************************************************************** 
  2. * 版權(quán)所有 (C)2015, Zhou Zhaoxiong。 
  3. * 文件名稱:GdbDebug.c 
  4. * 文件標識:無 
  5. * 內(nèi)容摘要:Gdb命令演示程序 
  6. * 其它說明:無 
  7. * 當前版本:V1.0 
  8. * 作    者:Zhou Zhaoxiong 
  9. * 完成日期:20151008 
  10. **********************************************************************/ 
  11. #include <stdio.h> 
  12. #include <stdlib.h> 
  13. #include <string.h> 
  14.  
  15. // 數(shù)據(jù)類型重定義 
  16. typedef unsigned char       UINT8; 
  17. typedef signed   int        INT32; 
  18. typedef unsigned int        UINT32; 
  19.  
  20.  
  21. // 函數(shù)聲明 
  22. void Sleep(UINT32 iCountMs); 
  23. void PrintInfo(void); 
  24. INT32 main(); 
  25.  
  26.  
  27. /********************************************************************** 
  28. * 功能描述:主函數(shù) 
  29. * 輸入?yún)?shù):無 
  30. * 輸出參數(shù):無 
  31. * 返 回 值:無 
  32. * 其它說明:無 
  33. * 修改日期        版本號     修改人            修改內(nèi)容 
  34. * ------------------------------------------------------------------- 
  35. * 20151008       V1.0     Zhou Zhaoxiong      創(chuàng)建 
  36. ***********************************************************************/ 
  37. INT32 main() 
  38.     PrintInfo();   // 在屏幕上輸出消息 
  39.  
  40.     return 0; 
  41.  
  42.  
  43. /********************************************************************** 
  44.  * 功能描述: 在屏幕上輸出消息 
  45.  * 輸入?yún)?shù): 無 
  46.  * 輸出參數(shù): 無 
  47.  * 返 回 值: 無 
  48.  * 其它說明: 無 
  49.  * 修改日期            版本號            修改人           修改內(nèi)容 
  50.  * ---------------------------------------------------------------------- 
  51.  * 20151008            V1.0        Zhou Zhaoxiong        創(chuàng)建 
  52.  ************************************************************************/ 
  53. void PrintInfo(void) 
  54.     UINT32 iLoopFlag = 0
  55.     UINT32 iSum      = 0
  56.     UINT32 iLen      = 0
  57.     UINT8 *pCtrStr   = NULL
  58.  
  59.     iLen = strlen(pCtrStr); 
  60.  
  61.     for (iLoopFlag = 0; iLoopFlag < iLen; iLoopFlag ++)      // 打印消息iLen次 
  62.     { 
  63.         printf("PrintInfo: hello, world!\n"); 
  64.  
  65.         iSumiSum = iSum + iLoopFlag; 
  66.  
  67.         Sleep(10 * 1000);   // 每10s打印一次 
  68.     } 
  69.  
  70.     return; 
  71.  
  72.  
  73. /********************************************************************** 
  74. * 功能描述: 程序休眠 
  75. * 輸入?yún)?shù): iCountMs-休眠時間(單位:ms) 
  76. * 輸出參數(shù): 無 
  77. * 返 回 值: 無 
  78. * 其它說明: 無 
  79. * 修改日期          版本號       修改人              修改內(nèi)容 
  80. * ------------------------------------------------------------------ 
  81. * 20151008         V1.0     Zhou Zhaoxiong          創(chuàng)建 
  82. ********************************************************************/ 
  83. void Sleep(UINT32 iCountMs) 
  84.     struct timeval t_timeout = {0}; 
  85.  
  86.     if (iCountMs < 1000
  87.     { 
  88.         t_timeout.tv_sec = 0
  89.         t_timeout.tv_usec = iCountMs * 1000; 
  90.     } 
  91.     else 
  92.     { 
  93.         t_timeout.tv_sec = iCountMs / 1000; 
  94.         t_timeout.tv_usec = (iCountMs % 1000) * 1000; 
  95.     } 
  96.     select(0, NULL, NULL, NULL, &t_timeout);   // 調(diào)用select函數(shù)阻塞程序 

3.用gdb分析core文件

在Linux上用“gcc -g -o GdbDebug GdbDebug.c”命令對程序進行編譯之后,運行“GdbDebug”命令,發(fā)現(xiàn)在當前目錄下出現(xiàn)了core文件。利用gdb命令對core文件進行分析的過程如下所示:

  1. ~/zhouzhaoxiong/zzx/GdbDebug> gdb GdbDebug core     -- 啟動gdb對core文件的分析 
  2. GNU gdb (GDB) SUSE (7.3-0.6.1) 
  3. Copyright (C) 2011 Free Software Foundation, Inc. 
  4. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> 
  5. This is free software: you are free to change and redistribute it. 
  6. There is NO WARRANTY, to the extent permitted by law.  Type "show copying" 
  7. and "show warranty" for details. 
  8. This GDB was configured as "x86_64-suse-linux". 
  9. For bug reporting instructions, please see: 
  10. <http://www.gnu.org/software/gdb/bugs/>... 
  11. Reading symbols from /home/zhou/zhouzhaoxiong/zzx/GdbDebug/GdbDebug...done. 
  12. Core was generated by `GdbDebug'. 
  13. Program terminated with signal 11, Segmentation fault. 
  14. #0  0x00007f4a736f9812 in __strlen_sse2 () from /lib64/libc.so.6 
  15. (gdb) where          -- 查看程序出問題的地方 
  16. #0  0x00007f4a736f9812 in __strlen_sse2 () from /lib64/libc.so.6 
  17. #1  0x000000000040061a in PrintInfo () at GdbDebug.c:64   -- 可以看到,在GdbDebug.c文件的第64行出的問題 
  18. #2  0x00000000004005e5 in main () at GdbDebug.c:41 
  19. (gdb) b 41           -- 在GdbDebug.c文件第41行設立斷點 
  20. Breakpoint 1 at 0x4005e0: file GdbDebug.c, line 41. 
  21. (gdb) b 64           -- 在GdbDebug.c文件第64行設立斷點 
  22. Breakpoint 2 at 0x400611: file GdbDebug.c, line 64. 
  23. (gdb) info b         -- 顯示斷點信息 
  24. Num     Type           Disp Enb Address            What 
  25. 1       breakpoint     keep y   0x00000000004005e0 in main at GdbDebug.c:41 
  26. 2       breakpoint     keep y   0x0000000000400611 in PrintInfo at GdbDebug.c:64 
  27. (gdb) r              -- 運行GdbDebug 
  28. Starting program: /home/zhou/zhouzhaoxiong/zzx/GdbDebug/GdbDebug  
  29.  
  30. Breakpoint 1, main () at GdbDebug.c:41 
  31. 41          PrintInfo();   // 在屏幕上輸出消息 
  32. (gdb) n             -- 執(zhí)行下一步 
  33.  
  34. Breakpoint 2, PrintInfo () at GdbDebug.c:64 
  35. 64              iLen = strlen(pCtrStr); 
  36. (gdb) p iLen        -- 打印(輸出)iLen的值 
  37. $1 = 0 
  38. (gdb) p iLoopFlag   -- 打印(輸出)iLoopFlag的值 
  39. $2 = 0 
  40. (gdb) c             -- 繼續(xù)執(zhí)行      
  41. Continuing. 
  42.  
  43. Program received signal SIGSEGV, Segmentation fault.    -- 程序core掉了 
  44. 0x00007ffff7ae9812 in __strlen_sse2 () from /lib64/libc.so.6 
  45. (gdb) q             -- 退出gdb 
  46. A debugging session is active. 
  47.  
  48.         Inferior 1 [process 26640] will be killed. 
  49.  
  50. Quit anyway? (y or n) y 
  51. ~/zhouzhaoxiong/zzx/GdbDebug> 

從以上分析可知,執(zhí)行GdbDebug.c文件的第64行時程序core掉了。此時仔細分析程序,發(fā)現(xiàn)pCtrStr指針為空。當對一個不存在的指針取長度時,由于找不到地址,程序便崩潰了。修改的辦法也非常的簡單,只需要讓pCtrStr指針指向具體的地址即可。

4.常見gdb命令操作示例

修改之后的代碼如下:

  1. /********************************************************************** 
  2. * 版權(quán)所有 (C)2015, Zhou Zhaoxiong。 
  3. * 文件名稱:GdbDebug.c 
  4. * 文件標識:無 
  5. * 內(nèi)容摘要:Gdb命令演示程序 
  6. * 其它說明:無 
  7. * 當前版本:V1.0 
  8. * 作    者:Zhou Zhaoxiong 
  9. * 完成日期:20151008 
  10. **********************************************************************/ 
  11. #include <stdio.h> 
  12. #include <stdlib.h> 
  13. #include <string.h> 
  14.  
  15. // 數(shù)據(jù)類型重定義 
  16. typedef unsigned char       UINT8; 
  17. typedef signed   int        INT32; 
  18. typedef unsigned int        UINT32; 
  19.  
  20.  
  21. // 函數(shù)聲明 
  22. void Sleep(UINT32 iCountMs); 
  23. void PrintInfo(void); 
  24. INT32 main(); 
  25.  
  26.  
  27. /********************************************************************** 
  28. * 功能描述:主函數(shù) 
  29. * 輸入?yún)?shù):無 
  30. * 輸出參數(shù):無 
  31. * 返 回 值:無 
  32. * 其它說明:無 
  33. * 修改日期        版本號     修改人            修改內(nèi)容 
  34. * ------------------------------------------------------------------- 
  35. * 20151008       V1.0    Zhou Zhaoxiong       創(chuàng)建 
  36. ***********************************************************************/ 
  37. INT32 main() 
  38.     PrintInfo();   // 在屏幕上輸出消息 
  39.  
  40.     return 0; 
  41.  
  42.  
  43. /********************************************************************** 
  44.  * 功能描述: 在屏幕上輸出消息 
  45.  * 輸入?yún)?shù): 無 
  46.  * 輸出參數(shù): 無 
  47.  * 返 回 值: 無 
  48.  * 其它說明: 無 
  49.  * 修改日期            版本號            修改人           修改內(nèi)容 
  50.  * ---------------------------------------------------------------------- 
  51.  * 20151008           V1.0         Zhou Zhaoxiong        創(chuàng)建 
  52.  ************************************************************************/ 
  53. void PrintInfo(void) 
  54.     UINT32 iLoopFlag = 0
  55.     UINT32 iSum      = 0
  56.     UINT32 iLen      = 0
  57.     UINT8 *pCtrStr   = "hello, world!";  // 修改了這行代碼 
  58.  
  59.     iLen = strlen(pCtrStr); 
  60.  
  61.     for (iLoopFlag = 0; iLoopFlag < iLen; iLoopFlag ++)      // 打印消息iLen次 
  62.     { 
  63.         printf("PrintInfo: hello, world!\n"); 
  64.  
  65.         iSumiSum = iSum + iLoopFlag; 
  66.  
  67.         Sleep(10 * 1000);   // 每10s打印一次 
  68.     } 
  69.  
  70.     return; 
  71.  
  72.  
  73. /********************************************************************** 
  74. * 功能描述: 程序休眠 
  75. * 輸入?yún)?shù): iCountMs-休眠時間(單位:ms) 
  76. * 輸出參數(shù): 無 
  77. * 返 回 值: 無 
  78. * 其它說明: 無 
  79. * 修改日期          版本號       修改人              修改內(nèi)容 
  80. * ------------------------------------------------------------------ 
  81. * 20151008         V1.0     Zhou Zhaoxiong          創(chuàng)建 
  82. ********************************************************************/ 
  83. void Sleep(UINT32 iCountMs) 
  84.     struct timeval t_timeout = {0}; 
  85.  
  86.     if (iCountMs < 1000
  87.     { 
  88.         t_timeout.tv_sec = 0
  89.         t_timeout.tv_usec = iCountMs * 1000; 
  90.     } 
  91.     else 
  92.     { 
  93.         t_timeout.tv_sec = iCountMs / 1000; 
  94.         t_timeout.tv_usec = (iCountMs % 1000) * 1000; 
  95.     } 
  96.     select(0, NULL, NULL, NULL, &t_timeout);   // 調(diào)用select函數(shù)阻塞程序 

編譯并運行之后,程序正常,說明問題已被我們解決掉。下面是常見的gdb命令的操作示例:

  1. ~/zhouzhaoxiong/zzx/GdbDebug> gdb GdbDebug    -- 啟動gdb調(diào)試 
  2. GNU gdb (GDB) SUSE (7.3-0.6.1) 
  3. Copyright (C) 2011 Free Software Foundation, Inc. 
  4. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> 
  5. This is free software: you are free to change and redistribute it. 
  6. There is NO WARRANTY, to the extent permitted by law.  Type "show copying" 
  7. and "show warranty" for details. 
  8. This GDB was configured as "x86_64-suse-linux". 
  9. For bug reporting instructions, please see: 
  10. <http://www.gnu.org/software/gdb/bugs/>... 
  11. Reading symbols from /home/zhou/zhouzhaoxiong/zzx/GdbDebug/GdbDebug...done. 
  12. (gdb) b 64     -- 在GdbDebug.c文件第64行設立斷點 
  13. Breakpoint 1 at 0x400611: file GdbDebug.c, line 64. 
  14. (gdb) b 72     -- 在GdbDebug.c文件第72行設立斷點 
  15. Breakpoint 2 at 0x400637: file GdbDebug.c, line 72. 
  16. (gdb) info b   -- 顯示斷點信息 
  17. Num     Type           Disp Enb Address            What 
  18. 1       breakpoint     keep y   0x0000000000400611 in PrintInfo at GdbDebug.c:64 
  19. 2       breakpoint     keep y   0x0000000000400637 in PrintInfo at GdbDebug.c:72 
  20. (gdb) r        -- 運行GdbDebug 
  21. Starting program: /home/zhou/zhouzhaoxiong/zzx/GdbDebug/GdbDebug  
  22.  
  23. Breakpoint 1, PrintInfo () at GdbDebug.c:64 
  24. 64              iLen = strlen(pCtrStr); 
  25. (gdb) p iLen    -- 打印(輸出)iLen的值 
  26. $1 = 0 
  27. (gdb) n         -- 執(zhí)行下一步 
  28. 66              for (iLoopFlag = 0; iLoopFlag < iLen; iLoopFlag ++)      // 打印消息iLen次 
  29. (gdb) n         -- 執(zhí)行下一步 
  30. 68              printf("PrintInfo: hello, world!\n"); 
  31. (gdb) p iLoopFlag   -- 打印(輸出)iLoopFlag的值 
  32. $2 = 0 
  33. (gdb) p iLen    -- 打印(輸出)iLen的值 
  34. $3 = 13 
  35. (gdb) n         -- 執(zhí)行下一步 
  36. PrintInfo: hello, world!    -- 程序的輸出結(jié)果 
  37. 70                      iSumiSum = iSum + iLoopFlag; 
  38. (gdb) p iSum    -- 打印(輸出)iSum的值 
  39. $4 = 0 
  40. (gdb) n        -- 執(zhí)行下一步 
  41.  
  42. Breakpoint 2, PrintInfo () at GdbDebug.c:72 
  43. 72                      Sleep(10 * 1000);   // 每10s打印一次 
  44. (gdb) n       
  45. 66              for (iLoopFlag = 0; iLoopFlag < iLen; iLoopFlag ++)      // 打印消息iLen次 
  46. (gdb) p iLoopFlag 
  47. $5 = 0 
  48. (gdb) n 
  49. 68              printf("PrintInfo: hello, world!\n"); 
  50. (gdb) p iLoopFlag 
  51. $6 = 1 
  52. (gdb) n 
  53. PrintInfo: hello, world! 
  54. 70                      iSumiSum = iSum + iLoopFlag; 
  55. (gdb) p iSum 
  56. $7 = 0 
  57. (gdb) n 
  58.  
  59. Breakpoint 2, PrintInfo () at GdbDebug.c:72 
  60. 72                      Sleep(10 * 1000);   // 每10s打印一次 
  61. (gdb) p iSum 
  62. $8 = 1 
  63. (gdb) finish        -- 一直運行到函數(shù)返回 
  64. Run till exit from #0  PrintInfo () at GdbDebug.c:72 
  65. PrintInfo: hello, world! 
  66.  
  67. Breakpoint 2, PrintInfo () at GdbDebug.c:72 
  68. 72                      Sleep(10 * 1000);   // 每10s打印一次 
  69. (gdb) c           -- 繼續(xù)執(zhí)行  
  70. Continuing. 
  71. PrintInfo: hello, world! 
  72.  
  73. Breakpoint 2, PrintInfo () at GdbDebug.c:72 
  74. 72                      Sleep(10 * 1000);   // 每10s打印一次 
  75. (gdb) bt            -- 打印當前的函數(shù)調(diào)用棧的所有信息 
  76. #0  PrintInfo () at GdbDebug.c:72 
  77. #1  0x00000000004005e5 in main () at GdbDebug.c:41 
  78. (gdb) q              -- 退出gdb 
  79. A debugging session is active. 
  80.  
  81.         Inferior 1 [process 26685] will be killed. 
  82.  
  83. Quit anyway? (y or n) y 
  84. ~/zhouzhaoxiong/zzx/GdbDebug>  

作為Linux下調(diào)試C/C++程序的工具,大家一定要熟練掌握gdb的用法。

【本文是51CTO專欄作者周兆熊的原創(chuàng)文章,作者微信公眾號:周氏邏輯(logiczhou)】

戳這里,看該作者更多好文

責任編輯:趙寧寧 來源: 51CTO專欄
相關(guān)推薦

2017-05-10 15:30:30

skynet崩潰程序

2015-10-09 16:42:16

GDB 排查Python程序故障

2010-06-04 17:48:20

Linux編程工具

2022-12-19 10:10:07

GDB命令

2009-07-27 08:50:29

2021-03-15 06:23:40

GDB調(diào)試代碼編程語言

2015-08-14 09:21:09

gdb工具調(diào)試 Go

2021-07-05 11:00:43

GDB棧空間編程語言

2021-07-28 08:53:53

GoGDB調(diào)試

2011-07-22 17:05:56

IOS 控制臺 GDB

2023-05-04 12:39:27

GDB命令程序

2025-03-31 03:25:00

2022-09-15 14:56:12

GDB調(diào)試鴻蒙

2009-12-18 16:08:17

Fedora proc

2024-09-13 17:06:54

EF Core分組查詢

2016-03-29 10:32:34

2010-01-20 10:39:52

Linuxcore

2012-05-21 10:13:05

XCode調(diào)試技巧

2017-02-06 18:42:37

Linuxgdb程序

2018-04-16 10:12:46

Linux命令gunzip
點贊
收藏

51CTO技術(shù)棧公眾號