GDB十分鐘教程

GDB十分鐘教程

作者: liigo
原文鏈接:?
http://blog.csdn.net/liigo/archive/2006/01/17/582231.aspx
日期: 2006年1月16日

本文寫給主要工作在Windows操作系統下而又需要開發一些跨平臺軟件的程序員朋友,以及程序愛好者。

GDB是一個由GNU開源組織發布的、UNIX/LINUX操作系統下的、基于命令行的、功能強大的程序調試工具。

GDB中的命令固然很多,但我們只需掌握其中十個左右的命令,就大致可以完成日常的基本的程序調試工作。

?命令?解釋?示例
file <文件名>加載被調試的可執行程序文件。
因為一般都在被調試程序所在目錄下執行GDB,因而文本名不需要帶路徑。
(gdb) file gdb-sample
rRun的簡寫,運行被調試的程序。
如果此前沒有下過斷點,則執行完整個程序;如果有斷點,則程序暫停在第一個可用斷點處。
(gdb) r
cContinue的簡寫,繼續執行被調試程序,直至下一個斷點或程序結束。(gdb) c
b <行號>
b <函數名稱>
b *<函數名稱>
b *<代碼地址>

d [編號]

b: Breakpoint的簡寫,設置斷點。兩可以使用“行號”“函數名稱”“執行地址”等方式指定斷點位置。
其中在函數名稱前面加“*”符號表示將斷點設置在“由編譯器生成的prolog代碼處”。如果不了解匯編,可以不予理會此用法。

d: Delete breakpoint的簡寫,刪除指定編號的某個斷點,或刪除所有斷點。斷點編號從1開始遞增。

(gdb) b 8
(gdb) b main
(gdb) b *main
(gdb) b *0x804835c

(gdb) d

s, ns: 執行一行源程序代碼,如果此行代碼中有函數調用,則進入該函數;
n: 執行一行源程序代碼,此行代碼中的函數調用也一并執行。

s 相當于其它調試器中的“Step Into (單步跟蹤進入)”;
n 相當于其它調試器中的“Step Over (單步跟蹤)”。

這兩個命令必須在有源代碼調試信息的情況下才可以使用(GCC編譯時使用“-g”參數)。

(gdb) s
(gdb) n
si, nisi命令類似于s命令,ni命令類似于n命令。所不同的是,這兩個命令(si/ni)所針對的是匯編指令,而s/n針對的是源代碼。(gdb) si
(gdb) ni
p <變量名稱>Print的簡寫,顯示指定變量(臨時變量或全局變量)的值。(gdb) p i
(gdb) p nGlobalVar
display ...

undisplay <編號>

display,設置程序中斷后欲顯示的數據及其格式。
例如,如果希望每次程序中斷后可以看到即將被執行的下一條匯編指令,可以使用命令
“display /i $pc”
其中 $pc 代表當前匯編指令,/i 表示以十六進行顯示。當需要關心匯編代碼時,此命令相當有用。

undispaly,取消先前的display設置,編號從1開始遞增。

(gdb) display /i $pc

(gdb) undisplay 1

iInfo的簡寫,用于顯示各類信息,詳情請查閱“help i”。(gdb) i r
qQuit的簡寫,退出GDB調試環境。(gdb) q
help [命令名稱]GDB幫助命令,提供對GDB名種命令的解釋說明。
如果指定了“命令名稱”參數,則顯示該命令的詳細說明;如果沒有指定參數,則分類顯示所有GDB命令,供用戶進一步瀏覽和查詢。
(gdb) help display

 

廢話不多說,下面開始實踐。

先給出一個示例用的小程序,C語言代碼,簡單的不能再簡單了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

//此程序僅作為“GDB十分鐘教程”的示例代碼, by liigo
//Email:
liigo@sina.com
//blog: http://blog.csdn.net/liigo
//WebSite: www.liigo.com


#include
<stdio.h>

int
nGlobalVar = 0;

int
tempFunction(inta, intb)
{
??? printf("tempFunction is called, a = %d, b = %d /n",a, b
);
??? return (a +b
);
}


int
main()
{
??? int n
;
??? n = 1
;
??? n
++;
??? n
--;

??? nGlobalVar += 100
;
??? nGlobalVar -= 12
;

??? printf("n = %d, nGlobalVar = %d /n",n, nGlobalVar
);

??? n = tempFunction(1,2
);
??? printf("n = %d",n
);

??? return 0
;
}

請將此代碼復制出來并保存到文件 gdb-sample.c 中,然后切換到此文件所在目錄,用GCC編譯之:

gcc gdb-sample.c -o gdb-sample -g

在上面的命令行中,使用 -o 參數指定了編譯生成的可執行文件名為 gdb-sample,使用參數 -g 表示將源代碼信息編譯到可執行文件中。如果不使用參數 -g,會給后面的GDB調試造成不便。當然,如果我們沒有程序的源代碼,自然也無從使用 -g 參數,調試/跟蹤時也只能是匯編代碼級別的調試/跟蹤。

下面“gdb”命令啟動GDB,將首先顯示GDB說明,不管它:

GNU gdb Red Hat Linux (5.3post-0.20021129.18rh)
Copyright 2003 Free Software Foundation, Inc.
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 "i386-redhat-linux-gnu".
(gdb)?

上面最后一行“(gdb) ”為GDB內部命令引導符,等待用戶輸入GDB命令。

下面使用“file”命令載入被調試程序 gdb-sample(這里的 gdb-sample 即前面 GCC 編譯輸出的可執行文件):

(gdb) file gdb-sample
Reading symbols from gdb-sample...done.

上面最后一行提示已經加載成功。

下面使用“r”命令執行(Run)被調試文件,因為尚未設置任何斷點,將直接執行到程序結束:

(gdb) r
Starting program: /home/liigo/temp/test_jmp/test_jmp/gdb-sample
n = 1, nGlobalVar = 88
tempFunction is called, a = 1, b = 2
n = 3
Program exited normally.

下面使用“b”命令在 main 函數開頭設置一個斷點(Breakpoint):

(gdb) b main
Breakpoint 1 at 0x804835c: file gdb-sample.c, line 19.

上面最后一行提示已經成功設置斷點,并給出了該斷點信息:在源文件 gdb-sample.c 第19行處設置斷點;這是本程序的第一個斷點(序號為1);斷點處的代碼地址為 0x804835c(此值可能僅在本次調試過程中有效)。回過頭去看源代碼,第19行中的代碼為“n = 1”,恰好是 main 函數中的第一個可執行語句(前面的“int n;”為變量定義語句,并非可執行語句)。

再次使用“r”命令執行(Run)被調試程序:

(gdb) r
Starting program: /home/liigo/temp/gdb-sample

Breakpoint 1, main () at gdb-sample.c:19
19 n = 1;

程序中斷在gdb-sample.c第19行處,即main函數是第一個可執行語句處。

上面最后一行信息為:下一條將要執行的源代碼為“n = 1;”,它是源代碼文件gdb-sample.c中的第19行。

下面使用“s”命令(Step)執行下一行代碼(即第19行“n = 1;”):

(gdb) s
20 n++;

上面的信息表示已經執行完“n = 1;”,并顯示下一條要執行的代碼為第20行的“n++;”。

既然已經執行了“n = 1;”,即給變量 n 賦值為 1,那我們用“p”命令(Print)看一下變量 n 的值是不是 1 :

(gdb) p n
$1 = 1

果然是 1。($1大致是表示這是第一次使用“p”命令——再次執行“p n”將顯示“$2 = 1”——此信息應該沒有什么用處。)

下面我們分別在第26行、tempFunction 函數開頭各設置一個斷點(分別使用命令“b 26”“b tempFunction”):

(gdb) b 26
Breakpoint 2 at 0x804837b: file gdb-sample.c, line 26.
(gdb) b tempFunction
Breakpoint 3 at 0x804832e: file gdb-sample.c, line 12.

使用“c”命令繼續(Continue)執行被調試程序,程序將中斷在第二個斷點(26行),此時全局變量 nGlobalVar 的值應該是 88;再一次執行“c”命令,程序將中斷于第三個斷點(12行,tempFunction 函數開頭處),此時tempFunction 函數的兩個參數 a、b 的值應分別是 1 和 2:

(gdb) c
Continuing.

Breakpoint 2, main () at gdb-sample.c:26
26 printf("n = %d, nGlobalVar = %d /n", n, nGlobalVar);
(gdb) p nGlobalVar
$2 = 88
(gdb) c
Continuing.
n = 1, nGlobalVar = 88

Breakpoint 3, tempFunction (a=1, b=2) at gdb-sample.c:12
12 printf("tempFunction is called, a = %d, b = %d /n", a, b);
(gdb) p a
$3 = 1
(gdb) p b
$4 = 2

上面反饋的信息一切都在我們預料之中,哈哈~~~

再一次執行“c”命令(Continue),因為后面再也沒有其它斷點,程序將一直執行到結束:

(gdb) c
Continuing.
tempFunction is called, a = 1, b = 2
n = 3
Program exited normally.

 

有時候需要看到編譯器生成的匯編代碼,以進行匯編級的調試或跟蹤,又該如何操作呢?

這就要用到display命令“display /i $pc”了(此命令前面已有詳細解釋):

(gdb) display /i $pc
(gdb)?

此后程序再中斷時,就可以顯示出匯編代碼了:

(gdb) r
Starting program: /home/liigo/temp/test_jmp/test_jmp/gdb-sample

Breakpoint 1, main () at gdb-sample.c:19
19 n = 1;
1: x/i $pc 0x804835c <main+16>: movl $0x1,0xfffffffc(%ebp)

看到了匯編代碼,“n = 1;”對應的匯編代碼是“movl $0x1,0xfffffffc(%ebp)”。

并且以后程序每次中斷都將顯示下一條匯編指定(“si”命令用于執行一條匯編代碼——區別于“s”執行一行C代碼):

(gdb) si
20 n++;
1: x/i $pc 0x8048363 <main+23>: lea 0xfffffffc(%ebp),%eax
(gdb) si
0x08048366 20 n++;
1: x/i $pc 0x8048366 <main+26>: incl (%eax)
(gdb) si
21 n--;
1: x/i $pc 0x8048368 <main+28>: lea 0xfffffffc(%ebp),%eax
(gdb) si
0x0804836b 21 n--;
1: x/i $pc 0x804836b <main+31>: decl (%eax)
(gdb) si
23 nGlobalVar += 100;
1: x/i $pc 0x804836d <main+33>: addl $0x64,0x80494fc

 

接下來我們試一下命令“b *<函數名稱>”。

為了更簡明,有必要先刪除目前所有斷點(使用“d”命令——Delete breakpoint):

(gdb) d
Delete all breakpoints? (y or n) y
(gdb)

當被詢問是否刪除所有斷點時,輸入“y”并按回車鍵即可。

下面使用命令“b *main”在 main 函數的 prolog 代碼處設置斷點(prolog、epilog,分別表示編譯器在每個函數的開頭和結尾自行插入的代碼):

(gdb) b *main
Breakpoint 4 at 0x804834c: file gdb-sample.c, line 17.
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/liigo/temp/test_jmp/test_jmp/gdb-sample

Breakpoint 4, main () at gdb-sample.c:17
17 {
1: x/i $pc 0x804834c <main>: push %ebp
(gdb) si
0x0804834d 17 {
1: x/i $pc 0x804834d <main+1>: mov %esp,%ebp
(gdb) si
0x0804834f in main () at gdb-sample.c:17
17 {
1: x/i $pc 0x804834f <main+3>: sub $0x8,%esp
(gdb) si
0x08048352 17 {
1: x/i $pc 0x8048352 <main+6>: and $0xfffffff0,%esp
(gdb) si
0x08048355 17 {
1: x/i $pc 0x8048355 <main+9>: mov $0x0,%eax
(gdb) si
0x0804835a 17 {
1: x/i $pc 0x804835a <main+14>: sub %eax,%esp
(gdb) si
19 n = 1;
1: x/i $pc 0x804835c <main+16>: movl $0x1,0xfffffffc(%ebp)

此時可以使用“i r”命令顯示寄存器中的當前值———“i r”即“Infomation Register”:

(gdb) i r
eax 0xbffff6a4 -1073744220
ecx 0x42015554 1107383636
edx 0x40016bc8 1073834952
ebx 0x42130a14 1108544020
esp 0xbffff6a0 0xbffff6a0
ebp 0xbffff6a8 0xbffff6a8
esi 0x40015360 1073828704
edi 0x80483f0 134513648
eip 0x8048366 0x8048366
eflags 0x386 902
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x33 51

當然也可以顯示任意一個指定的寄存器值:

(gdb) i r eax
eax 0xbffff6a4 -1073744220

 

最后一個要介紹的命令是“q”,退出(Quit)GDB調試環境:




GDB 調試器使用手冊


使用GDB:
???本文描述GDB,GNU的原代碼調試器。(這是4.12版1994年一月,GDB版本4。16)
*?目錄:
*?摘要:????????????????????????GDB的摘要
*?實例:??????????????????????????一個使用實例
*?入門:????????????????????????進入和退出GDB
*?命令:????????????????????????GDB?的命令
*?運行:????????????????????????在GDB下運行程序
*?停止:????????????????????????暫停和繼續執行
*?棧:??????????????????????????檢查堆棧
*?原文件:??????????????????????檢查原文件
*?數據:????????????????????????檢查數據
*?語言:????????????????????????用不同的語言來使用GDB
*?符號:?????????????????????????檢查符號表
*?更改:?????????????????????????更改執行
*?GDB的文件?????????????????????文件
*?對象??????????????????????????指定調試對象
*?控制GDB???????????????????????控制
*?執行序列:????????????????????執行一序列命令
*?Emacs:????????????????????????使GDB和Emacs一起工作
*?GDB的bug:
*?命令行編輯:??????????????????行編輯
*?使用歷史記錄交互:
*?格式化文檔:??????????????????如何格式化和打印GDB文檔

*?索引:

GDB簡介:
**************

???調試器(比如象GDB)能讓你觀察另一個程序在執行時的內部活動,或程序出錯時
發生了什么。
???GDB主要能為你做四件事(包括為了完成這些事而附加的功能),幫助你找出程序
中的錯誤。
???*?運行你的程序,設置所有的能影響程序運行的東西。

???*?保證你的程序在指定的條件下停止。

???*?當你程序停止時,讓你檢查發生了什么。

???*?改變你的程序。那樣你可以試著修正某個bug引起的問題,然后繼續查找另一
?????個bug.

???你可以用GDB來調試C和C++寫的程序。(參考?*C?和C++)


???調試Pascal程序時,有一些功能還不能使用。

??GDB還可以用來調試FORTRAN程序,盡管現在還不支持表達式的輸入,輸出變量,
或類FORTRAN的詞法。
*?GDB是"free?software",大家都可以免費拷貝。也可以為GDB增加新的功能,不
過可要遵守GNU的許可協議幺。反正我認為GNU還是比較不錯的:-)
就這句話:
???Fundamentally,?the?General?Public?License?is?a?license?which?says
that?you?have?these?freedoms?and?that?you?cannot?take?these?freedoms
away?from?anyone?else.
GDB的作者:
???Richard?Stallman是GDB的始作俑者,另外還有許多別的GNU的成員。許多人
為此作出了貢獻。(都是老外不提也罷,但愿他們不要來找我麻煩:-))

這里是GDB的一個例子:
????????原文中是使用一個叫m4的程序。但很遺憾我找不到這個程序的原代碼,
所以沒有辦法來按照原文來說明。不過反正是個例子,我就拿一個操作系統的
進程調度原碼來說明把,原代碼我會附在后面。
????????首先這個程序叫os.c是一個模擬進程調度的原程序(也許是個老古董了:-))。
先說明一下如何取得包括原代碼符號的可執行代碼。大家有心的話可以去看一下gcc的
man文件(在shell下打man?gcc)。gcc?-g?<原文件.c>?-o?<要生成的文件名>
-g?的意思是生成帶原代碼調試符號的可執行文件。
-o?的意思是指定可執行文件名。
(gcc?的命令行參數有一大堆,有興趣可以自己去看看。)
反正在linux下把os.c用以上方法編譯連接以后就產生了可供gdb使用的可執行文件。
我用gcc?-g?os.c?-o?os,產生的可執行文檔叫os.
然后打gdb?os,就可進入gdb,屏幕提示:
?????GDB?is?free?software?and?you?are?welcome?to?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.

?????GDB?4.16,?Copyright?1995?Free?Software?Foundation,?Inc...
?(gdb)
??(gdb)是提示符,在這提示符下可以輸入命令,直到退出。(退出命令是q/Q)
為了盡量和原文檔說明的命令相符,即使在本例子中沒用的命令我也將演示。
首先我們可以設置gdb的屏幕大小。鍵入:
?(gdb)set?width?70
就是把標準屏幕設為70列。
??然后讓我們來設置斷點。設置方法很簡單:break或簡單打b后面加行號或函數名
比如我們可以在main?函數上設斷點:
?(gdb)break?main
或(gdb)b?main
?系統提示:Breakpoint?1?at?0x8049552:?file?os.c,?line?455.
?然后我們可以運行這個程序,當程序運行到main函數時程序就會停止返回到gdb的
提示符下。運行的命令是run或r(gdb中有不少alias,可以看一下help,在gdb下打help)
run?后面可以跟參數,就是為程序指定命令行參數。
比如r?abcd,則程序就會abcd以作為參數。(這里要說明的是可以用set?args來指定參
數)。打入r或run后,程序就開始運行直到進入main的入口停止,顯示:
Starting?program:?<路徑>/os

Breakpoint?1,?main?()?at?os.c:455
455????????????Initial();
這里455?Initial();是將要執行的命令或函數。
gdb提供兩種方式:1.單步進入,step?into就是跟蹤到函數內啦。命令是step或s
?????????????????2.單步,next,就是簡單的單步,不會進入函數。命令是next或n
這兩個命令還有別的用法以后再說。
我們用n命令,鍵入:
(gdb)n
Success?forking?process#?1?,pid?is?31474

Success?forking?process#?2?,pid?is?31475

Success?forking?process#?3?,pid?is?31476


Success?forking?process#?5?,pid?is?31478

Success?forking?process#?6?,pid?is?31479

????????????????Dispatching?Algorithm?:?FIFO
********************************************************************************

????????????PCB#????????PID?????Priority????????PC??????State
????????????1???????????31474??????24????????????0??????WAITING
????????????2???????????31475??????19????????????0??????WAITING
????????????3???????????31476??????16????????????0??????WAITING
????????????4???????????31477??????23????????????0??????WAITING
????????????5???????????31478??????22????????????0??????WAITING
????????????6???????????31479??????20????????????0??????WAITING

******************************************************************************

CPU??:??NO?process?running
IO?:??No?process
Waiting?CPU!!!??31474???31475???31476???31477???31478???31479
Waiting??IO????NONE
456????????????State=WAITING;
最后的一行就是下一句要執行的命令。我們現在在另一個函數上加斷點。注意我們
可以用l/list命令來顯示原代碼。這里我們鍵入
(gdb)l
451?????main()
452?????{
453?????????????int?message;
454
455????????????Initial();
456????????????State=WAITING;
457????????????printf("Use?Control-C?to?halt?/n");
458????????????signal(SIGALRM,AlarmMessage);
459????????????signal(SIGINT,InteruptMessage);
460????????????signal(SIGUSR2,IoMessage);
(gdb)?l
461????????????alarm(TimeSlot);
462????????????for(;;)
463?????????????{
464?????????????message=GetMessage();
465???????????????????switch(message)
466?????????????????????{

468?????????????????????????????????????????????????????break;
469?????????????????????????????case?CHILD_IO:??????????WaitingIo();
470?????????????????????????????????????????????????????break;
顯示了原代碼,現在在AlarmMessage上加斷點。
(gdb)?b?AlarmMessage
Breakpoint?2?at?0x8048ee3:?file?os.c,?line?259.
(gdb)
然后我們繼續運行程序。
(gdb)c
c或continue命令讓我們繼續被中斷的程序。?顯示:
Continuing.
Use?Control-C?to?halt

Breakpoint?2,?AlarmMessage?()?at?os.c:259
259?????????????ClearSignal();
注意我們下一句語句就是ClearSignal();
我們用s/step跟蹤進入這個函數看看它是干什么的。
(gdb)?s
ClearSignal?()?at?os.c:227
227?????????????signal(SIGINT,SIG_IGN);
用l命令列出原代碼:
(gdb)?l
222?????}
223
224
225?????void?ClearSignal()????/*?Clear?other?signals?*/
226?????{
227?????????????signal(SIGINT,SIG_IGN);
228?????????????signal(SIGALRM,SIG_IGN);
229?????????????signal(SIGUSR2,SIG_IGN);
230?????}
231
(gdb)
我們可以用s命令繼續跟蹤。現在讓我們來試試bt或backtrace命令。這個命令可以
顯示棧中的內容。
(gdb)?bt
#0??ClearSignal?()?at?os.c:227
#1??0x8048ee8?in?AlarmMessage?()?at?os.c:259
#2??0xbffffaec?in????()
#3??0x80486ae?in?___crt_dummy__?()
(gdb)
大家一定能看懂顯示的意思。棧頂是AlarmMessage,接下來的函數沒有名字--就是
沒有原代碼符號。這顯示了函數調用的嵌套。
好了,我們跟蹤了半天還沒有檢查過變量的值呢。檢查表達式的值的命令是p或print
格式是p?<表達式>
444444讓我們來找一個變量來看看。:-)
(gdb)l?1
還記得l的作用嗎?l或list顯示原代碼符號,l或list加<行號>就顯示從<行號>開始的
原代碼。好了找到一個讓我們來看看WaitingQueue的內容
(gdb)?p?WaitingQueue
$1?=?{1,?2,?3,?4,?5,?6,?0}
(gdb)
WaitingQueue是一個數組,gdb還支持結構的顯示,
(gdb)?p?Pcb
$2?=?{{Pid?=?0,?State?=?0,?Prior?=?0,?pc?=?0},?{Pid?=?31474,?State?=?2,
????Prior?=?24,?pc?=?0},?{Pid?=?31475,?State?=?2,?Prior?=?19,?pc?=?0},?{
????Pid?=?31476,?State?=?2,?Prior?=?16,?pc?=?0},?{Pid?=?31477,?State?=?2,
????Prior?=?23,?pc?=?0},?{Pid?=?31478,?State?=?2,?Prior?=?22,?pc?=?0},?{
????Pid?=?31479,?State?=?2,?Prior?=?20,?pc?=?0}}
(gdb)
這里可以對照原程序看看。
原文檔里是一個調試過程,不過我想這里我已經把gdb的常用功能介紹了一遍,基本上
可以用來調試程序了。:-)

運行GDB(一些詳細的說明):

??前面已經提到過如何運行GDB了,現在讓我們來看一些更有趣的東西。你可以在運行
GDB時通過許多命令行參數指定大量的參數和選項,通過這個你可以在一開始就設置好
程序運行的環境。
??這里將要描述的命令行參數覆蓋了大多數的情況,事實上在一定環境下有的并沒有
什么大用處。最通常的命令就是使用一個參數:
?$gdb?<可執行文檔名>
你還可以同時為你的執行文件指定一個core文件:
?$gdb?<可執行文件名>?core
你也可以為你要執行的文件指定一個進程號:
?$gdb?<可執行文件名>?<進程號>?如:&gdb?os?1234將使gdb與進程1234相聯系(attach)
除非你還有一個文件叫1234的。gdb首先檢查一個core文件。
如果你是使用一個遠程終端進行遠程調試的話,那如果你的終端不支持的話,你將無法
使用第二個參數甚至沒有core?dump。如果你覺得開頭的提示信息比較礙眼的話,你可以
用gdb?-silent。你還可以用命令行參數更加詳細的控制GDB的行為。
打入gdb?-help或-h?可以得到這方面的提示。所有的參數都被按照排列的順序傳給gdb
除非你用了-x參數。
??當gdb開始運行時,它把任何一個不帶選項前綴的參數都當作為一個可執行文件或core
文件(或進程號)。就象在前面加了-se或-c選項。gdb把第一個前面沒有選項說明的參數
看作前面加了-se?選項,而第二個(如果有的話)看作是跟著-c選項后面的。
??許多選項有縮寫,用gdb?-h可以看到。在gdb中你也可以任意的把選項名掐頭去尾,只
要保證gdb能判斷唯一的一個參數就行。
在這里我們說明一些最常用的參數選項
-symbols?<文件名>(-s?<文件名>)------從<文件名>中讀去符號。
-exec?<文件名>(-e?<文件名>)----在合適的時候執行<文件名>來做用正確的數據與core
?dump的作比較。
-se?<文件名>------從<文件名>中讀取符號并把它作為可執行文件。
-core?<文件名>(-c?<文件名>)--指定<文件名>為一個core?dump?文件。
-c?<數字>----連接到進程號為<數字>,與attach命令相似。
-command?<文件名>
-x?<文件名>-----執行gdb命令,在<文件名>指定的文件中存放著一序列的gdb命令,就
象一個批處理。
-directory(-d)?<路徑>---指定路徑。把<路徑>加入到搜索原文件的路徑中。
-m
-mapped----
???注意這個命令不是在所有的系統上都能用。如果你可以通過mmap系統調用來獲得內存
映象文件,你可以用這個命令來使gdb把你當前文件里的符號寫入一個文件中,這個文件
將存放在你的當前路徑中。如果你調試的程序叫/temp/fred那么map文件就叫
./fred.syms這樣當你以后再調試這個程序時,gdb會認識到這個文件的存在,從而從這
個文件中讀取符號,而不是從可執行文件中讀取。.syms與主機有關不能共享。
-r
-readnow---馬上從符號文件中讀取整個符號表,而不是使用缺省的。缺省的符號表是
調入一部分符號,當需要時再讀入一部分。這會使開始進入gdb慢一些,但可以加快以后
的調試速度。

?-m和-r一般在一起使用來建立.syms文件


接下來再談談模式的設置(請聽下回分解?:-))
附:在gdb文檔里使用的調試例子我找到了在minix下有這個程序,叫m4有興趣的
可以自己去看看


模式的選擇
--------------
現在我們來聊聊gdb運行模式的選擇。我們可以用許多模式來運行gdb,例如在“批模式”
或“安靜模式”。這些模式都是在gdb運行時在命令行作為選項指定的。
`-nx'
`-n'
?????不執行任何初始化文件中的命令。(一般初始化文件叫做`.gdbinit').一般情況下在

`-quiet'
`-q'
?????“安靜模式”。不輸出介紹和版權信息。這些信息在“批模式”中也被跳過。

`-batch'
?????“批模式”。在“批模式”下運行。當在命令文件中的所有命令都被成功的執行后
?????gdb返回狀態“0”,如果在執行過程中出錯,gdb返回一個非零值。
?????“批模式”在把gdb作為一個過濾器運行時很有用。比如在一臺遠程計算機上下載且
?????執行一個程序。信息“?Program?exited?normally”(一般是當運行的程序正常結束
?????時出現)不會在這種模式中出現。
`-cd?DIRECTORY'
?????把DIRECTORY作為gdb的工作目錄,而非當前目錄(一般gdb缺省把當前目錄作為工作目
?????錄)。
`-fullname'
`-f'
?????GNU?Emacs?設置這個選項,當我們在Emacs下,把gdb作為它的一個子進程來運行時,
?????Emacs告訴gdb按標準輸出完整的文件名和行號,一個可視的棧內容。這個格式跟在
?????文件名的后面。行號和字符重新按列排,Emacs-to-GDB界面使用/032字符作為一個
?????顯示一頁原文件的信號。
`-b?BPS'
?????為遠程調試設置波特率。

`-tty?DEVICE'
?????使用DEVICE來作為你程序的標準輸入輸出。

(gdb) q
The program is running. Exit anyway? (y or n) y

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/454056.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/454056.shtml
英文地址,請注明出處:http://en.pswp.cn/news/454056.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

課后作業-閱讀任務-閱讀提問-3

1.如果兩個人合作的始終達不到規范階段該怎如何處理&#xff1f; 2. 邏輯和界面設計要注意哪些因素&#xff1f;轉載于:https://www.cnblogs.com/fhycm/p/7866548.html

ride上點擊用例不能顯示edit信息_接口測試平臺代碼實現61: 多接口用例1

終于又序更上了&#xff0c;原諒最近作者幾天事情不斷。按照我們之前的計劃&#xff0c;需要迅速開啟很重要的核心多用例接口。首先&#xff0c;我們要確定&#xff0c;這個功能的大體設計。就放在在我們的頁面 用例庫 中&#xff1a;所以也就是我們很久之前就創建好的P_cases.…

黑客攻防專題八:21種RING的提權方法

好多都沒有成功&#xff0c;還是發來看看&#xff0c;看看思路&#xff0c;呵呵 以下全部是本人提權時候的總結 很多方法至今沒有機會試驗也沒有成功&#xff0c;但是我是的確看見別人成功過的。本人不才&#xff0c;除了第一種方法自己研究的&#xff0c;其他的都是別人的經驗…

Linux 狀態命令之內存狀態 free

簡介 free指令會顯示內存的使用情況&#xff0c;包括實體內存&#xff0c;虛擬的交換文件內存&#xff0c;共享內存區段&#xff0c;以及系統核心使用的緩沖區等。 語法 free [-bkmotV][-s <間隔秒數>]參數說明&#xff1a;-b  以Byte為單位顯示內存使用情況。-k  以…

SpringMVC在使用Jackson2時關于日期類型格式化的問題

*本例程序使用Jackson2.9.0&#xff0c;jackson1.x的處理方式稍稍有些不同。 在基于Spring&SpringMVC的Web項目中&#xff0c;我們常使用Jackson(1.x/2.x)來增加程序對Json格式的數據的支持。 因此&#xff0c;在實際應用中有個常見的需求&#xff1a;日期的格式化。 假設&…

GDB 使用——Linux C編程

簡述 一 列文件清單 二&#xff1a;執行程序 三&#xff1a;顯示數據 四&#xff1a;斷點(breakpoint) 五&#xff0e;斷點的管理 六&#xff0e;變量的檢查和賦值 七. 單步執行 八&#xff0e;函數的調用 九&#xff0e;機器語言工具 …

python撥號_python 撥號代碼(win10 系統親測有效)

# -*- coding: utf-8 -*-import win32rasimport time,osdef Connect(dialname, account, passwd):dial_params (dialname, , , account, passwd, )return win32ras.Dial(None, None, dial_params, None)def DialBroadband():dialname u寬帶連接 #just a nameaccount u059291…

HP服務器引導盤下載地址

HP SmartStart CD 8.7 x32版本的下載地址為&#xff1a;http://ftp.hp.com/pub/softlib2/software1/cd/p1040463476/v63549/smartstart-8.70-0-x86.zip HP SmartStart CD 8.7 x32版本支持以下機型&#xff1a; HP ProLiant ML 和 DL 300、500 和 700 系列以及 HP ProLiant BL S…

MUI - 預加載

打開詳情頁回到頂部:document.body.scrollTop document.documentElement.scrollTop 0;方式一&#xff1a;preload一次僅能預加載一個頁面&#xff08;除非循環&#xff09; var subWebview mui.preload({url: examples/accordion.html,id: template_sub,top: styles: {48 …

python 分類變量xgboost_【轉】XGBoost參數調優完全指南(附Python代碼)

xgboost入門非常經典的材料&#xff0c;雖然讀起來比較吃力&#xff0c;但是會有很大的幫助&#xff1a;英文原文鏈接:https://www.analyticsvidhya.com/blog/2016/03/complete-guide-parameter-tuning-xgboost-with-codes-python/

用 GDB 調試Linux程序及有用技巧

用 GDB 調試Linux程序及有用技巧(轉) armlinux 2008-06-19 10:48 閱讀91 評論0 字號&#xff1a; 大大 中中 小小 GNU的調試器稱為gdb&#xff0c;該程序是一個交互式工具&#xff0c;工作在字符模式。在 X Window 系統中&#xff0c;有一個gdb的前端圖形工具…

Bash : 索引數組

Bash 提供了兩種類型的數組&#xff0c;分別是索引數組(indexed array)和關聯數組(associative array)。本文主要介紹索引數組的基本用法。 索引數組的基本特點 Bash 提供的數組都是一維數組。任何變量都可以用作索引數組。通過 declare 關鍵字可以顯式的聲明一個索引數組。數組…

Flask 第三方組件之 login

在了解使用Flask來實現用戶認證之前&#xff0c;我們首先要明白用戶認證的原理。假設現在我們自己去實現用戶認證&#xff0c;需要做哪些事情呢&#xff1f; 首先&#xff0c;登錄。用戶能夠輸入用戶名和密碼進行登錄&#xff0c;所以需要網頁和表單&#xff0c;實現用戶輸入和…

Zookeeper客戶端Curator使用詳解

http://www.jianshu.com/p/70151fc0ef5dZookeeper客戶端Curator使用詳解 簡介 Curator是Netflix公司開源的一套zookeeper客戶端框架&#xff0c;解決了很多Zookeeper客戶端非常底層的細節開發工作&#xff0c;包括連接重連、反復注冊Watcher和NodeExistsException異常等等。Pat…

python argparse nargs_Python | 使用argparse解析命令行參數

今天是Python專題第27篇文章&#xff0c;我們來聊聊Python當中的命令行參數工具argparse。命令行參數工具是我們非常常用的工具&#xff0c;比如當我們做實驗希望調節參數的時候&#xff0c;如果參數都是通過硬編碼寫在代碼當中的話&#xff0c;我們每次修改參數都需要修改對應…

Python 第三方模塊之 smtplib

1 python對SMTP的支持 SMTP&#xff08;Simple Mail Transfer Protocol&#xff09;是簡單傳輸協議&#xff0c;它是一組用于用于由源地址到目的地址的郵件傳輸規則。 python中對SMTP進行了簡單的封裝&#xff0c;可以發送純文本郵件、HTML郵件以及帶附件的郵件。兩個核心模塊…

Node.js 使用jQuery取得Nodejs http服務端返回的JSON對象示例

server.js代碼&#xff1a; // 內置http模塊&#xff0c;提供了http服務器和客戶端功能&#xff08;path模塊也是內置模塊&#xff0c;而mime是附加模塊&#xff09; var httprequire("http");// 創建服務器,創建HTTP服務器要調用http.createServer()函數&#xff0c…

linux下gdb單步調試

用 GDB調試程序 GDB 概述 ———— GDB 是 GNU開源組織發布的一個強大的 UNIX下的程序調試工具。或許&#xff0c;各位比較喜歡那種圖形界面方式的&#xff0c;像 VC、 BCB等 IDE的調試&#xff0c;但如果你是在 UNIX平臺下做軟件&#xff0c;你會發現 GDB這個調試工具有比 V…

svg 動畫_根據AI導出的SVG path制作SVG線條動畫

點擊右上方紅色按鈕關注“web秀”&#xff0c;讓你真正秀起來前言首先祝大家2019新年快樂&#xff0c;萬事大吉&#xff0c;豬事順利&#xff0c;闔家歡樂。前面文章SVG 線條動畫基礎入門知識學習到了基礎知識&#xff0c;現在來給大家講講如何制作SVG 制作復雜圖形線條動畫。假…

MySQL提示Truncated incorrect DOUBLE value解決方法

“Truncated incorrect DOUBLE value”的解決方法主要是這兩種&#xff1a; 1、修改了多個列的值而各列之間用逗號連接而不要用and 錯誤寫法示例&#xff1a;update tablename set col1value1 and col2value2 where col3value3&#xff1b;正確寫法示例&#xff1a;update ta…