標籤:gdb gcc
gcc
常用選項
-c 只編譯不連結,產生目標檔案".o"
-S 只編譯不彙編,產生彙編代碼
-E 只進行先行編譯,不做其他處理
-g 在可執行程式中包含標準調試資訊
-o file 將file檔案指定為輸出檔案
-v 列印出編譯器內部編譯各過程的命令列資訊和編譯器的版本
-I dir 在標頭檔的搜尋路徑列表中添加dir目錄
gcc庫選項列表
-static 進行靜態編譯,即連結靜態庫,禁止使用動態庫
-shared
1.可以產生動態庫檔案
2.進行動態編譯,儘可能地連結動態庫,只有當沒有動態庫時才會連結同名的靜態庫(
預設選項,即可省略)
-L dir 在庫檔案的搜尋路徑列表中添加dir目錄
-lname 連結稱為libname.a(靜態庫)或者libname.so(動態庫)的庫檔案。若兩個庫都存在則根據編譯方式(-static還是-shared)而進行連結
-fPIC(或-fpic)產生使用相對位址的位置無關的目標代碼。然後通常使用gcc的-static選項從該PIC目標檔案產生動態庫檔案
連結到靜態庫會使使用者的程式臃腫,並且難以升級,但是可能會比較容易部署。而連結到動態庫會使使用者的程式輕便,並且易於升級,但是會難以部署
gcc警告和出錯選項選項列表
-ansi 支援符合ANSI標準的C程式
-pedantic 允許發出ANSI C標準所列的全部警告資訊
-pedantic-error 允許發出ANSI C標準所列的全部錯誤資訊
-w 關閉所有警示
-Wall 允許發出gcc提供的所有有用的警示資訊
-werror 把所有的警示資訊轉化為錯誤資訊,並在警示發生時終止編譯過程
#include<stdio.h>
void main()
{
long long tmp = 1;
printf("bad code\n");
return 0;
}
gcc –ansi warning.c –o warning
warning.c: 在函數“main”中:
warning.c:7 警告:在無返回值的函數中,“return”帶返回值
warning.c:4 警告:“main”的傳回型別不是“int”
該選項並沒有發現“long long”
gcc –pedantic warning.c –o warning
warning.c: 在函數“main”中:
warning.c:5 警告:ISO C90不支援“long long”
warning.c:7 警告:在無返回值的函數中,“return”帶返回值
warning.c:4 警告:“main”的傳回型別不是“int”
使用該選項查出了“long long”
gcc –Wall warning.c –o warning
warning.c:4 警告:“main”的傳回型別不是“int”
warning.c: 在函數“main”中:
warning.c:7 警告:在無返回值的函數中,“return”帶返回值
warning.c:5 警告:未使用的變數“tmp”
使用該選項查出了未使用的變數tmp,但它並沒有找出無效資料類型
gcc還可以利用選項對單獨的常見錯誤分別指定警告
最佳化選項 -On
n 是一個代表最佳化層級的整數 n 的取值範圍及其對應的最佳化效果可能並不完全相同,比較典型的範圍是從0變化到2或3;
"-O" 主要進行線程跳轉(Thread Jump)和延遲退棧(Deferred Stack Pops)兩種最佳化
"-O2" 除了完成所有"-O1"層級的最佳化之外,同時還要進行一些額外的調整工作,如處理器指令調度等。
"-O3"則還包括迴圈展開和其他一些與處理器特性相關的最佳化工作。
弊端:
雖然最佳化選項可以加速代碼的運行速度,但對於調試而言將是一個很大的挑戰。
因為代碼在經過最佳化之後,原先在來源程式中聲明和使用的變數很可能不再使用,控制流程也可能會突然跳轉到意外的地方,迴圈語句也有可能因為迴圈展開而變得到處都有,所有這些對調試來講都將是一場噩夢。建議在調試的時候最好不使用任何最佳化選項,只有當程式在最終發行的時候才考慮對其進行最佳化。
gcc體繫結構相關選項列表
-mcpu=type 針對不同的CPU使用相應的CPU指令。可選擇的type有i386、i486、pentium及i686
-mieee-fp 使用IEEE標準進行浮點數的比較
-mno-ieee-fp 不使用IEEE標準進行浮點數的比較
-msoft-float 輸出包含浮點庫調用的目標代碼
-mshort 把int類型作為16位處理,相當於short int
-mrtd 強行將函數參數個數固定的函數用ret NUM返回,節省調用函數的一條指令
gdb 調試器
#include <stdio.h>int sum(int);int main(){ printf("the sum of 1-50 is %d\n",sum(50));}int sum(int n){ int i,sum; for(i = 1,sum = 0; i <= n; ++i){ sum += i; } return sum;}
gcc -g gdbt.c -o gdbt
gdb gdbt
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-60.el6_4.1)
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /root/gdbt...done.
(gdb)
(1)查看檔案。
鍵入“l”(list)查看所載入的檔案
(gdb) l1#include <stdio.h>23int sum(int);45int main(){6 printf("the sum of 1-50 is %d\n",sum(50));7}89int sum(int n){10 int i,sum;(gdb) 11 for(i = 1,sum = 0; i <= n; ++i){12 sum += i;13 }14 return sum;15}(gdb) Line number 16 out of range; gdbt.c has 15 lines.gdb 列出的原始碼中明確地給出了對應的行號,這樣就可以大大地方便代碼的定位。
(2)設定斷點。
在 gdb 中設定斷點非常簡單,只需在“b”後加入對應的行號即可(這是最常用的方式,另外還有其他方式設定斷點)
(gdb)
b 12
Breakpoint 1 at 0x8048402: file gdbt.c, line 12.
利用行號設定斷點是指代碼運行到對應行之前將其停止,如上例中,代碼運行到第12 行之前暫停(並沒有運行第12 行)
(3)查看斷點情況。
在設定完斷點之後,使用者可以鍵入“info b”來查看設定斷點情況,在gdb 中可以設定多個斷點。
(gdb)
info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x08048402 in sum at gdbt.c:12
使用者在斷點鍵入“backrace”(只輸入“bt”即可)可以查到調用函數(堆棧)的情況,這個功能在程式調試之中使用非常廣泛,經常用於排除錯誤或者監視呼叫堆疊的情況。
(gdb) bt
#0 sum (n=50) at gdbt.c:12
#1 0x080483d9 in main () at gdbt.c:6
(4)運行代碼。
接下來就可運行代碼了,gdb預設從首行開始運行代碼,鍵入“r”(run)即可(若想從程式中指定行開始運行,可在r後面加上行號)。
(gdb) r
Starting program: /root/gdbt
Breakpoint 1, sum (n=50) at gdbt.c:12
12 sum += i;
(5)查看變數值。
在程式停止運行之後,程式員所要做的工作是查看斷點處的相關變數值。在gdb中鍵入“p”+變數值即可
(gdb) p sum
$1 = 0
(gdb) p i
$2 = 1
(gdb)
gdb 在顯示變數值時都會在對應值之前加上“$N”標記,它是當前變數值的引用標記,所以以後若想再次引用此變數就可以直接寫作“$N”,而無需寫冗長的變數名。
(gdb) p $2
$3 = 1
(6)單步運行。
單步運行可以使用命令“n”(next)或“s”(step),它們之間的區別在於:若有函數調用的時候,“s”會進入該函數而“n”不會進入該函數。因此,“s”就類似於Uisual等工具中的“step in”,“n”類似與Uisual等工具中的“step over”
(gdb) n
11 for(i = 1,sum = 0; i <= n; ++i){
(gdb) s
Breakpoint 1, sum (n=50) at gdbt.c:12
12 sum += i;
(7)刪除斷點
delete Num 這個Num是info b的Num
(gdb) delete 1(d 1同效)
(gdb) info b
Num Type Disp Enb Address What
2 breakpoint keep y 0x080483cd in main at gdbt.c:6
(8)恢複程式運行
在查看完所需變數及堆棧情況後,就可以使用命令“c”(continue)恢複程式的正常運行了。這時,它會把剩餘還未執行的程式執行完,並顯示剩餘程式中的執行結果
(gdb) c
Continuing.
the sum of 1-50 is 1275
在gdb中,程式的運行狀態有“運行”、“暫停”和“停止”3種,其中“暫停”狀態為程式遇到了斷點或觀察點之類的,程式暫時停止運行,而此時函數的地址、函數參數、函數內的局部變數都會被壓入“棧”(Stack)中。故在這種狀態下可以查看函數的變數值等各種屬性。但在函數處於“停止”狀態之後,“棧”就會自動撤消,它也就無法查看各種資訊了。
gdb基本命令
gdb 的命令可以通過查看help進行尋找,由於gdb 的命令很多,因此gdb 的help將其分成了很多種類(class),使用者可以通過進一步查看相關class找到相應命令
(gdb) help(簡寫h)
List of classes of commands:
aliases -- Aliases of other commands
breakpoints -- Making program stop at certain points
data -- Examining data
files -- Specifying and examining files
internals -- Maintenance commands
obscure -- Obscure features
running -- Running the program
stack -- Examining the stack
status -- Status inquiries
support -- Support facilities
tracepoints -- Tracing of program execution without stopping the program
user-defined -- User-defined commands
Type "help" followed by a class name for a list of commands in that class.
Type "help all" for the list of all commands.
Type "help" followed by command name for full documentation.
Type "apropos word" to search for commands related to "word".
Command name abbreviations are allowed if unambiguous.
(gdb) h data
Examining data.
List of commands:
append -- Append target code/data to a local file
append binary -- Append target code/data to a raw binary file
append binary memory -- Append contents of memory to a raw binary file
append binary value -- Append the value of an expression to a raw binary file
append memory -- Append contents of memory to a raw binary file
append value -- Append the value of an expression to a raw binary file
call -- Call a function in the program
disassemble -- Disassemble a specified section of memory
display -- Print value of expression EXP each time the program stops
...
(gdb) h append
Append target code/data to a local file.
List of append subcommands:
append binary -- Append target code/data to a raw binary file
append memory -- Append contents of memory to a raw binary file
append value -- Append the value of an expression to a raw binary file
Type "help append" followed by append subcommand name for full documentation.
Type "apropos word" to search for commands related to "word".
Command name abbreviations are allowed if unambiguous.
(gdb) h append binary
Append target code/data to a raw binary file.
List of append binary subcommands:
append binary memory -- Append contents of memory to a raw binary file
append binary value -- Append the value of an expression to a raw binary file
Type "help append binary" followed by append binary subcommand name for full documentation.
Type "apropos word" to search for commands related to "word".
Command name abbreviations are allowed if unambiguous.
(gdb) h append binary value
Append the value of an expression to a raw binary file.
Arguments are FILE EXPRESSION. Writes the value of EXPRESSION
to the specified FILE in raw target ordered bytes.
使用者已知命令名,直接鍵入“help [command]”也可,tab可命令補全。
gdb 中的命令主要分為以下幾類:工作環境相關命令、設定斷點與恢複命令、原始碼查看命令、查看運行資料相關命令及修改運行參數命令
1.工作環境相關命令
gdb 中不僅可以調試所啟動並執行程式,而且還可以對程式相關的工作環境進行相應的設定,甚至還可以使用shell中的命令進行相關的操作,其功能極其強大
set args 運行時的參數指定運行時參數,如set args 2
show args 查看設定好的運行參數
Path dir 設定程式的運行路徑
show paths 查看程式的運行路徑
set environment var [=value] 設定環境變數
show environment [var] 查看環境變數
cd dir 進入dir目錄,相當於shell中的cd命令
Pwd 顯示當前工作目錄
shell command 運行shell的command命令
2.設定斷點與恢複命令
gdb
中設定斷點與恢複的常見命令
Info b 查看所設斷點
break [檔案名稱:]行號或函數名 <條件運算式> 設定斷點
tbreak [檔案名稱:]行號或函數名 <條件運算式> 設定臨時斷點,到達後被自動刪除
delete [斷點號] 刪除指定斷點,其斷點號為“info b”中的第一欄。若預設斷點號則刪除所有斷點
disable [斷點號] 停止指定斷點,使用“info b”仍能查看此斷點。同delete一樣,若預設斷點號則停止所有斷點
enable [斷點號] 啟用指定斷點,即啟用被disable停止的斷點
condition [斷點號] <條件運算式> 修改對應斷點的條件
ignore [斷點號]<num> 在程式執行中,忽略對應斷點num次
Step 單步恢複程式運行,且進入函數調用
Next 單步恢複程式運行,但不進入函數調用
Finish 運行程式,直到當前函數完成返回
C 繼續執行函數,直到函數結束或遇到新的斷點
gdb 中設定斷點有多種方式:其一是按行設定斷點;另外還可以設定函數斷點和條件斷點。
1) 函數斷點。
gdb 中按函數設定斷點只需把
函數名列在命令“b”之後
(gdb) b sum
Breakpoint 4 at 0x80483f2: file gdbt.c, line 11.
(gdb) info b
Num Type Disp Enb Address What
4 breakpoint keep y 0x080483f2 in sum at gdbt.c:11
2)條件斷點。
gdb 中設定條件斷點的格式為:
b 行數或函數名if 運算式
(gdb) b 12
if i==2
Breakpoint 5 at 0x8048402: file gdbt.c, line 12.
(gdb) info b
Num Type Disp Enb Address What
4 breakpoint keep y 0x080483f2 in sum at gdbt.c:11
5 breakpoint keep y 0x08048402 in sum at gdbt.c:12
stop only if i==2
3.gdb 中源碼查看相關命令
在 gdb 中可以查看源碼以方便其他動作
list <行號>|<函數名> 查看指定位置代碼
file [檔案名稱] 載入指定檔案
forward-search Regex原始碼的前向搜尋
reverse-search Regex原始碼的後向搜尋
dir DIR 將路徑DIR添加到源檔案搜尋的路徑的開頭
show directories 顯示源檔案的當前搜尋路徑
info line 顯示載入到gdb記憶體中的代碼
4.gdb 中查看運行資料相關命令
gdb 中查看運行資料是指當程式處於“運行”或“暫停”狀態時,可以查看的變數及運算式的資訊
print 運算式|變數查看程式運行時對應運算式和變數的值
x <n/f/u> 查看記憶體變數內容。其中n為整數表示顯示記憶體的長度,f表示顯示的格式,u表示從當前地址往後請求顯示的位元組數
display 運算式設定在單步運行或其他情況中,自動顯示的對應運算式的內容
backtrace 查看當前棧的情況,即可以查到哪些被調用的函數尚未返回
5.gdb 中修改運行參數相關命令
gdb 還可以修改運行時的參數,並使該變數按照使用者當前輸入的值繼續運行。它的設定方法為:
在逐步執行的過程中,鍵入命令“set 變數=設定值”
gdb使用時的注意點:
1.在gcc編譯選項中一定要加入“-g”。
2.只有在代碼處於“運行”或“暫停”狀態時才能查看變數值。
3.設定斷點後程式在指定行之前停止。
linux下gcc.gdb整理