Hexagon GDB Debugger介紹(5)
-
-
- 2.5.4 shell 指令
- 2.5.5 Tcl 腳本
- 2.5.6 記錄輸出
- 2.5.7 獲得幫助
- 2.5.8 示例調試會話
-
2.5.4 shell 指令
如果你需要在調試會話期間偶爾執行 shell 指令,則無需離開或暫停調試器; 相反,你可以使用 shell 指令。
shell 指令字元串
調用标準 shell 來執行 command_string。 如果存在,環境變量 SHELL 決定運作哪個 shell。 否則,調試器将使用預設 shell(例如,UNIX 系統上的 /bin/sh)。
在開發環境中經常需要實用程式 make。 為此,你不必使用 shell 指令。 例如:
make make_args
… 使用指定的參數執行 make 程式。 這相當于“shell make make_args”。
2.5.5 Tcl 腳本
調試器可選擇支援使用 Tcl 腳本語言。 可以使用 set 指令啟用 Tcl 腳本。
set tclfe on
啟用 Tcl 腳本(第 4.4 節)。
注意
啟用腳本會影響 GDB 指令縮寫(第 2.5.1 節)
2.5.6 記錄輸出
你可能希望将調試器指令的輸出儲存到檔案中。 有幾個指令可以控制日志記錄。
指令 | 描述 |
---|---|
set logging on | 啟用日志記錄。 |
set logging off | 禁用日志記錄。 |
set logging file file | 更改目前日志檔案的名稱。 預設日志檔案是 gdb.txt。 |
set logging overwrite [on|off] | 預設情況下,調試器會将新的日志資訊附加到日志檔案中。 如果你希望将登入設定為覆寫日志檔案,請設定覆寫。 |
set logging redirect [on|off] | 預設情況下,調試器輸出同時寫入終端和日志檔案。 如果你隻想輸出到日志檔案,請設定重定向。 |
show logging | 顯示日志設定的目前值。 |
2.5.7 獲得幫助
你始終可以使用指令幫助向調試器詢問有關其指令的資訊。
指令 | 描述 |
---|---|
help / h | 可以使用不帶參數的幫助(縮寫為 h)來顯示命名指令類的簡短清單。 |
help class | 使用通用幫助類之一作為參數,可以獲得該類中各個指令的清單。 例如,這裡是class狀态的幫助顯示: |
(hexagon-gdb) help status
狀态查詢。
指令清單:
info -- 用于顯示有關正在調試的程式的資訊的通用指令
show -- 用于顯示有關調試器的内容的通用指令
鍵入“help”後跟指令名稱以擷取完整文檔。
如果沒有歧義,則允許使用指令名稱縮寫。
指令 | 描述 |
---|---|
help command | 使用指令名稱作為幫助參數,顯示關于如何使用該指令的簡短段落。 |
apropos command_expr | apropos 指令在所有調試器指令及其相應文檔中搜尋 command_expr 中指定的正規表達式。 它列印出找到的所有比對項。 例如: |
apropos reload
... 結果是:
set symbol-reloading -- 在一次運作中設定動态符号表重新加載多次
show symbol-reloading -- 在一次運作中顯示多次重新加載的動态符号表
指令 | 描述 |
---|---|
complete command_string | complete 指令列出了指令開頭的所有可能的補全。 使用 command_string 指定要完成的指令的開頭。 例如: |
complete i
... results in:
if
ignore
info
inspec
NOTE complete 旨在供 GNU Emacs 使用。
除了幫助之外,還可以使用指令 info 和 show 來查詢程式的狀态或調試器本身的狀态。 每個指令支援多個查詢主題; 本手冊在适當的上下文中介紹了它們中的每一個。
指令 | 描述 |
---|---|
info | 此指令(縮寫為 i)用于描述程式的狀态。 例如,可以使用 info args 列出給你的程式的參數,使用 info registers 列出目前正在使用的寄存器,或者列出你使用 info breakpoints 設定的斷點。 你可以通過幫助資訊擷取資訊子指令的完整清單。 |
set | 你可以使用 set 将表達式的結果配置設定給環境變量。 例如,你可以使用 set prompt $ 将調試器提示設定為 $-sign。 |
show | 與 info 不同,show 用于描述調試器本身的狀态。 通過使用相關的指令集,你可以更改你可以顯示的大部分内容; 例如,你可以使用 set radix 控制顯示使用的數字系統,或者隻需使用 show radix 查詢目前正在使用的數字系統。 要顯示所有可設定的參數及其目前值,你可以使用不帶參數的 show; 你也可以使用資訊集。 這兩個指令産生相同的顯示。 |
以下是三個雜項 show 子指令,所有這些子指令都缺少相應的 set 指令:
指令 | 描述 |
---|---|
show version | 顯示正在運作的調試器版本。 |
show copying | 顯示有關複制調試器的權限的資訊。 |
show warranty | 顯示 GNU “NO WARRANTY”聲明或保證(如果你的調試器版本附帶有)。 |
2.5.8 示例調試會話
本節提供了一個示例調試會話,它示範了基本的調試器指令。
gnu m4(一種通用宏處理器)的一個初步版本顯示出以下錯誤:有時,當我們從預設值更改其引号字元串時,用于捕獲另一個宏定義中的指令的指令會停止工作。 在以下簡短的 m4 會話中,我們定義了一個宏 foo,它擴充為 0000; 然後我們使用 m4 内置的 defn 将 bar 定義為相同的東西。 但是,當我們将左引号字元串更改為 并将關閉引号字元串更改為 時,相同的過程無法定義新的同義詞 baz:
$ cd gnu/m4
$ ./m4
define(foo,0000)
foo
0000
define(bar,defn(’foo’))
bar
0000
changequote(<QUOTE>,<UNQUOTE>)
define(baz,defn(<QUOTE>foo<UNQUOTE>))
baz
Ctrl-d
m4: End of input: 0: fatal error: EOF in string
要查找 m4 中的錯誤,請啟動調試器:
$ hexagon-gdb
Copyright 2004 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.
(hexagon-gdb)
調試器隻讀取足夠的符号資料,以便在需要時知道在哪裡可以找到其餘的; 結果,第一個提示出現得非常快。 我們現在告訴它使用比平時更窄的顯示寬度,以便示例适合本手冊。
(hexagon-gdb) set width 70
我們需要看看 m4 内置的 changequote 是如何工作的。 檢視源代碼後,我們知道相關子程式是 m4_changequote,是以我們使用 break 指令在那裡設定了一個斷點。
(hexagon-gdb) break m4_changequote
Breakpoint 1 at 0x62f4: file builtin.c, line 879.
使用 run 指令,我們啟動 m4 在調試器的控制下運作; 隻要控制沒有到達 m4_changequote 子程式,程式就照常運作:
(hexagon-gdb) run
Starting program: /work/Editorial/gdb/gnu/m4/m4
define(foo,0000)
foo
0000
為了觸發斷點,我們調用changequote。 調試器暫停 m4 的執行,顯示有關它停止的上下文的資訊。
changequote(<QUOTE>,<UNQUOTE>)
Breakpoint 1, m4_changequote (argc=3, argv=0x33c70)
at builtin.c:879
879 if (bad_argc(TOKEN_DATA_TEXT(argv[0]),argc,1,3))
現在我們使用指令 n (next) 将執行推進到目前函數的下一行。
(hexagon-gdb) n
882 set_quotes((argc >= 2) ? TOKEN_DATA_TEXT(argv[1])\
: nil,
set_quotes 看起來像是一個很有前途的子程式。 我們可以使用指令 s (step) 而不是 next 來進入它。 step 轉到要在任何子例程中執行的下一行,是以它步入 set_quotes。
(hexagon-gdb) s
set_quotes (lq=0x34c78 "<QUOTE>", rq=0x34c88 "<UNQUOTE>")
at input.c:530
530 if (lquote != def_lquote)
顯示 m4 現在挂起的子程式(及其參數)的顯示稱為堆棧幀顯示。 它顯示了堆棧的摘要。 我們可以使用 backtrace 指令(也可以拼寫為 bt)來檢視我們在整個堆棧中的位置:backtrace 指令顯示每個活動子程式的堆棧幀。
(hexagon-gdb) bt
#0 set_quotes (lq=0x34c78 "<QUOTE>", rq=0x34c88 "<UNQUOTE>")
at input.c:530
#1 0x6344 in m4_changequote (argc=3, argv=0x33c70)
at builtin.c:882
#2 0x8174 in expand_macro (sym=0x33320) at macro.c:242
#3 0x7a88 in expand_token (obs=0x0, t=209696, td=0xf7fffa30)
at macro.c:71
#4 0x79dc in expand_input () at macro.c:40
#5 0x2930 in main (argc=0, argv=0xf7fffb20) at m4.c:195
我們再多走幾行看看會發生什麼。 前兩次,我們可以使用s; 接下來的兩次我們使用 n 來避免陷入 xstrdup 子例程。
(hexagon-gdb) s
0x3b5c 532 if (rquote != def_rquote)
(hexagon-gdb) s
0x3b80 535 lquote = (lq == nil || *lq == ’\0’) ? \
def_lquote : xstrdup(lq);
(hexagon-gdb) n
536 rquote = (rq == nil || *rq == ’\0’) ? def_rquote\
: xstrdup(rq);
(hexagon-gdb) n
538 len_lquote = strlen(rquote);
顯示的最後一行看起來有點奇怪; 我們可以檢查變量 lquote 和 rquote 以檢視它們是否實際上是我們指定的新左引号和右引号。 我們使用指令 p(列印)來檢視它們的值。
(hexagon-gdb) p lquote
$1 = 0x35d40 "<QUOTE>"
(hexagon-gdb) p rquote
$2 = 0x35d50 "<UNQUOTE>"
lquote 和 rquote 确實是新的左右引号。 為了檢視一些上下文,我們可以使用 l (list) 指令顯示圍繞目前行的十行源代碼。
(hexagon-gdb) l
533 xfree(rquote);
534
535 lquote = (lq == nil || *lq == ’\0’) ? def_lquote\
: xstrdup (lq);
536 rquote = (rq == nil || *rq == ’\0’) ? def_rquote\
: xstrdup (rq);
537
538 len_lquote = strlen(rquote);
539 len_rquote = strlen(lquote);
540 }
541
542 void
讓我們跳過設定 len_lquote 和 len_rquote 的兩行,并檢查這些變量的值。
(hexagon-gdb) n
539 len_rquote = strlen(lquote);
(hexagon-gdb) n
540 }
(hexagon-gdb) p len_lquote
$3 = 9
(hexagon-gdb) p len_rquote
$4 = 7
這看起來肯定是錯誤的,假設 len_lquote 和 len_rquote 分别是 lquote 和 rquote 的長度。 我們可以使用 p 指令将變量設定為更好的值,因為它可以列印任何表達式的值,并且該表達式可以包括子例程調用和指派。
(hexagon-gdb) p len_lquote=strlen(lquote)
$5 = 7
(hexagon-gdb) p len_rquote=strlen(rquote)
$6 = 9
這足以解決在 m4 内置 defn 中使用新引号的問題嗎? 我們可以讓 m4 繼續執行 c (continue) 指令,然後嘗試最初出現問題的示例:
(hexagon-gdb) c
Continuing.
define(baz,defn(<QUOTE>foo<UNQUOTE>))
baz
0000
成功! 新報價現在與預設報價一樣有效。 問題似乎隻是定義錯誤長度的兩個拼寫錯誤。 我們通過給它一個 EOF 作為輸入來允許 m4 退出:
Ctrl-d
Program exited normally.
調試器生成的消息“程式正常退出”。 表示 m4 已經執行完畢。 我們可以使用 quit 指令結束我們的調試會話。
(hexagon-gdb) quit