《debug hacks》

第二章 調試前的必會知識


4. 獲取內核的進程轉儲

4.1 舉例

  • ulimit -c 1073741824 #設置內核轉儲文件上限
  • 新建測試文件
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
   int *a=NULL;
   *a=0x1;
   return 0;
}
  • 編譯:gcc 14_a.c -g #注意加上-g選項保存調試信息
  • ./a.out #運行,,正常應該報錯
  • file *core :在當前目錄下查看生成的內核轉儲文件
  • gdb -c core ./a.out :用GDB調試生成的內核轉儲文件,出現以下信息
[New LWP 3096]
Core was generated by `./a.out'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x00000000004004e6 in main () at 14_a.c:7 7 *a=0x1; (gdb) q

上述信息指示第7行在訪問a地址的時候出現錯誤編程

4.2 啓用整個系統的內核轉儲功能

  • 修改會添加 /etc/profie:
    ulimit -S -c unlimited > /dev/null 2>&1
    DAEMON_COREFILEFILE='unlimited'
  • 在文件/etc/sysctl.conf中添加:fs.suid_dumpable=1
  • 重啓系統

4.3 利用內核轉儲掩碼排除共享內存

  • 見書本

5. 調試器(GDB)的基本使用方法(之一)

  • gcc -wall -02 -werror -g 源文件
    • -g:保存調試信息
    • -werror:在警告發生時當作錯誤來處理
  • ./a.out ;ls *core #運行並查看內核轉儲文件
  • gdb -c core ./a.out :用GDB調試生成的內核轉儲文件,出現以下信息
  • b main :在main函數出設置斷點
  • info braek:查看斷點
  • run -a:運行程序
  • start:同上
  • backtrace full -N:在端點處顯示最後的N個棧幀
  • print:顯示局部變量
  • info reg:顯示寄存器值
  • p/c $eax:ASCII顯示寄存器的值
    • u:無符號十進制
    • o:八進制
    • t:二進制
    • d:十進制
  • x/10i $pc:顯示地址pc處的10條彙編代碼
    • x:16進制顯示pc處的值
    • 同上
  • disassemble:反彙編當前的整個函數
  • disassemble 程序計數器:反彙編程序計數器所在函數的整個函數
  • disassemble 開始地址 結束地址:反彙編從開始地址到結束地址之間的部分
  • next:執行下一步
  • step:執行到函數內部
  • nexti:逐條執行彙編指令
  • continue:繼續執行,加數字如 c 5表遇到5次斷點不中止
  • watch <表達式>:常量或變量發生變化時暫停運行
  • awatch <表達式>:被訪問、改變時暫停訪問
  • rwatch <表達式>:被訪問時暫停運行
    • awatch short_output:short_output被訪問時暫停運行
  • delete b:刪除斷點和監視點
  • set variable <變量>=<表達式>:如set variable a=1,把a的值改成1
  • generate-core-file :生成內核轉儲文件
  • gcore 'pidof emacs':在命令行直接生成內核轉儲文件

6. 調試器(GDB)的基本使用方法(之二)

相關文章
相關標籤/搜索