Skip to content

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

Merged
merged 1 commit into from
Mar 27, 2019

Conversation

adrian-prantl
Copy link
Contributor

@adrian-prantl adrian-prantl commented Mar 21, 2019

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

@adrian-prantl
Copy link
Contributor Author

@swift-ci test

Copy link
Contributor

@slavapestov slavapestov left a 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.

@rjmccall
Copy link
Contributor

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?

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.

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - 95c96e83abd11aa36d1cc9d86247ca189b3f0bdd

@adrian-prantl
Copy link
Contributor Author

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?

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.

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?

@rjmccall
Copy link
Contributor

Sorry, I meant for WMO. See getIRLinkage in GenDecl.cpp.

@adrian-prantl
Copy link
Contributor Author

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 getIRLinkage().

@@ -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);
Copy link
Contributor Author

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...

Copy link
Contributor

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.

@slavapestov
Copy link
Contributor

@adrian-prantl LLDB defines a method named SwiftASTManipulator::MakeDeclarationsPublic(). Is it not getting called anymore? Or its not doing the right thing?

Copy link
Contributor

@rjmccall rjmccall left a 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;
Copy link
Contributor

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);
Copy link
Contributor

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
Copy link
Contributor Author

@adrian-prantl LLDB defines a method named SwiftASTManipulator::MakeDeclarationsPublic(). Is it not getting called anymore? Or its not doing the right thing?

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.

@slavapestov
Copy link
Contributor

@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?

@adrian-prantl
Copy link
Contributor Author

adrian-prantl commented Mar 27, 2019

@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

private struct FixedContainer {
  var s = S() // S is a resilient struct and defined in a different module
}
private var g_main_c = FixedContainer()

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
@adrian-prantl
Copy link
Contributor Author

@swift-ci test

1 similar comment
@adrian-prantl
Copy link
Contributor Author

@swift-ci test

@slavapestov
Copy link
Contributor

The type in the example was private.

Right, but doesn't SwiftASTManipulator::MakeDeclarationsPublic() make everything public? That's the part I'm confused about.

@adrian-prantl
Copy link
Contributor Author

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.

@adrian-prantl adrian-prantl merged commit e622ea6 into swiftlang:master Mar 27, 2019
@adrian-prantl
Copy link
Contributor Author

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.

@slavapestov
Copy link
Contributor

@adrian-prantl No worries.

If the Decl is part of the swiftmodule being debugged, why is lldb emitting the type metadata accessor?

@jrose-apple
Copy link
Contributor

It's emitting a reference to the existing accessor (a declaration rather than a definition).

@slavapestov
Copy link
Contributor

@jrose-apple I see. Perhaps it makes more sense to elevate private linkage to internal when emitting code with -g?

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.

5 participants