Octave 中內建有專門用於開發程式的除錯工具,此除錯工具可以用來暫停指令稿的執行,進入除錯模式,並讓開發者查看目前符號表中的變數值,檢查是否有錯誤。在除錯模式中也支援一般的命令列編輯與歷史紀錄。
在 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 的輸出,只會顯示最上層的錯誤訊息。
要離開 Octave 的除錯模式可以使用 dbcont()
或 return()
函數。
dbcont ()
dbcont()
函數可以離開除錯模式繼續執行原來的程式,適用於除錯模式中。
若是在除錯模式中要終止程式執行,直接回到命令列,可以使用 dbquit()
函數。
dbquit ()
dbquit()
函數可以離開除錯模式並終止原來的程式,回到最上層的命令列,適用於除錯模式中。
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 會輸出一個提示符號,等待使用者輸入指令,輸入的指令會被執行,然後輸出執行結果,這樣可以讓使用者在中斷函數執行時,檢查或更改變數中的值。若要離開這個提示符號,可以使用 return
或 dbcont
命令。keyboard()
函數不會傳回離開的狀態值。prompt
參數可以指定提示符號,若省略則預設為 'debug> '
。
在 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 繼續執行直到跳出目前的函數為止。
[stack, idx] = dbstack (n)
dbstack()
函數會傳回目前的堆疊資訊,若指定參數 n
則會忽略 n
個最內層的堆疊。
dbup (n)
在除錯模式中呼叫 dbup(n)
函數會往上跳出 n
個堆疊,若省略參數 n
則跳到上一個堆疊。
dbdown (n)
在除錯模式中呼叫 dbdown(n)
函數會往下跳入 n
個堆疊,若省略參數 n
則跳到下一個堆疊。