Skip to content
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

[LLDB][NFC] Create a namespace for the DWARF plugin #68150

Merged

Conversation

walter-erquinigo
Copy link
Member

@walter-erquinigo walter-erquinigo commented Oct 3, 2023

As a followup of #67851, I'm defining a new namespace lldb_plugin::dwarf for the classes in this Plugins/SymbolFile/DWARF folder. This change is very NFC and helped me with exporting the necessary symbols for my out-of-tree language plugin. The only class that I didn't change is ClangDWARFASTParser, because that shouldn't be in the same namespace as the generic language-agnostic dwarf parser.
It would be a good idea if other plugins follow the same namespace scheme.

@walter-erquinigo walter-erquinigo marked this pull request as ready for review October 3, 2023 20:00
@llvmbot llvmbot added the lldb label Oct 3, 2023
@walter-erquinigo walter-erquinigo force-pushed the walter/namespace-change branch 2 times, most recently from 98c009c to 92dc652 Compare October 3, 2023 20:17
@bulbazord
Copy link
Member

bulbazord commented Oct 4, 2023

I have no problem with putting things from SymbolFileDWARF into its own namespace. Let's wait a bit though to see if anyone else has any opinions.

Copy link
Collaborator

@clayborg clayborg left a comment

Choose a reason for hiding this comment

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

I have no issues with putting this into a namespace either. Just a question in my inline comment

@@ -18,7 +18,9 @@
#include "llvm/DebugInfo/DWARF/DWARFLocationExpression.h"
#include <functional>

namespace lldb_plugin::dwarf {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do we do this anywhere else? Should this be split into:

namespace lldb_plugin {
namespace dwarf {

Not sure if there is a llvm coding convention for this?

Copy link
Member Author

Choose a reason for hiding this comment

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

This is possible after the switch to c++17, and that's probably why no one else is using it in LLDB. There's no explicit llvm coding convention for this. I'm fine with splitting it into two lines if you want.

Copy link
Member

Choose a reason for hiding this comment

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

I'd prefer the old way for the sake of consistency.

Copy link
Member Author

Choose a reason for hiding this comment

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

Sure, I'll change that!!

@JDevlieghere
Copy link
Member

In the previous iteration of this PR, @bulbazord suggested keeping this in the lldb_private namespace. Something like lldb_private::plugin::dwarf for example? Is there a reason to make this not part of lldb_private? As Jim pointed out in that thread, the way LLDB plugins work today, you're stuck with the unstable private API anyway, so being explicit about that might be nice?

Is the goals to do the same for other plugins as well? Seems like that could be a largely mechanical change. If we enforce the use of the namesake, it might make it more obvious when folks accidentally try to use them in generic code. WDYT?

@walter-erquinigo
Copy link
Member Author

@JDevlieghere , now that I think of it twice, I like the approach you mention better. I'll use lldb_private::plugin::dwarf for the namespace then. Do you still want these nested namespaces to be defined in three lines instead of one? I could keep consistency as you mention, but I don't know if that would be visually too much.

@JDevlieghere
Copy link
Member

Do you still want these nested namespaces to be defined in three lines instead of one? I could keep consistency as you mention, but I don't know if that would be visually too much.

If the plan is to move all plugins under lldb_private::plugin then the one-line is fine as I expect it will be the (new) majority of nested namespace in LLDB.

@walter-erquinigo
Copy link
Member Author

sounds good! I'll do the change now

@walter-erquinigo
Copy link
Member Author

@JDevlieghere PTAL

@walter-erquinigo
Copy link
Member Author

ping @clayborg

Copy link
Collaborator

@clayborg clayborg left a comment

Choose a reason for hiding this comment

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

Should we have a top level "lldb_plugin" namespace instead of "lldb_private::plugin"? It would be easier to be able to export only a single plug-in interface if needed if we did this

@walter-erquinigo
Copy link
Member Author

@clayborg has a very valid point. This will allow for better tuning of what gets exported. I'll do that instead.

Copy link
Collaborator

@clayborg clayborg left a comment

Choose a reason for hiding this comment

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

LGTM, anyone else have any objections?

@walter-erquinigo
Copy link
Member Author

@JDevlieghere PTAL :)

@JDevlieghere
Copy link
Member

Should we have a top level "lldb_plugin" namespace instead of "lldb_private::plugin"? It would be easier to be able to export only a single plug-in interface if needed if we did this

What makes it easier to export lldb_plugin than lldb_private::plugin? I'm only familiar with using an export list in which case it's just another prefix.

I also think conceptually this is somewhat confusing or even misleading. We currently have an lldb and lldb_private namespace which mean very different things. That expectations, combined with the fact that LLDB has plugins, makes it really sound like lldb_plugin is the interface we expose for writing (dynamically loadable) plugins. But that's not the case at all, it's actually the opposite: because all the plugins use lldb_private in their interfaces, so you need to export lldb_private types. Making it a namespace contained in lldb_private makes that really obvious.

If we ever want to have somewhat stable language plugins for Swift or Rust, we actually will need something like what I describe above: a "somewhat stable" interface that downstream languages can use to implement their language support without having to maintain a full fork (like Swift). We're still pretty far from that, but I wouldn't want to reserve a namespace now that will only make that harder down the line.

FWIW I don't feel super strongly about this. I want to understand the benefit of Greg's suggestion because I see a smallish downside to doing it that way and all things being equal we can avoid some confusing in the future.

@walter-erquinigo
Copy link
Member Author

walter-erquinigo commented Oct 13, 2023

A problem that I'm seeing now is that if we move all the plugins to lldb_private::plugin, the liblldb-private.exports file will by default emit all the lldb symbols (the ones in plugins + the regular lldb_private symbols). This can potentially be too many symbols, as IIUC some linkers have a limit for the number of symbols from exports files, like the windows linker.
On the other hand, if the plugin symbols don't use the lldb_private namespace, we can leave liblldb-private.exports unchanged, and if someone wants the symbols of an specific plugin, they could just modify that file or provide their own. In other words, people could selectively pick the symbols of the plugins they want.

A workaround with sticking to the lldb_private namespace is to modify liblldb-private.exports to exclude in its regex lldb_private::plugin but to include any other lldb_private namespace, and I don't really know if that would work with all linkers. So far I've just seen linkers using regexes without exclusions.

@walter-erquinigo
Copy link
Member Author

That expectations, combined with the fact that LLDB has plugins, makes it really sound like lldb_plugin is the interface we expose for writing (dynamically loadable) plugins.

I don't think people would have the expectation that you need to use lldb_plugin for a namespace of a dynamically loaded plugin. In fact, an external shared library is free to use any namespace because you only need to provide the symbol PluginInitialize to make LLDB happy. An in any case, if you used lldb_plugin for your plugin, there would be nothing wrong, tbh.

If we go the lldb_plugin route, we could try to standardize:
lldb_private -> core lldb symbols that don't belong to a plugin
lldb_plugin -> symbols from any plugins
lldb -> public ABI-stable symbols

@jimingham
Copy link
Collaborator

jimingham commented Oct 13, 2023 via email

@walter-erquinigo
Copy link
Member Author

I think I'm missing something. The API's you are calling the lldb_plugin API's aren't really stand-alone, are they? The lldb_plugin::dwarf API's seem to have a bunch of methods that take lldb_private types. So you already have to have some kind of closure of the exported API's that includes whatever lldb_private types these API's depend on. You're going to be doing picking and choosing of exports, so I don't see why putting it in another top-level namespace makes this easier?

You are pretty much right. The picking is mostly about which specific symbols a developer wants to export and prevent an explosion of exported symbols.

I also agree with Jonas, we should reserve lldb_plugin for when we make a viable API for the more usefully externalized plugins in lldb. So even if we need another top-level namespace, we should use still use an accurate name like lldb_plugin_private.

After reading twice Jonas' point, I agree with you. Reserving this namespace for such API is definitely very valuable.

All in all, I'm now convinced that we should go with lldb_private::plugin::dwarf. If I end up having too many symbols to process, I can figure out workarounds, but that's likely not to happen even in a very long time.

In any case, is everyone okay if I use the lldb_private::plugin::dwarf namespace?

@jimingham
Copy link
Collaborator

lldb_private::plugin::dwarf is fine by me.

As a followup of llvm#67851, I'm defining a new namespace `lldb_plugin::dwarf` for the classes in this Plugins/SymbolFile/DWARF folder. This change is very NFC and helped me with exporting the necessary symbols for my out-of-tree language plugin. The only two classes that I didn't change are DWARFDataExtractor, because that's being explicitly exported as part of lldb_private in `lldb-forward.h` , and the ClangDWARFASTParser, because that shouldn't be in the same namespace as the generic language-agnostic dwarf parser, but I'm okay with changing that. In any case, even if I didn't need this for my work, adding this namespace could be considered a good practice.
@walter-erquinigo
Copy link
Member Author

walter-erquinigo commented Oct 13, 2023

I've just updated this PR to use

namespace lldb_private::plugin {
namespace dwarf {

PTAL, @JDevlieghere , @clayborg

Copy link
Member

@JDevlieghere JDevlieghere left a comment

Choose a reason for hiding this comment

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

Thanks Walter! I'm happy with this 👍

@walter-erquinigo
Copy link
Member Author

Thanks for unblocking me!!

@walter-erquinigo walter-erquinigo merged commit 1673a1b into llvm:main Oct 13, 2023
3 checks passed
@walter-erquinigo walter-erquinigo deleted the walter/namespace-change branch October 13, 2023 20:51
@clayborg
Copy link
Collaborator

I still think we should have a "lldb_private" namespace for generic code that uses the internal virtual plug-in APIs. It would be nice to have the "lldb_plugins" namespace for plugins and the DWARF plug-in would go into "lldb_plugins::dwarf". Right now if we export "lldb_private::", we are going to get a lot more functions exported if poeple used to export "lldb_private::", so this will case a change in behavior. If someone needs the DWARF plug-in, they can add "lldb_plugins::dwarf" to the exports list. We might also keep exporting more and more functions as time goes on if people follow the current state of this PR where you add your plugin into the lldb_private namespace if they see the DWARF plug-in now doing it, so they might copy it. This doesn't really affect me as I never plan to use the fragile API, I am just trying to point this out in case it makes sense.

@clayborg
Copy link
Collaborator

But if everyone else prefers the current state of this patch, I am fine with it.

@clayborg
Copy link
Collaborator

And if we ever make external plug-ins, they wouldn't be expected to use either the "lldb_private::plugins" or "lldb_plugins" namespaces as those are solely for built in stuff.

@jimingham
Copy link
Collaborator

jimingham commented Oct 17, 2023 via email

@clayborg
Copy link
Collaborator

Sounds good, I am ok since everyone else is ok with this. Thanks for the comments.

adrian-prantl added a commit to adrian-prantl/llvm-project that referenced this pull request Oct 25, 2023
As a followup of llvm#67851, I'm
defining a new namespace `lldb_plugin::dwarf` for the classes in this
Plugins/SymbolFile/DWARF folder. This change is very NFC and helped me
with exporting the necessary symbols for my out-of-tree language plugin.
The only class that I didn't change is ClangDWARFASTParser, because that
shouldn't be in the same namespace as the generic language-agnostic
dwarf parser.
It would be a good idea if other plugins follow the same namespace
scheme.

(cherry picked from commit 1673a1b)

 Conflicts:
	lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
	lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants