-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Better runtime failure messages (not yet enabled by default) #25978
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
6094039
to
79f89a2
Compare
@swift-ci test |
Build failed |
Build failed |
79f89a2
to
edf7854
Compare
@swift-ci test |
1 similar comment
@swift-ci test |
Build failed |
Build failed |
…iteral, indicating the failure reason.
The SIL generation for this builtin also changes: instead of generating the cond_fail instructions upfront, let the optimizer generate it, if the operand is a static string literal. In worst case, if the second operand is not a static string literal, the Builtin.condfail is lowered at the end of the optimization pipeline with a default message: "unknown program error".
To display a failure message in the debugger, create a function in the debug info which has the name of the failure message. The debug location of the trap/cond_fail is then wrapped into this function and the function is declared as "inlined". In case the debugger stops at the trap instruction, it displays the inline function, which looks like the failure message. For example: * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) frame #0: 0x0000000100000cbf a.out`testit3(_:) [inlined] Unexpectedly found nil while unwrapping an Optional value at test.swift:14:11 [opt] 11 12 @inline(never) 13 func testit(_ a: Int?) -> Int { -> 14 return a! 15 } 16 This change is currently not enabled by default, but can be enabled with the option "-Xllvm -enable-trap-debug-info". Enabling this feature needs some changes in lldb. When the lldb part is done, this option can be removed and the feature enabled by default.
For using the improved condfail messages in the stdlib, we need a function, like precondition(), just taking a StaticString instead of a String for the message. The existing (underscored) _precondition is a perfect fit for this, except that it's not printing the location info in debug builds. This change makes _precondition() equivalent to precondition, just taking a StaticString as argument. The other alternative would be to add another variant of precondition, just taking a StaticString. But we already have so many failure functions in Assert.swift, so adapting an existing one seems to be a better solution. This effectively undos a change from 5 years ago which intentionally removed the location info from _precondition (rdar://problem/16958193). But this was at a time where swift was not open source yet. So I think today it's okay to always add location information, even if it's from inside the stdlib. It can be even very useful for expert users for looking up the location the stdlib source.
…nil while unwrapping an optional" failure message. Advantage: the failure message is now also visible in release builds.
edf7854
to
bc48b3d
Compare
@swift-ci test |
Build failed |
Build failed |
@eeckstein We've reverted this because we think it may have broken four tests:
See e.g. https://ci.swift.org/job/oss-swift_tools-RA_stdlib-DA_test-simulator/715 for examples of the failures. |
The implementation was done quite a while ago. Now, that we have support in lldb (swiftlang/llvm-project#773), we can enable it by default in the compiler. LLDB now shows the runtime failure reason, for example: * thread #1, queue = 'com.apple.main-thread', stop reason = Swift runtime failure: arithmetic overflow frame #1: 0x0000000100000f0d a.out`testit(a=127) at trap_message.swift:4 1 2 @inline(never) 3 func testit(_ a: Int8) -> Int8 { -> 4 return a + 1 5 } 6 For details, see swiftlang#25978 rdar://problem/51278690
Meaning:
All this is done via debug info, so there is no overhead in code generation. Thanks @adrian-prantl for the idea of implementing this with inline functions in the debug info.
When having debug info available, e.g. when running in the debugger, the failure message is displayed as inline function.
Examples:
This change is currently not enabled by default, but can be enabled with the option "-Xllvm -enable-trap-debug-info". Enabling this feature needs some changes in lldb. When the lldb part is done, this option can be removed and the feature enabled by default.
rdar://problem/51278690