Linux工程管理器和GDB偵錯程式

2021-08-08 22:27:52 字數 4924 閱讀 7687

在實際的開發過程中,僅僅通過使用 gcc 命令對程式進行編譯是非常低效的。原因主要有以下兩點。

1)程式往往是由多個原始檔組成的,原始檔的個數越多,那麼 gcc 的命令列就會越長。此外,各種編譯規則也會加

大 gcc 命令列的複雜度。所以在開發除錯程式的過程中,通過輸入gcc 命令列來編譯程式是很麻煩的。

2)在程式的整個開發過程中,除錯的工作量佔到了整體工作量的 70%以上。在除錯程式的過程中,每次除錯一般只

會修改部分原始檔。而在使用 gcc 命令列編譯程式時,gcc 會把那些沒有被修改的原始檔一起編譯,這樣就會影響編譯的

總體效率。

gcc 提供了半自動化的工程管理器 make。所謂半自動化是指在使用工程管理器前需要人工編寫程式的編譯規則

所有的編譯規則都儲存在 makefile 檔案中。全自動化的工程管理器在編譯程式前會自動生成 makefile 檔案。make工

程管理器的優越性具體體現在以下兩個方面。

(1)使用方便

通過命令「make」就可以啟動 make 工程管理器對程式進行編譯,所以不再需要每次都輸入 gcc 命令列。make 啟動

後會根據 makefile 檔案中的編譯規則命令自動對原始檔進行編譯和鏈結,最終生成可執行檔案。

(2)除錯效率高

為了提高編譯程式的效率,make 會檢查每個原始檔的修改時間(時間戳)。只有在上次編譯之後被修改的原始檔

才會在接下來的編譯過程中被編譯和鏈結,這樣就能避免多餘的編譯工作量。為了保證原始檔具有正確的時間戳,必須

保證作業系統時間的正確性(注意vmware 虛擬機器的 cmos 時間是否正確)。

1)需要生成的目標檔案(target file)。

2)生成目標檔案所需要的依賴檔案(dependency file)。

3)生成目標檔案的編譯規則命令列(command)。

這三項內容按照如下格式進行組織:

target file  : dependency file

(tab)command

其中,makefile 規定在書寫 command 命令行前必須加乙個鍵。

makefile 檔案由以下三項基本內容組成。

1)需要生成的目標檔案(target file)。

2)生成目標檔案所需要的依賴檔案(dependency file)。

3)生成目標檔案的編譯規則命令列(command)。

make 工程管理器在編譯程式時會檢查每個依賴檔案的時間戳,一旦發現某個依賴檔案的時間戳比目標檔案要新,就會執行目標檔案的規則命令來重新生成目標檔案。這個過程稱為目標檔案的依賴規則檢查。依賴規則檢查是 make 工程管理器的最核心的工作任務之一。下面以編譯程式 test(由 a.c、b.c 和 b.h 組成)為例來描述 make 的工作過程。例如:

  a.c:

#include 「b.h」

int main()

  b.h:

void hello();
  b.c

#include 「stdio.h」

void hello()

int main()

test.c檔案是乙個通過遞迴呼叫來計算5的階乘的程式。通過執行命令「gcc –g test.c-o test」對 test.c 進行編譯其中引數 g 的作用是把除錯資訊加入生成的 test 可執行檔案中,否則 gdb 就無法對 test 進行除錯

接下來可以使用命令「gdb test」啟動 gdb 對 test 進行除錯了。如下所示:

[root@localhost home]# gdb test

gnu gdb everest linux (6.4-1)

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 "i686-pc-linux-gnu"...using host libthread_db

library "/lib/libthread_db.so.1".
可以看到,gdb 首先顯示了版本資訊和庫資訊。隨後 gdb 停留在符號「(gdb)」處等待使用者輸入除錯命令。gd

b 提供了大量的命令來實現各種除錯功能,下面僅對一些常用的命令進行介紹。

在除錯程式時,gcc 會給出產生警告或錯誤的**行數。但在普通的文字環境中是無法直接獲得語句行數的。在

gdb 中通過命令 l(list 的縮寫)可以檢視所有的**行數。如下所示:

(gdb) l

2 int cal(int n)3 9

10 int main()

11 (gdb) l

line number 17 out of range; test.c has 16 lines.

可以看到,gdb 以 10 行為單位進行顯示。再執行一次命令 l 就會顯示下 10 行**。這樣設計方便了源**的

閱讀。斷點是除錯程式的重要方法,通過斷點可以知道程式每一步的執行狀況(比如當前變數的值、函式是否呼叫、堆

棧使用情況等)。在 gdb 中通過命令 b(breakpoint 的縮寫)進行斷點設定。如下所示:

(gdb) b 7

breakpoint 1 at 0x8048389: file test.c, line 7.

可以看到,gdb 在程式的第 7 行處設定了第乙個斷點,並顯示了斷點的位置資訊。

在 gdb 中通過命令 r(run 的縮寫)執行程式。gdb 預設從**的首行開始執行(也可以通過「r 行數」的方式讓

程式從指定行數開始執行)。如果程式中有斷點,則程式會在斷點行數的前一行暫停執行,結果如下所示:

(gdb) r

starting program: /home/test

breakpoint 1, cal (n=5) at test.c:7

7 return n * cal(n - 1);

可以看到,程式在執行到第 7 行時就暫停了,沒有繼續執行第 8 行的**。

程式暫停執行後就可以檢視當前的狀態了。在 gdb 中通過命令「p 變數名」(print 的縮寫)檢視當前變數 n 的值

如下所示:

(gdb) p n

$1 = 5

gdb 通過「$n」(「$1」、「$2」)來顯示變數的值。這樣在下次檢視變數值時,就可以用「$n」代替變數名了。可以看到,當前變數 n 的值為 5。

檢視完當前程式的情況後,就可以讓程式繼續往下執行了。在 gdb 中通過命令 c 讓程式繼續往下執行在 test.c 中,由於函式 cal 是遞迴呼叫執行,所以程式會再次在斷點處暫停。如下所示:

(gdb) c

continuing.

breakpoint 1, cal (n=4) at test.c:7

7 return n * cal(n - 1);

程式暫停後可以再次檢視當前變數 n 的值。如下所示:

(gdb) p n

$2 = 4

在程式邏輯比較複雜的時候往往需要程式能一步一步的往下執行,但如果每行都設定乙個斷點的話又會很麻煩。

在 gdb 中可以通過命令 s(step 的縮寫)和 n(next 的縮寫)讓程式一步一步的往下執行。其中s 可以在發生

函式呼叫時進入函式內部執行,而 n 不會進入函數內部執行。在 test.c 中。由於函式 cal 是遞迴呼叫執行,所以只能

選擇 s 才能看到變數n 的值。如下所示:

(gdb) s

cal (n=3) at test.c:4

4 if(n == 1)

(gdb) s

breakpoint 1, cal (n=3) at test.c:7

7 return n * cal(n - 1);

(gdb) s

cal (n=2) at test.c:4

4 if(n == 1)

(gdb) s

104breakpoint 1, cal (n=2) at test.c:7

7 return n * cal(n - 1);

(gdb) s

cal (n=1) at test.c:4

4 if(n == 1)

(gdb) s

5 return 1;

由於在使用 s 前函式 cal 已經呼叫了兩次,所以執行 s 後當前變數 n 的值為 3。可以看到,函式 cal 進行 3 次呼叫

後返回了值 1。

偵錯程式gdb 工程管理器 make

格式 gcc g 檔名.c o 可執行檔案 gdb 可執行檔案 list 檢視程式 quit 退出 run 執行 break 行號 設定斷點 break 行號 if i 3 語句 info break 檢視斷點 delete 斷點編號 刪除斷點 next 單步執行 不進入子函式 step 單步執行 ...

Linux工程管理器make

1.怎麼建立功能目錄 mkdir p add src 根據指令依次建立目錄 mv add.c add src touch add makefile 在功能目錄下建 makefile 2.功能目錄中的目錄 include 存放標頭檔案 lib 存放庫檔案 tools 存放工具 doc 存放文件 scr...

GDB偵錯程式 工程管理器 make和指令碼Shell

一 gdb功能 1 啟動被除錯程式 2 讓被除錯程式在指定的位置停住 3 當程式被停住時,可以檢查程式狀態 變數值 gcc g test.c o test gdb test 啟動gdb break main 在main函式處設定斷點 run r 執行程式 next n 單步執行程式 不進入子函式 s...