☰ OCaml 工具
第 15 章 執行期系統 (ocamlrun)
ocamlrun 命令會執行 ocamlc 命令的連結階段所產生的位元組碼檔案。
1 概觀
ocamlrun 命令包含三個主要部分:位元組碼直譯器(實際執行位元組碼檔案)、記憶體配置器和垃圾收集器,以及一組實作基本操作(例如輸入/輸出)的 C 函式。
ocamlrun 的用法為
ocamlrun options bytecode-executable arg 1 ... arg n
第一個非選項的引數會被視為包含可執行位元組碼的檔案名稱。(該檔案會在可執行路徑以及目前目錄中搜尋。)剩餘的引數會傳遞給 OCaml 程式,在字串陣列 Sys.argv 中。此陣列的元素 0 是位元組碼可執行檔案的名稱;元素 1 到 n 是剩餘的引數 arg 1 到 arg n 。
如第 13 章所述,ocamlc 命令產生的位元組碼可執行檔案是可自我執行的,並會自動在其自身上啟動 ocamlrun 命令。也就是說,假設 a.out 是位元組碼可執行檔案,
a.out arg 1 ... arg n
與
ocamlrun a.out arg 1 ... arg n
的效果完全相同。請注意,直接呼叫 a.out 時,無法將選項傳遞給 ocamlrun 。
Windows: 在數個 Windows 版本中,位元組碼可執行檔案只有在名稱結尾為 .exe 時才能自我執行。建議一律將 .exe 名稱提供給位元組碼可執行檔案,例如使用 ocamlc -o myprog.exe ... 而非 ocamlc -o myprog ... 進行編譯。
2 選項
ocamlrun 可辨識下列命令列選項。
-b 當程式因未捕獲的例外而中止時,會印出詳細的執行「回溯追蹤」,顯示引發例外的位置以及此時未完成的函式呼叫。只有在位元組碼可執行檔案包含除錯資訊時,才會印出回溯追蹤,也就是說,必須使用 ocamlc 的 -g 選項進行編譯和連結。這相當於在 OCAMLRUNPARAM 環境變數中設定 b 旗標(請參閱下方)。 -config 印出 ocamlrun 的版本號碼和其設定的詳細摘要,然後結束。 -I dir 除了標準搜尋路徑(請參閱第 15.3 節)之外,還會在目錄 dir 中搜尋動態載入的函式庫。 -m 印出作為引數提供的位元組碼可執行檔案的魔術數字並結束。 -M 印出此執行期版本預期的位元組碼可執行檔案的魔術數字並結束。 -p 印出此 ocamlrun 版本已知的原始型別名稱並結束。 -t 增加除錯執行期的追蹤層級(否則會忽略)。 -v 指示記憶體管理員在標準錯誤上印出一些進度訊息。這相當於在 OCAMLRUNPARAM 環境變數中設定 v=61 (請參閱下方)。 -version 印出版本字串並結束。 -vnum 印出簡短版本號碼並結束。 也會參考下列環境變數
CAML_LD_LIBRARY_PATH 搜尋動態載入函式庫的其他目錄(請參閱第 15.3 節)。 OCAMLLIB 包含 OCaml 標準函式庫的目錄。(如果未設定 OCAMLLIB ,則會改用 CAMLLIB 。)用於尋找動態載入的 ld.conf 設定檔(請參閱第 15.3 節)。如果未設定,則預設為編譯 OCaml 時指定的函式庫目錄。 OCAMLRUNPARAM 設定執行期系統選項和垃圾收集參數。(如果未設定 OCAMLRUNPARAM ,則會改用 CAMLRUNPARAM 。)此變數必須是以逗號分隔的參數規格序列。為了方便起見,會忽略變數開頭的逗號,且多個逗號會被解讀為單一逗號。參數規格是一個選項字母,後面接著 = 符號、一個十進位數字(或以 0x 開頭的十六進位數字),以及一個可選的乘數。選項記錄如下;選項 a、i、l、m、M、n、o、O、s、v、w 對應於 模組 Gc 中記錄的 control 記錄欄位。
b (回溯追蹤)當未捕獲的例外中止程式時,觸發印出堆疊回溯追蹤。可以提供一個可選引數:b=0 會關閉回溯追蹤列印;b=1 等同於 b 並開啟回溯追蹤列印;b=2 會開啟回溯追蹤列印,並強制執行期系統在程式啟動時載入除錯資訊,而不是在回溯追蹤列印時載入。如果執行期無法在回溯追蹤列印時載入除錯資訊,例如如果沒有可用的檔案描述元,則可以使用 b=2 。 c (cleanup_on_exit )在結束時正常關閉執行期(請參閱第 22.7.5 節中的 caml_shutdown )。此選項也會啟用集區功能(如同 caml_startup_pooled 中)。此模式可用於使用第三方記憶體除錯器偵測洩漏。 e (runtime_events_log_wsize )每個網域執行期事件環形緩衝區的大小,以對數的二次方字組表示。預設值為 16,在 64 位元系統上會提供 64k 字組或 512kb 的緩衝區。 l (stack_limit )堆疊大小的限制(以字組為單位)。這只與位元組碼執行期相關,因為原生碼執行期使用作業系統的堆疊。 m (custom_minor_ratio )次要堆積中自訂值持有的堆積外記憶體的浮動垃圾的上限。當次要堆積中位於次要堆積中的自訂值持有這麼多記憶體時,就會觸發次要 GC。表示為次要堆積大小的百分比。預設值:100。注意:這僅適用於使用 caml_alloc_custom_mem 配置的值。 M (custom_major_ratio )主要堆積中自訂值(例如 bigarray)持有的堆積外記憶體的浮動垃圾與主要堆積大小的目標比例。會調整 GC 速度,以盡可能使用此記憶體作為尚未收集的無用值。表示為主要堆積大小的百分比。預設值:44。注意:這僅適用於使用 caml_alloc_custom_mem 配置的值。 n (custom_minor_max_size )次要堆積中每個自訂值配置的堆積外記憶體最大量。當在次要堆積上配置自訂值,且此值持有的位元組數多於此值時,只有此值會計入 custom_minor_ratio ,其餘則直接計入 custom_major_ratio 。預設值:8192 位元組。注意:這僅適用於使用 caml_alloc_custom_mem 配置的值。 乘數為 k 、M 或 G ,分別表示乘以 210 、220 和 230 。 o (space_overhead )主要 GC 速度設定。請參閱 Gc 模組文件以取得詳細資訊。 p (語法分析器追蹤)開啟 ocamlyacc 產生的語法分析器的除錯支援。當此選項開啟時,執行語法分析器的下推自動機會印出其動作的追蹤。此選項不接受任何引數。 R (隨機化)預設開啟所有雜湊表的隨機化(請參閱 模組 Hashtbl )。此選項不接受任何引數。 s (minor_heap_size )次要堆積的大小。(以字組為單位) t 設定除錯執行期的追蹤層級(標準執行期會忽略)。 v (verbose )要列印到 stderr 的 GC 訊息。這是從下列選項中選取的值的總和
1 (= 0x001) 主要 GC 週期的開始和結束。 2 (= 0x002) 次要收集和主要 GC 片段。 4 (= 0x004) 堆積的擴展和縮小。 8 (= 0x008) 堆疊和記憶體管理員表格的調整大小。 16 (= 0x010) 堆積壓縮。 32 (= 0x020) 變更 GC 參數。 64 (= 0x040) 計算主要 GC 切片大小。 128 (= 0x080) 呼叫終結函數 256 (= 0x100) 啟動訊息(載入位元組碼可執行檔、解析共享函式庫)。 512 (= 0x200) 計算觸發壓縮的條件。 1024 (= 0x400) 在程式結束時輸出 GC 統計資料。 2048 (= 0x800) GC 除錯訊息。 4096 (= 0x1000) 位址空間保留變更。
V (verify_heap ) 在主要 GC 週期完成後,對堆積執行完整性檢查 W 將執行階段警告列印至 stderr(例如,在檔案上開啟的 Channel 在未關閉的情況下終止、未刷新的資料等等)如果選項字母無法識別,則會忽略整個參數;如果缺少等號或數字,則值會被視為 1;如果無法識別乘數,則會忽略它。
例如,在 32 位元的機器上,在 bash 下執行命令
export OCAMLRUNPARAM='b,s=256k,v=0x015'
會告知後續的 ocamlrun 列印未捕獲的例外狀況的回溯追蹤、將其初始次要堆積大小設定為 1 MB,並在每次主要 GC 週期開始時、堆積大小變更時以及觸發壓縮時列印訊息。
CAMLRUNPARAM 如果在環境中找不到 OCAMLRUNPARAM ,則會改為使用 CAMLRUNPARAM 。如果也找不到 CAMLRUNPARAM ,則會使用預設值。 PATH 搜尋位元組碼可執行檔的目錄清單。
3 動態載入共享函式庫
在支援動態載入的平台上,ocamlrun 可以動態連結 C 共享函式庫(DLL),以提供標準執行階段系統所提供之外的額外 C 原生函式。這些函式庫的名稱在連結時提供,如第22.1.4 節所述,並記錄在位元組碼可執行檔中;然後,ocamlrun 會在位元組碼可執行程式啟動時,找到這些函式庫並解析對其原生函式的引用。
ocamlrun 命令會按照指示的順序,在以下目錄中搜尋共享函式庫
使用 -I 選項在 ocamlrun 命令列中指定的目錄。 在 CAML_LD_LIBRARY_PATH 環境變數中指定的目錄。 在連結時透過 ocamlc 的 -dllpath 選項指定的目錄。(這些目錄會記錄在位元組碼可執行檔中。) 在檔案 ld.conf 中指定的目錄。此檔案位於 OCaml 標準函式庫目錄中,並列出要搜尋的目錄名稱(每行一個)。通常,它只包含一行,指定 OCaml 標準函式庫目錄的 stublibs 子目錄。使用者可以在其中新增包含常用共享函式庫的其他目錄名稱;但是,為了安裝的一致性,我們建議將共享函式庫直接安裝在系統 stublibs 目錄中,而不是將行新增至 ld.conf 檔案。 系統動態載入器搜尋的預設目錄。在 Unix 下,這些通常包括 /lib 和 /usr/lib ,以及在檔案 /etc/ld.so.conf 和環境變數 LD_LIBRARY_PATH 中列出的目錄。在 Windows 下,這些包括 Windows 系統目錄,以及在 PATH 環境變數中列出的目錄。
4 常見錯誤
本節說明並解釋最常遇到的錯誤訊息。
filename : no such file or directory 如果 filename 是一個自我執行的位元組碼檔案的名稱,則表示該檔案不存在,或者它無法在自身上執行 ocamlrun 位元組碼直譯器。第二種可能性表示 OCaml 未正確安裝在您的系統上。 Cannot exec ocamlrun (在啟動自我執行的位元組碼檔案時。)在可執行路徑中找不到 ocamlrun 。請檢查 OCaml 是否已正確安裝在您的系統上。 Cannot find the bytecode file ocamlrun 嘗試執行的檔案(例如,作為 ocamlrun 的第一個非選項引數提供的檔案)不存在,或者不是有效的可執行位元組碼檔案。Truncated bytecode file ocamlrun 嘗試執行的檔案不是有效的可執行位元組碼檔案。可能是自建立以來被截斷或損壞了。請擦除並重新建置它。Uncaught exception 正在執行的程式包含一個「遊蕩」的例外狀況。也就是說,它在某個點引發例外狀況,而此例外狀況永遠不會被捕獲。這會導致程式立即終止。會列印例外狀況的名稱,以及它的字串、位元組序列和整數引數(更複雜類型的引數不會正確列印)。若要找到未捕獲例外狀況的上下文,請使用 -g 選項編譯程式,然後在 ocamldebug 除錯器下再次執行它(請參閱第20 章),或使用 ocamlrun -b 或將 OCAMLRUNPARAM 環境變數設定為 b=1 來執行它。 Out of memory 正在執行的程式需要的記憶體超出可用記憶體。可能是程式建構了過大的資料結構;或者程式包含太多巢狀的函式呼叫,導致堆疊溢位。在某些情況下,您的程式完全正確,只是需要的記憶體超出您的機器所提供的。在其他情況下,「記憶體不足」訊息會揭示程式中的錯誤:非終止的遞迴函式、配置過大的陣列、字串或位元組序列、嘗試建構無限列表或其他資料結構,...為了協助您診斷此錯誤,請使用 ocamlrun 的 -v 選項執行程式,或將 OCAMLRUNPARAM 環境變數設定為 v=63 。如果它顯示很多「Growing stack …」訊息,這很可能是迴圈遞迴函式。如果它顯示很多「Growing heap …」訊息,且堆積大小緩慢增加,這很可能是嘗試建構具有太多(無限多?)儲存格的資料結構。如果它顯示很少的「Growing heap …」訊息,但堆積大小大幅增加,這很可能是嘗試建構過大的陣列、字串或位元組序列。
Copyright © 2024 Institut National de Recherche en Informatique et en Automatique