模組 Stdlib.Printexc

module Printexc: Printexc

type t = exn = ..

例外值 (exception values) 的類型。

val to_string : exn -> string

Printexc.to_string e 會回傳例外 e 的字串表示。

val to_string_default : exn -> string

Printexc.to_string_default e 會回傳例外 e 的字串表示,忽略所有已註冊的例外印表機。

val print : ('a -> 'b) -> 'a -> 'b

Printexc.print fn xfn 應用於 x 並回傳結果。如果 fn x 的評估引發任何例外,則會在標準錯誤輸出上印出例外的名稱,並再次引發該例外。典型的用法是捕獲並報告逃脫函數應用程式的例外。

val catch : ('a -> 'b) -> 'a -> 'b
已棄用。此函式不再需要。

Printexc.catch fn x 類似於 Printexc.print,但在印出未捕獲的例外後,會以退出代碼 2 中止程式。此函式已被棄用:現在執行階段系統能夠像 Printexc.catch 一樣精確地印出未捕獲的例外。此外,呼叫 Printexc.catch 會使得使用除錯器或堆疊回溯工具追蹤例外的位置變得更加困難。因此,請勿在新程式碼中使用 Printexc.catch

val print_backtrace : out_channel -> unit

Printexc.print_backtrace oc 會在輸出通道 oc 上印出例外回溯。回溯會列出最近引發例外的位置,以及例外透過函數呼叫傳播的位置。

如果呼叫不在例外處理常式內,則回傳的回溯未指定。如果在一些例外捕獲程式碼之後(在處理常式中,或在例外處理常式匹配期間的 when-guard 中)呼叫,回溯可能對應於比處理過的例外更晚的例外。

val get_backtrace : unit -> string

Printexc.get_backtrace () 會回傳一個字串,其中包含與 Printexc.print_backtrace 會印出的相同的例外回溯。使用限制與 Printexc.print_backtrace 相同。

val record_backtrace : bool -> unit

Printexc.record_backtrace b 會開啟(如果 b = true)或關閉(如果 b = false)例外回溯的記錄。最初,回溯不會被記錄,除非透過 OCAMLRUNPARAM 變數將 b 旗標提供給程式。

val backtrace_status : unit -> bool

Printexc.backtrace_status() 會在目前記錄例外回溯時回傳 true,否則回傳 false

val register_printer : (exn -> string option) -> unit

Printexc.register_printer fn 會將 fn 註冊為例外印表機。如果印表機不知道如何轉換傳遞的例外,則應回傳 None 或引發例外;如果它可以轉換傳遞的例外,則應回傳 Some
    s
,其中 s 為結果字串。印表機引發的例外將被忽略。

將例外轉換為字串時,將以註冊的反向順序呼叫印表機,直到印表機回傳 Some s 值(如果不存在此類印表機,則執行階段將使用泛型印表機)。

當使用此機制時,應注意例外回溯會附加到看到引發例外的執行緒,而不是附加到例外本身。實際上,這表示如果 fn 相關的程式碼本身之前引發了例外,則不應使用回溯。

val use_printers : exn -> string option

Printexc.use_printers e 如果沒有已註冊的印表機則回傳 None,否則回傳 Some s,其中 s 為結果字串。

原始回溯 (Raw backtraces)

type raw_backtrace 

類型 raw_backtrace 會以低階格式儲存回溯,可以使用下面的 raw_backtrace_entriesbacktrace_slots_of_raw_entry 將其轉換為可用形式。

將回溯轉換為 backtrace_slot 比擷取回溯慢。如果應用程式處理許多回溯,則使用 raw_backtrace 可以避免或延遲轉換。

無法編組 (marshal) 原始回溯。如果需要編組,則應使用下一節的 backtrace_slots 函式回傳的陣列。

type raw_backtrace_entry = private int 

raw_backtrace_entryraw_backtrace 的一個元素。

每個 raw_backtrace_entry 都是不透明的整數,其值在不同程式之間,甚至在同一二進制檔案的不同執行之間都不穩定。

可以使用下面的 backtrace_slots_of_raw_entryraw_backtrace_entry 轉換為可用形式。請注意,由於內嵌,單個 raw_backtrace_entry 可能會轉換為多個 backtrace_slot。由於 raw_backtrace_entry 的值不穩定,因此無法編組它們。如果要轉換它們,則必須由產生它們的程序來完成轉換。

同樣由於內嵌,可能有多個不同的 raw_backtrace_entry 值轉換為相同的 backtrace_slot。但是,如果兩個 raw_backtrace_entry 以整數形式相等,則它們表示相同的 backtrace_slot

val raw_backtrace_entries : raw_backtrace -> raw_backtrace_entry array
val get_raw_backtrace : unit -> raw_backtrace

Printexc.get_raw_backtrace () 會回傳與 Printexc.print_backtrace 會印出的相同的例外回溯,但採用原始格式。使用限制與 Printexc.print_backtrace 相同。

val print_raw_backtrace : out_channel -> raw_backtrace -> unit

以與 Printexc.print_backtrace 使用的相同格式印出原始回溯。

val raw_backtrace_to_string : raw_backtrace -> string

以與 Printexc.get_backtrace 使用的相同格式,從原始回溯回傳字串。

val raise_with_backtrace : exn -> raw_backtrace -> 'a

使用給定的 raw_backtrace 重新引發例外,作為例外的起源

目前呼叫堆疊 (Current call stack)

val get_callstack : int -> raw_backtrace

Printexc.get_callstack n 會回傳目前程式點(對於目前執行緒)的呼叫堆疊頂部的描述,最多 n 個條目。(注意:此函式與例外無關,儘管它是 Printexc 模組的一部分。)

未捕獲的例外 (Uncaught exceptions)

val default_uncaught_exception_handler : exn -> raw_backtrace -> unit

Printexc.default_uncaught_exception_handler 會在標準錯誤輸出上印出例外和回溯。

val set_uncaught_exception_handler : (exn -> raw_backtrace -> unit) -> unit

Printexc.set_uncaught_exception_handler fn 會將 fn 註冊為未捕獲例外的處理常式。預設處理常式為 Printexc.default_uncaught_exception_handler

請注意,當呼叫 fn 時,所有以 at_exit 註冊的函式都已被呼叫。因此,您必須確保 fn 寫入的任何輸出通道都已刷新。

另請注意,互動式 toplevel 中使用者程式碼引發的例外不會傳遞給此函式,因為它們由 toplevel 本身捕獲。

如果 fn 引發例外,則傳遞給 fn 的例外和 fn 引發的例外都會以各自的回溯印出。

回溯資訊的操作 (Manipulation of backtrace information)

這些函式用於遍歷原始回溯的槽,並以程式設計師友善的格式從中提取資訊。

type backtrace_slot 

抽象類型 backtrace_slot 表示回溯的單個槽。

val backtrace_slots : raw_backtrace -> backtrace_slot array option

回傳原始回溯的槽,如果其中沒有任何槽包含有用的資訊,則回傳 None

在回傳陣列中,索引 0 處的槽對應於追蹤中最最近的函數呼叫、引發或原始 get_backtrace 呼叫。

回傳 None 的一些可能原因如下:

  • 追蹤中的任何槽都不來自使用除錯資訊 (-g) 編譯的模組
  • 該程式是未啟用除錯資訊連結的位元組碼程式 (ocamlc -g)
val backtrace_slots_of_raw_entry : raw_backtrace_entry -> backtrace_slot array option

回傳單個原始回溯條目的槽,如果此條目缺少除錯資訊,則回傳 None

槽的回傳順序與 backtrace_slots 相同:索引 0 處的槽是最最近的呼叫、引發或原始呼叫,後續的槽表示呼叫者。

type location = {
   filename : string;
   line_number : int;
   start_char : int;
   end_char : int;
   end_line : int; (*
  • 5.2
*)
   end_col : int; (*
  • 5.2
*)
}

在回溯中找到的位置資訊的類型。start_charend_char 是相對於 line_number 開頭的位置。end_col 是相對於 end_line 開頭的位置。

module Slot: sig .. end

原始回溯槽 (Raw backtrace slots)

type raw_backtrace_slot 

此類型用於反覆運算 raw_backtrace 的槽。對於大多數用途,backtrace_slots_of_raw_entry 更容易使用。

raw_backtrace_entry 類似,此類型的值是特定於程序的,絕對不能編組,並且由於這個原因,使用它們是不安全的(編組它們可能不會失敗,但取消編組和使用結果將導致未定義的行為)。

此類型的元素仍然可以被比較和雜湊:當兩個元素相等時,它們代表相同的原始碼位置(例如,在內聯的情況下,反之則不一定成立)。

val raw_backtrace_length : raw_backtrace -> int

raw_backtrace_length bckt 返回回溯 bckt 中的槽位數量。

val get_raw_backtrace_slot : raw_backtrace -> int -> raw_backtrace_slot

get_raw_backtrace_slot bckt pos 返回回溯 bckt 中位置 pos 的槽位。

val convert_raw_backtrace_slot : raw_backtrace_slot -> backtrace_slot

從低階的 raw_backtrace_slot 中提取使用者友好的 backtrace_slot

val get_raw_backtrace_next_slot : raw_backtrace_slot -> raw_backtrace_slot option

get_raw_backtrace_next_slot slot 返回下一個內聯槽位(如果有的話)。

遍歷所有幀(內聯和非內聯)的範例程式碼

      (* Iterate over inlined frames *)
      let rec iter_raw_backtrace_slot f slot =
        f slot;
        match get_raw_backtrace_next_slot slot with
        | None -> ()
        | Some slot' -> iter_raw_backtrace_slot f slot'

      (* Iterate over stack frames *)
      let iter_raw_backtrace f bt =
        for i = 0 to raw_backtrace_length bt - 1 do
          iter_raw_backtrace_slot f (get_raw_backtrace_slot bt i)
        done
    

例外槽 (Exception slots)

val exn_slot_id : exn -> int

Printexc.exn_slot_id 返回一個整數,該整數唯一識別用於建立例外值 exn 的建構子(在目前的執行時)。

val exn_slot_name : exn -> string

Printexc.exn_slot_name exn 返回用於建立例外值 exn 的建構子的內部名稱。