堆栈跟踪跳过函数
Stack trace skipping functions
我正在查看 F# 中生成的堆栈跟踪,它们正在跳过函数。一个测试用例:
let foo() =
failwithf "foo"
[<EntryPoint>]
let main argv =
foo()
0
使用调试信息编译,运行:
(torch) C:\t>fsc -g test.fs
Microsoft (R) F# Compiler version 10.8.0.0 for F# 4.7
Copyright (c) Microsoft Corporation. All Rights Reserved.
(torch) C:\t>test
Unhandled Exception: System.Exception: foo
at Microsoft.FSharp.Core.PrintfModule.PrintFormatToStringThenFail@1637.Invoke(String message)
at Test.main(String[] argv) in C:\t\test.fs:line 7
它说异常是从 main
生成的,但没有提到 foo
实际生成的位置。
如何获取完整的堆栈跟踪,包括实际生成异常的函数?
您一直是优化的受害者,这使得在任何工具链中进行调试变得困难。
请注意 fsc
,优化是 turned on by default。
他们是:
内联
foo()
甚至没有被调用——它是一个简单的静态方法,可以很容易地内联。
生成的 IL 等效于:
let main argv =
PrintfModule.PrintFormatToStringThenFail(new PrintfFormat<_>("foo"));
0
我们可以用 --optimize-
关闭它
fsc -g --optimize- Program.fs
但这还不够。因为...
尾调用优化
尾调用优化可让您避免为函数分配新的堆栈帧。 foo
是一个简化 main
的简单函数。由于没有堆栈框架,您不会在堆栈跟踪中看到它。
我们可以用 --tailcalls-
关闭它。
要获得完整的调试体验,请使用 VS 为 DEBUG
所做的基本操作:
fsc --debug:full --define:DEBUG --define:TRACE --optimize- --tailcalls- Program.fs
现在,如果我们 运行 我们的目标,我们将按预期获得堆栈跟踪:
Unhandled Exception: System.Exception: foo
at Microsoft.FSharp.Core.PrintfModule.PrintFormatToStringThenFail@1639.Invoke(String message)
at Program.foo[a]() in Program.fs:line 4
at Program.main(String[] argv) in Program.fs:line 13
我正在查看 F# 中生成的堆栈跟踪,它们正在跳过函数。一个测试用例:
let foo() =
failwithf "foo"
[<EntryPoint>]
let main argv =
foo()
0
使用调试信息编译,运行:
(torch) C:\t>fsc -g test.fs
Microsoft (R) F# Compiler version 10.8.0.0 for F# 4.7
Copyright (c) Microsoft Corporation. All Rights Reserved.
(torch) C:\t>test
Unhandled Exception: System.Exception: foo
at Microsoft.FSharp.Core.PrintfModule.PrintFormatToStringThenFail@1637.Invoke(String message)
at Test.main(String[] argv) in C:\t\test.fs:line 7
它说异常是从 main
生成的,但没有提到 foo
实际生成的位置。
如何获取完整的堆栈跟踪,包括实际生成异常的函数?
您一直是优化的受害者,这使得在任何工具链中进行调试变得困难。
请注意 fsc
,优化是 turned on by default。
他们是:
内联
foo()
甚至没有被调用——它是一个简单的静态方法,可以很容易地内联。
生成的 IL 等效于:
let main argv =
PrintfModule.PrintFormatToStringThenFail(new PrintfFormat<_>("foo"));
0
我们可以用 --optimize-
fsc -g --optimize- Program.fs
但这还不够。因为...
尾调用优化
尾调用优化可让您避免为函数分配新的堆栈帧。 foo
是一个简化 main
的简单函数。由于没有堆栈框架,您不会在堆栈跟踪中看到它。
我们可以用 --tailcalls-
关闭它。
要获得完整的调试体验,请使用 VS 为 DEBUG
所做的基本操作:
fsc --debug:full --define:DEBUG --define:TRACE --optimize- --tailcalls- Program.fs
现在,如果我们 运行 我们的目标,我们将按预期获得堆栈跟踪:
Unhandled Exception: System.Exception: foo
at Microsoft.FSharp.Core.PrintfModule.PrintFormatToStringThenFail@1639.Invoke(String message)
at Program.foo[a]() in Program.fs:line 4
at Program.main(String[] argv) in Program.fs:line 13