-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[Runtime][Reflection][swift-inspect] Add facilities for tracking and examining backtraces for metadata allocations. #32244
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
[Runtime][Reflection][swift-inspect] Add facilities for tracking and examining backtraces for metadata allocations. #32244
Conversation
@swift-ci please test |
Build failed |
Build failed |
a8e4e53
to
bff26ed
Compare
@swift-ci please test |
Build failed |
Build failed |
bff26ed
to
b89894c
Compare
b89894c
to
65765ab
Compare
auto Error = Context->iterateMetadataAllocationBacktraces([&] | ||
(auto AllocationPtr, auto Count, auto Ptrs) { | ||
std::vector<swift_reflection_ptr_t> ConvertedPtrs{&Ptrs[0], &Ptrs[Count]}; | ||
Call(AllocationPtr, Count, ConvertedPtrs.data(), ContextPtr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This now makes me wonder ... ConvertedPtrs.data()
is effectively just Ptrs
. I think that this call is effectively:
Call(AllocationPtr, Count, Ptrs, ContextPtr);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's true only when swift_reflection_ptr_t
and StoredPointer
are the same. When they aren't (as is the case for 32-bit targets) then this is needed to convert the values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, right, the foreign case. A comment about that would be nice!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You got it!
func symbolicatedLong(inspector: Inspector) -> String { | ||
return ptrs.reversed().enumerated().map { | ||
let indent = String(repeating: " ", count: $0 + 1) | ||
return indent + symbolString(ptr: $1, inspector: inspector) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another option would be to pass indentation
to the symbolString
and have the two just be different separators.
@@ -67,11 +67,19 @@ class Inspector { | |||
} | |||
|
|||
func getAddr(symbolName: String) -> swift_addr_t { | |||
let symbol = CSSymbolOwnerGetSymbolWithMangledName(swiftCore, symbolName) | |||
let symbol = CSSymbolOwnerGetSymbolWithMangledName(swiftCore, | |||
"_" + symbolName) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't this need to take into account the platform before adding a user label prefix? Linux, android, Windows x86_64 and ARM do not use _
(Windows x86, MIPS, and Darwin do).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is Darwin-specific code, as the CS*
calls are only available there. Support for other OSes will need a new Inspector
implementation that uses the appropriate calls for that OS.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair enough. Though, it raises the question of whether this should be inside CS*
or outside still.
} | ||
print(metadata.name) | ||
if let allocation = metadata.allocation { | ||
if let style = backtraceStyle { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could probably pull this bit out into an @inline(__always)
function.
|
||
func CSSymbolOwnerGetName(_ sym: CSTypeRef) -> String? { | ||
let name = Sym.CSSymbolOwnerGetName(sym) | ||
return name.map({ String(cString: $0) }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unnecessary parens
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return name.map({ String(cString: $0) }) | |
func CSSymbolOwnerGetName(_ sym: CSTypeRef) -> String? { | |
Sym.CSSymbolOwnerGetName(sym) | |
.map(String.init(cString:)) |
65765ab
to
0a6c805
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably should address Ben's comment before merging. Thanks for the iteration on this.
…examining backtraces for metadata allocations. rdar://problem/63674755
0a6c805
to
cd624bf
Compare
@compnerd I made Ben's suggested change as well. Always a pleasure to get good feedback. |
@swift-ci please test |
Build failed |
Build failed |
To be clear, my comment was mostly for my own idle amusement rather than an important change... Can't wait to use this! |
@airspeedswift I think you just really hate the |
@swift-ci please test |
@mikeash you're not wrong there |
Hi @mikeash – Git bisect has revealed this as breaking my Fedora 32 (linux, x86_64) machine. Can we revert this or commit a quick fix?
|
It looks like this test was added recently but nothing (as far as I can tell) in the Swift build system forces the GNU C++ standard library to be used, so if the host compiler defaults to LLVM's C++ library, then this test is at risk of failing. I've also been using LLVM's C++ standard library for a long time, so this breakage is unfortunate. |
@mikeash – So I'm not a python expert. How hard would it be to get the Swift |
CC: @compnerd because he wrote the brittle test. |
There’s definitely some assumptions around the C++ runtime on different platforms. I don’t think that the test would fail on libc++ though. The filtering there is to work around the libstdc++ forcing exported symbols. The diff appears to indicate that you’re building with RTTI? The standard disables RTTI which I think is causing some undesired (weak) exports of the type information. |
Weird. My setup is not explicitly disabling RTTI and I wouldn’t knowingly enable RTTI. I’d wager that either the runtime isn’t consistently disabling RTTI or this is pull request is exposing a latent bug in LLVM’s libc++. |
If we add the symbols you found to that test, would that make the test pass for both C++ libraries? |
Yeah, that’s probably a good way to get the tests passing again. Though, we should figure out why libc++ is injecting the vtables in the runtime (sounds like we’re messing up some flags). |
Pull request swiftlang#32244 introduced the use of `std::stringstream` but that causes vtables to be generated and we don't want that.
So I debugged this a bit. The problem is |
rdar://problem/63674755