Skip to content

Conversation

@tbkka
Copy link
Contributor

@tbkka tbkka commented Jul 10, 2024

This inserts a suitably named function into the stack trace whenever a dynamic cast failure involves a NULL source or target type. Very often, crash logs include backtraces with function names but no log output; with this change, such a backtrace might look like the following -- note TARGET_TYPE_NULL in the function name here to mark the missing type information:

 frame #0: __pthread_kill + 8
 frame #1: pthread_kill + 288
 frame #2: abort + 128
 frame #3: swift::fatalErrorv()
 frame #4: swift::fatalError()
 frame #5: swift_dynamicCastFailure_TARGET_TYPE_NULL()
 frame #6: swift::swift_dynamicCastFailure()
 frame #7: ::swift_dynamicCast()

Resolves rdar://130630157

This inserts a suitably named function into the stack trace whenever
a dynamic cast failure involves a NULL source or target type.
Very often, crash logs include backtraces with function names but
no log output; with this change, such a backtrace might look like
the following -- note `TARGET_TYPE_NULL` in the function name
here to mark the missing type information:

```
 frame #0: __pthread_kill + 8
 frame swiftlang#1: pthread_kill + 288
 frame swiftlang#2: abort + 128
 frame swiftlang#3: swift::fatalErrorv()
 frame swiftlang#4: swift::fatalError()
 frame swiftlang#5: swift_dynamicCastFailure_TARGET_TYPE_NULL()
 frame swiftlang#6: swift::swift_dynamicCastFailure()
 frame swiftlang#7: ::swift_dynamicCast()
```

Resolves rdar://130630157
@tbkka tbkka requested review from al45tair and mikeash as code owners July 10, 2024 23:13
Copy link
Contributor

@al45tair al45tair left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice idea.

Copy link
Contributor

@mikeash mikeash left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lovely. There are probably a bunch more places where we should adopt this technique.

I'm worried about the compiler getting too clever for us and emitting fatalError as a tail call. The std::string destructor at the end of scope might prevent this, but on the other hand the noreturn attribute on fatalError might prevent that. We could annotate fatalError with __attribute__((not_tail_called)) or annotate these functions with __attribute__((disable_tail_calls)). The former would apply to all callers, but that might be a good thing.

@tbkka
Copy link
Contributor Author

tbkka commented Jul 11, 2024

@swift-ci Please test

@tbkka tbkka enabled auto-merge July 11, 2024 15:56
@wearhere
Copy link

Cool!!

@tbkka tbkka merged commit 5916325 into swiftlang:main Jul 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants