【Linux網路編程】使用GDB調試程式

来源:http://www.cnblogs.com/tyrus/archive/2016/06/15/linux_gdb.html
-Advertisement-
Play Games

Linux中有一個強大的調試工具GDB(GNU Debugger),可以調試C和C++程式。 GDB的主要功能如下: 使用GDB的前提是,在編譯程式的時候需要加入-g選項,即 gcc -g xxx.c。當設置這個選項的時候,GCC會向程式中加入“楔子”,GDB能夠利用這些楔子與程式交互。 書上的測試 ...


Linux中有一個強大的調試工具GDB(GNU Debugger),可以調試C和C++程式。

GDB的主要功能如下:

  1. 設置斷點
  2. 顯示變數的值
  3. 單步執行
  4. 運行時修改變數的值
  5. 路徑跟蹤,方便跟蹤代碼
  6. 線程切換
  7. 其他的。。。

使用GDB的前提是,在編譯程式的時候需要加入-g選項,即 gcc -g xxx.c。當設置這個選項的時候,GCC會向程式中加入“楔子”,GDB能夠利用這些楔子與程式交互。

 

書上的測試程式一則:

/*文件名:ex02-gdb-01.c*/
#include <stdio.h>
/* 用於printf*/
#include <stdlib.h>
/*用於malloc*/

/* 聲明函數sum為static int類型 */
static int sum(int value);

/* 用於控制輸入輸出的結構 */
struct inout {
	int value;
	int result;
	};
int main(int argc, char * argv[]) {
	/*申請記憶體*/
	struct inout * io = (struct inout * ) malloc(sizeof(struct inout));
	/*判斷是否成功*/
	if (NULL == io) {
		/*失敗返回*/
		printf("申請記憶體失敗\n");
		return -1;
	}
	/*判斷輸入參數是否正確*/
	if (argc != 2) {
		printf("參數輸入錯誤!\n");
		return -1;
	}
	/* 獲得輸入的參數 */
	io -> value = *argv[1] - '0';
	/* 對value進行累加求和 */
	io -> result = sum(io -> value);
	printf("你輸入的值為:%d,計算結果為:%d\n", io -> value, io -> result);
	return 0;
}

/* 累加求和函數 */
static int sum(int value) {
	int result = 0;
	int i = 0;
	/* 迴圈計算累加值 */
	for (i = 0; i < value; i++) result += (i + 1);
	/*返回結果*/
	return result;
}

 

輸入gcc -o test gdb-01.c -g,使其加入“楔子”。下麵進入調試:

其中test是可執行文件的名字。

 

GDB常用的命令( 命令(命令簡寫):格式及含義 ):

file:載入(可執行)文件,使用在gdb命令後沒有接文件名的時候。

(gdb) file gdb-01.c
"/home/tyruschin/ClionProjects/gdb_learning/gdb-01.c": not in executable format: 不可識別的文件格式
(gdb) file test
Load new symbol table from "test"? (y or n) y
Reading symbols from test...done.

set args:設置輸入參數(可以在run命令中設置,如果不設置的話,run的時候預設使用前一條run命令的參數),set args 參數1 參數2 ...

(gdb) set args 2
(gdb) run
Starting program: /home/tyruschin/ClionProjects/gdb_learning/test 2
你輸入的值為:2,計算結果為:3

show:顯示變數,show args

(gdb) set args 2 3
(gdb) show args
Argument list to give program being debugged when it is started is "2 3".

list(l):表示列出文件的代碼內容。list 1表示從第一行開始,預設顯示10行,按下回車鍵可以繼續列印10行;list 1,4表示顯示1到4行,此時再次按下回車則繼續列印下麵的10行。

break(b):設置斷點,b 行號或函數名。程式運行到斷點的位置會終端,等待用戶的下一步操作指令。

具體的使用(如果有多個文件共同生成一個目標執行文件的時候,要指定文件名,如 b gdb-01.c:38 ):

  1. break 行號:程式停止在設定的行之前
  2. break 函數名稱:程式停止在設定的函數之前
  3. break 行數或者函數if條件:條件為真的情況下,到達指定行或函數時停止

查看斷點信息,info break

// 沒有寫編號就表示全部編號了

刪除指定的某個斷點:delete breakpoints 斷點編號(在info break 中找到)

禁止斷點:disable b 斷點編號(此時info break中的Enb列中,顯示的是n而不是y)

允許斷點(禁止的反操作):enable b 斷點編號 

清除斷點:clear 斷點行號

run(r):運行程式,run args,這裡的args和set args中的是一致的。運行到遇到斷點會暫停下來。

(gdb) run 3
Starting program: /home/tyruschin/ClionProjects/gdb_learning/test 3

Breakpoint 1, sum (value=3) at gdb-01.c:39
39		int result = 0;

print(p):列印變數內容,功能強大,可以列印任何有效表達式的值。

設置斷點在28行,以上是p列印變數的例子,其中io是一個結構體數組,argv是一個字元串數組,@後面的數字表示列印的個數,超過個數之後列印處的結果是隨機的。。

whatis:變數類型檢測,列印數組或者變數的類型,whatis 變數名

ptype:變數類型檢測,結構的詳細定義

set:修改變數的值,set xx=val

display:display 變數,每次在調試到暫停的時候都會顯示該值。

(gdb) run 3
Starting program: /home/tyruschin/ClionProjects/gdb_learning/test 3

Breakpoint 8, main (argc=2, argv=0x7fffffffde18) at gdb-01.c:33
33		printf("你輸入的值為:%d,計算結果為:%d\n", io -> value, io -> result);
4: argc = 2
3: *argv = 0x7fffffffe1c6 "/home/tyruschin/ClionProjects/gdb_learning/test"
2: argv = (char **) 0x7fffffffde18
1: argc = 2

單步調試:next(n)單步跟蹤,step(s)進入某個函數,finish返回調用的函數中,continue(c)表示繼續執行知道遇到斷點或結束。

(gdb) run 3
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/tyruschin/ClionProjects/gdb_learning/test 3

Breakpoint 1, main (argc=2, argv=0x7fffffffde18) at gdb-01.c:19
19		if (NULL == io) {
(gdb) s
25		if (argc != 2) {
(gdb) s
30		io -> value = *argv[1] - '0';
(gdb) s
32		io -> result = sum(io -> value);
(gdb) s
sum (value=3) at gdb-01.c:39
39		int result = 0;
(gdb) s
40		int i = 0;
(gdb) finish
Run till exit from #0  sum (value=3) at gdb-01.c:40
0x0000000000400639 in main (argc=2, argv=0x7fffffffde18) at gdb-01.c:32
32		io -> result = sum(io -> value);
Value returned is $1 = 6
(gdb) s
33		printf("你輸入的值為:%d,計算結果為:%d\n", io -> value, io -> result);
(gdb) c
Continuing.
你輸入的值為:3,計算結果為:6
[Inferior 1 (process 27047) exited normally]

 q表示退出GDB。。

 

 

 

 

附:書上的例子:

/*文件名:ex02-gdb-01.c*/
#include <stdio.h>
/* 用於printf*/
#include <stdlib.h>
/*用於malloc*/

/* 聲明函數sum為static int類型 */
static int sum(int value);

/* 用於控制輸入輸出的結構 */
struct inout {
	int value;
	int result;
	};
int main(int argc, char * argv[]) {
	/*申請記憶體*/
	struct inout * io = (struct inout * ) malloc(sizeof(struct inout));
	/*判斷是否成功*/
	if (NULL == io) {
		/*失敗返回*/
		printf("申請記憶體失敗\n");
		return -1;
	}
	/*判斷輸入參數是否正確*/
	if (argc != 2) {
		printf("參數輸入錯誤!\n");
		return -1;
	}
	/* 獲得輸入的參數 */
	io -> value = *argv[1] - '0';
	/* 對value進行累加求和 */
	io -> result = sum(io -> value);
	printf("你輸入的值為:%d,計算結果為:%d\n", io -> value, io -> result);
	return 0;
}

/* 累加求和函數 */
static int sum(int value) {
	int result = 0;
	int i = 0;
	/* 迴圈計算累加值 */
	for (i = 0; i < value; i++) result += (i + 1);
	/*返回結果*/
	return result;
}

  


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 學習Linux Shell知識,就來Linux大學網(Linuxdaxue.com)! 本系列適合Linux初學者,屬於Linux入門級教程,主要介紹了Shell的分類、語法格式以及腳本的使用和編寫格式等。 不斷更新中,是Shell學習的必讀經典教程。 現主要包含以下文章: Linux Shell系 ...
  • 進程式控制制塊,英文名(Processing Control Block),簡稱 PCB 。 進程式控制制塊是系統為了管理進程設置的一個專門的數據結構,主要表示進程狀態。 每一個進程都對應一個PCB來維護進程相關的信息; 在Linux中,PCB結構為task_struct; task_struct是Linu ...
  • 近日換新機器,裝了win10,但想從舊機器訪問win10的\\ip\D$拷數據過去,首先發現怎麼也連不上win10的共用,於是把win10防火牆中“文件和印表機共用”的“專用”(即內網)勾選上終於可以連上了。 但又發現用我新建的賬號(管理員許可權)也無法訪問\\ip\D$,儘管\\ip已經可以連接上去 ...
  • 1,crontab簡介 crontab命令常見於Unix和Linux的操作系統之中,用於設置周期性被執行的指令。該命令從標準輸入設備讀取指令,並將其存放於“crontab”文件中,以供之後讀取和執行。通常,crontab儲存的指令被守護進程激活。crond 常常在後臺運行,每一分鐘檢查是否有預定的作 ...
  • 最近伺服器上出現了一個很詭異的問題,癥狀如下圖所示: 查看進程發現: 如上圖所示,非常多的df -h進程沒有退出。於是手工kill掉這些 df -h進程。cpu load恢復正常。 至於為什麼會有這麼多 df -h進程,給出的解釋是:掛了NFS,之前沒有umount乾凈,所以有df -h進程 ...
  • 前面經過對LAMP安裝配置的學習算入門了,LAMP(Linux+Apache+Mysql+Php/perl/python),而LEMP架構是把提供web服務的Apache改用為Nginx。從而形成,(Linux+Nginx+Mysql+Php/perl/python)架構,在當前企業級別應用Ngin ...
  • 額,這篇貌似是我名義上的第一篇博客,但是我好像沒有第一寫他,沒事,都一樣。(我會假裝它是人生中第一篇博客的) 上大學之後,很久之後才發現自己聽喜歡linux的,因為感覺很高大上,所以自己自學了很多關於linux的,不過我不是大神,我只是一個小小白,寫的技術可能對於一些大神來說簡直是so easy , ...
  • 一.多行註釋的添加 1. vim的命令模式下(ESC 進入命令模式): 2. 按CTRL+V進入可視化模式(VISUAL BLOCK); 註意:vim命令模式下v進入的是visual模式,ctrl+v進入的是visual block,簡單的選擇視覺區別如下圖: 3. 移動游標,選中需要註釋的多行 的 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...