-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Add a -public-linkage-for-metadata-accessors IRGen flag for LLDB. #23465
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
@swift-ci test |
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 feels a bit arbitrary. What about all the other accessor functions IRGen emits, or even just private methods? Maybe instead do a post-processing pass on the LLVM module to make everything public? I also thought at some point the lldb expression evaluator walked to AST making everything public - is that no longer happening?
I’m also worried that “plumbing” boolean parameters like this through multiple layers of calls will lead to a proliferation of boolean conditions that will become hard to reason about as these sort of flags accumulate. I’d be happy to discuss other ways of solving the underlying problem.
Or have IRGen's linkage computation understand that private things from the execution context aren't actually object-file-private when running in the debugger. We do something similar with private declarations when building for LTO. |
Build failed |
Can you elaborate on this a bit? So, still have an IRGen flag that specifies that this is for the expression evaluator, but have it apply to more kinds of symbols? What's a reasonable boundary? A quick grep for LTO in IRGen didn't find any results, what should I be looking for? |
Sorry, I meant for WMO. See |
95c96e8
to
81018a7
Compare
Sorry for the delay. @rjmccall Is this closer to what you had in mind? The option to communicate that we are in the LLDB expression evaluator is still there, but it is now localized to |
81018a7
to
8b096bb
Compare
@@ -1462,6 +1462,9 @@ getIRLinkage(const UniversalLinkageInfo &info, SILLinkage linkage, | |||
return RESULT(External, Hidden, Default); | |||
|
|||
case SILLinkage::Private: { | |||
if (info.forcePublicDecls()) | |||
return getIRLinkage(info, SILLinkage::SharedExternal, isDefinition, | |||
isWeakImported); |
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.
I'm also not sure whether this is the best possible set of flags. It appears to work...
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.
It probably ought to be based on whether this is a definition, so that definitions are shared (or maybe even private) and non-definitions are public-external.
@adrian-prantl LLDB defines a method named |
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.
Yeah, that's more what I was thinking, thanks.
@@ -49,12 +49,15 @@ class UniversalLinkageInfo { | |||
/// True iff are multiple llvm modules. | |||
bool HasMultipleIGMs; | |||
|
|||
/// Used by the LLDB expression evaluator. | |||
bool ForcePublicDecls; |
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.
The comment here should explain what this means, not how it's used.
@@ -1462,6 +1462,9 @@ getIRLinkage(const UniversalLinkageInfo &info, SILLinkage linkage, | |||
return RESULT(External, Hidden, Default); | |||
|
|||
case SILLinkage::Private: { | |||
if (info.forcePublicDecls()) | |||
return getIRLinkage(info, SILLinkage::SharedExternal, isDefinition, | |||
isWeakImported); |
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.
It probably ought to be based on whether this is a definition, so that definitions are shared (or maybe even private) and non-definitions are public-external.
IIUC the problem I'm trying to solve here is that Swift metadata accessors particularly are transparent to the AST and only injected/created by IRGen. |
@adrian-prantl The linkage of a metadata accessor is computed from the access level of the nominal type. So if the type is public the accessor should be public too. Is this not happening in some cases? |
The type in the example was private. For context, the expression is printing a global variable
|
In LLDB expressions, references to private metadata accessors may be emitted and need to be bound to symbols available in the attached program, even if these symbols are only supposed to have private visibility within the program. Also rdar://problem/48018240
8b096bb
to
e1f92cc
Compare
@swift-ci test |
1 similar comment
@swift-ci test |
Right, but doesn't |
As far as I understand the type in question is not part of the AST walked by SwiftASTManipulator::Publicist. It walks the expression source file, but our type is part of the swiftmodule that is being debugged. |
Note that just because I merged this, doesn't mean we shouldn't still replace this with something better if we find it, but this is blocking all the resilience support. |
@adrian-prantl No worries. If the Decl is part of the swiftmodule being debugged, why is lldb emitting the type metadata accessor? |
It's emitting a reference to the existing accessor (a declaration rather than a definition). |
@jrose-apple I see. Perhaps it makes more sense to elevate private linkage to internal when emitting code with -g? |
In LLDB expressions, references to private metadata accessors may be
emitted and need to be bound to symbols available in the attached
program, even if these symbols are only supposed to have private
visibility within the program.
Also rdar://problem/48018240