ocamldebug中的調用堆棧是真正的調用堆棧,因此已經做出尾部調用的函數不會顯示在其中。這很混亂。我如何獲得包含尾部呼叫的回溯?如何獲得包含在Ocaml中的尾部調用的堆棧跟蹤?
4
A
回答
7
最簡單的方法是改變你的函數,使它不再是尾遞歸。這就是我使用的情況,當我想要在執行異常終止程序時顯示好回溯(在這種情況下不需要ocamldebug,運行程序OCAMLRUNPARAM="b"
就足夠了; documentation)。
我個人的方法是改變尾調用到
let result = <tail call> in result
ocaml的大多是編譯代碼,因爲它是寫的,在這種情況下,它是偉大的:編譯器不內聯這個,你會得到一個不錯的俯瞰回溯。當然,一旦發現錯誤,您可以輕鬆地刪除該優化。當你只有幾個尾巴呼叫時,這個工作正常;如果你有很多尾巴,你可以把整個功能體包裝成let result = <body> in result
,但是我覺得它不太方便和清晰。)
If你需要的功能仍然是taill呼叫(例如,你有一個OS設定的堆棧大小限制,你可以橫置),你可以物化爲這個功能到數據結構調用堆棧,把
let rec f arg1 arg2 .. argN =
...
f arg1' arg2' .. argN'
分成
let rec f stack arg1 arg2 .. argN =
let stack' = (arg1,arg2,..,argN)::stack in
...
f stack' arg1' arg2' .. argN'
然後你可以在ocamldebug中檢查stack
變量的值,以獲取函數特定的堆棧跟蹤。
+0
不幸的是,我實際上在探索一個陌生的代碼庫(Coq),所以我不能立即知道在回溯中可以看到的函數的哪些調用者是真正的調用者。 –
0
要查看真實尾部呼叫的位置,我可以重複鍵入「開始」以反轉執行並彈出堆棧,直到到達感興趣的呼叫目標,然後回退。費力,而且必須在逐個呼叫的基礎上完成,但它很有效。
相關問題
- 1. 如何獲得正確的堆棧跟蹤而不是反射堆棧跟蹤?
- 2. 如何在OCaml中獲取堆棧跟蹤?
- 3. 如何獲得堆棧跟蹤
- 4. 如何獲取包含堆棧跟蹤的bluemix日誌?
- 5. 如何在堆棧溢出後在OCaml中獲得完整的非結構化堆棧跟蹤?
- 6. 如何獲得斯卡拉外殼調用堆棧跟蹤
- 7. C#堆棧跟蹤不包含調用新的運營商
- 8. 如何在SBT 0.10.0中獲得完整的堆棧跟蹤?
- 9. 堆棧跟蹤如何構建以及堆棧如何跟蹤?
- 10. 如何獲取ABAP中的程序調用堆棧跟蹤?
- 11. 如何通過xdebug中的api調用獲取堆棧跟蹤?
- 12. 輕鬆獲得堆棧跟蹤
- 13. 如何獲得堆棧跟蹤C++中的Android
- 14. 如何獲得Specman中的堆棧跟蹤?
- 15. 如何在Firefox中獲得JavaScript堆棧跟蹤?
- 16. 調試堆棧跟蹤?
- 17. 調試堆棧跟蹤
- 18. 在任何網頁結尾處獲取堆棧跟蹤瀏覽
- 19. 在堆棧跟蹤中獲取被調用的靜態類名
- 20. 如何堆棧跟蹤extlib?
- 21. 獲取的$充分調用堆棧跟蹤的HTTP調用
- 22. 如何獲取堆棧跟蹤信息?
- 23. eclipse中的堆棧跟蹤
- 24. VB6中的堆棧跟蹤
- 25. 你如何獲得Nashorn的JavaScript堆棧跟蹤?
- 26. Valgrind(主要下面),如何獲得完整的堆棧跟蹤?
- 27. Android Google Play如何獲得更長的堆棧跟蹤?
- 28. 在堆棧跟蹤中捕獲FileNotFound?
- 29. 在VB6中獲取堆棧跟蹤
- 30. 在Perl中獲取堆棧跟蹤?
有趣的問題。我猜測這將涉及禁用尾部優化,因爲程序很難顯示已被完全覆蓋的堆棧幀。如果有人發現如何做到這一點,您可能還需要提高堆棧限制(在Bash中爲'ulimit -s')。 –