分類: Octave

Octave 除錯(Debugging)

Octave 中內建有專門用於開發程式的除錯工具,此除錯工具可以用來暫停指令稿的執行,進入除錯模式,並讓開發者查看目前符號表中的變數值,檢查是否有錯誤。在除錯模式中也支援一般的命令列編輯與歷史紀錄。

進入除錯模式(Entering Debug Mode)

在 Octave 中有兩種方式可以中斷指令稿的執行,一種是使用中斷點(breakpoints),當程式執行至中斷點時,就會暫停並進入除錯模式(請參考中斷點);而另一種是設定停止條件,在程式在執行期間符合指定的條件時,就會暫停程式的執行而進入除錯模式。

Octave 中有三種停止條件可以使用,分別以 debug_on_interrupt()debug_on_warning()debug_on_error() 函數來設定。

val = debug_on_interrupt ()
old_val = debug_on_interrupt (new_val)

debug_on_interrupt() 函數可以設定與查詢 Octave 是否要在接收到中斷訊號(interrupt signal,通常是 Ctrl + c)時進入除錯模式,若在進入除錯模式之前,又再收到一個中斷訊號,則會依照一般收到中斷訊號的情況處理,也就是中斷程式的執行並離開。

val = debug_on_warning ()
old_val = debug_on_warning (new_val)

debug_on_warning() 函數可以查詢 Octave 是否要在警告產生時時進入除錯模式。

val = debug_on_error ()
old_val = debug_on_error (new_val)

debug_on_error() 函數可以查詢 Octave 是否要在錯誤產生時時進入除錯模式,若設定這個選項同時也會關閉一般的 traceback 的輸出,只會顯示最上層的錯誤訊息。

離開除錯模式(Leaving Debug Mode)

要離開 Octave 的除錯模式可以使用 dbcont()return() 函數。

dbcont ()

dbcont() 函數可以離開除錯模式繼續執行原來的程式,適用於除錯模式中。

若是在除錯模式中要終止程式執行,直接回到命令列,可以使用 dbquit() 函數。

dbquit ()

dbquit() 函數可以離開除錯模式並終止原來的程式,回到最上層的命令列,適用於除錯模式中。

中斷點(Breakpoints)

Octave 的中斷點可以使用 dbstop() 函數設置在任何函數中。

rline = dbstop (func, line, ...)

dbstop() 函數可以在 func 函數中設定中斷點,若在除錯模式中則不用指定 func 參數,只需要指定 line 參數即可; line 參數則是指定中斷點的所在行數,若要指定多個中斷點,可以使用多個參數指定或是使用向量。傳回值 rline 是實際上設定中斷點的行數。

Octave 的中斷點不可以設在內建函數(built-in function,例如:sin() 函數)或是動態載入函數(dynamically loaded function,例如:.oct 檔)中。若要將中斷點設置在函數的開頭,則 line 應設定為 1,開頭的註解部分會自動跳過,實際的中斷點會設置在第一個可以執行的敘述上,例如:

dbstop ("asind", 1)

輸出為

ans =  28

傳回值 28 表示實際的中斷點是設置在第 28 行,一個函數的其斷點的狀態可以由 dbstatus() 函數來查詢。

lst = dbstatus (func)

dbstatus(func) 函數可以傳回 func 函數中所有中斷點的行數,若在除錯模式中則不用加入 func 參數。例如上面所加入的中斷點可以這樣查詢:

dbstop ("asind", 31);
dbstatus ("asind")

輸出為

Breakpoint in asind at line(s) 31.
dbclear (func, line, ...)

dbclear() 函數可以清除 func 函數中的中斷點,若在除錯模式中則不用加入 func 參數,line 參數可以指定要移除的中斷點的行數,若要指定多個中斷點,可以使用多個參數指定或是使用向量。

Octave 並不會檢查所指定的行數是否真的有中斷點,若指定錯誤的行號,則 Octave 會直接忽略。

下面的範例可以移除一個函數中所有的中斷點:

dbclear ("asind", dbstatus ("asind"));

中斷點亦可設置在子函數內,假設一個函數檔案的內容為:

function y = func1 (x)
  y = func2 (x);
endfunction
function y = func2 (x)
  y = x + 1;
endfunction

在子函數中設置一個中斷點:

dbstop (["func1", filemarker(), "func2"])

輸出為

ans =  5

其中 filemarker() 函數會輸出一個用於分隔檔案名稱與子函數的分隔符號,藉由這樣的方式可以指定檔案中的子函數。

另一種指定中斷點的方式是使用 keyboard() 函數。

keyboard ()
keyboard (prompt)

keyboard() 函數是專門用於除錯的函數,當執行此函數時,Octave 會輸出一個提示符號,等待使用者輸入指令,輸入的指令會被執行,然後輸出執行結果,這樣可以讓使用者在中斷函數執行時,檢查或更改變數中的值。若要離開這個提示符號,可以使用 returndbcont 命令。keyboard() 函數不會傳回離開的狀態值。prompt 參數可以指定提示符號,若省略則預設為 'debug> '

除錯模式(Debug Mode)

在 Octave 除錯模式中有兩個函數可以查詢在進入除錯模式前,程式執行的位置,並顯示出附近的程式碼。

dbwhere ()

dbwhere() 函數會顯示在進入除錯模式前,程式執行的位置。

dbtype ()

dbtype() 函數會輸出加入行號後的函數檔案內容。

若要判斷除錯模式是否正在執行,可以使用 isdebugmode() 函數。

isdebugmode ()

isdebugmode() 函數會判斷除錯模式是否正在執行,若正在執行則傳回 true,否則傳回 false

dbstep n
dbstep in
dbstep out

在除錯模式中執行 dbstep n 可以讓 Octave 向下執行 n 行程式碼,若省略參數 n 則會執行下一行程式碼。若下一行指令是定義在另外一個檔案中,則會依然停留在目前這個檔案中。

在除錯模式中執行 dbstep in 會執行下一行程式碼,並進入下一行程式碼所在的檔案中。dbstep out 會讓 Octave 繼續執行直到跳出目前的函數為止。

呼叫堆疊(Call Stack)

[stack, idx] = dbstack (n)

dbstack() 函數會傳回目前的堆疊資訊,若指定參數 n 則會忽略 n 個最內層的堆疊。

dbup (n)

在除錯模式中呼叫 dbup(n) 函數會往上跳出 n 個堆疊,若省略參數 n 則跳到上一個堆疊。

dbdown (n)

在除錯模式中呼叫 dbdown(n) 函數會往下跳入 n 個堆疊,若省略參數 n 則跳到下一個堆疊。

G. T. Wang

個人使用 Linux 經驗長達十餘年,樂於分享各種自由軟體技術與實作文章。

Share
Published by
G. T. Wang
標籤: 數學

Recent Posts

光陽 KYMCO GP 125 機車接電發動、更換電瓶記錄

本篇記錄我的光陽 KYMCO ...

2 年 ago

[開箱] YubiKey 5C NFC 實體金鑰

本篇是 YubiKey 5C ...

3 年 ago

[DIY] 自製竹火把

本篇記錄我拿竹子加上過期的苦茶...

3 年 ago