[lldb-dev] Multiple platforms with the same name

Greg Clayton via lldb-dev lldb-dev at lists.llvm.org
Wed Jan 19 16:19:02 PST 2022



> On Jan 19, 2022, at 4:28 AM, Pavel Labath <pavel at labath.sk> wrote:
> 
> On 19/01/2022 00:38, Greg Clayton wrote:
>> Platforms can contain connection specific setting and data. You might want to create two different "remote-linux" platforms and connect each one to a different remote linux machine. Each target which uses this platform would each be able to fetch files, resolve symbol files, get OS version/build string/kernel info, get set working directory from the remote server they are attached. Since each platform tends to belong to a target and since you might want to create two different targets and have each one connected to a different remote machine, I believe it is fine to have multiple instances.
>> I would vote to almost always create a new instance unless it is the host platform. Though it should be possible to create to targets and possibly set the platform on one target using the platform from another that might already be connected.
>> I am open to suggestions if anyone has any objections.
>> Greg
> 
> I agree that permitting multiple platforms would be a more principled position, but it was not clear to me if that was ever planned to be the case.

This code definitely evolved as time went on. Then we added the remote capabilities. As Jim said, there are two parts for the platform that _could_ be separated: PlatformLocal and PlatformRemote. Horrible names that can be improved upon, I am sure, but just names I quickly came up with.

PlatformLocal would be "what can I do for a platform that only involves finding things on this machine for supporting debugging on a remote platform". This would involve things like:
- where are remote files cached on the local machine for easy access
- where can I locate SDK/NDK stuff that might help me for this platform
- what architectures/triples are supported by this platform so it can be selected
- how to start a debug session for a given binary (which might use parts of PlatformRemote) as platforms like "iOS-simulator" do not require any remote connections to be able to start a process. Same could happen for VM based debugging on a local machine.

PlatformRemote
- get/put files
- get/set working directory
- install executable so OS can see/launch it
- create/delete directories

So as things evolved, everything got thrown into the Platform case and we just made things work as we went. I am sure this can be improved.

> 
> If it was (or if we want it to be), then I think we need to start making bigger distinctions between the platform plugins (classes), and the actual instantiations of those classes. Currently there is no way to refer to "older" instances of the platforms as they all share the same name (the name of the plugin). Like, you can enumerate them through SBDebugger.GetPlatformAtIndex(), but that's about the only thing you can do as all the interfaces (including the SB ones) take a platform _name_ as an argument. This gets particularly confusing as in some circumstances we end up choosing the newer one (e.g. if its the "current" platform) and sometimes the older.
> 
> If we want to do that, then this is what I'd propose:
> a) Each platform plugin and each platform instance gets a name. We enforce the uniqueness of these names (within their category).

Maybe it would be better to maintain the name, but implement an instance identifier for each platform instance?

> b) "platform list" outputs two block -- the list of available plugins and the list of plugin instances

If we added a instance identifier, then we could just show the available plug-in names followed by their instances?

> c) a new "platform create" command to create a platform
>  - e.g. "platform create my-arm-test-machine --plugin remote-linux"

Now we are assuming you want to connect to a remote machine when we create platform? "platform connect" can be used currently if we want to actually connect to a remote platform, but there is a lot of stuff in the iOS platforms that really only deals with finding stuff on the local machine. Each platform plugin in "platform connect" has the ability to create its own unique connection arguments and options which is nice for different platforms.

The creation and connecting should still be done separately. Seeing the arguments you added above leads me to believe this is like a "select" and a "connect" all in one. And each "platform connect" has unique and different arguments and options that are tailored to each plug-in currently.

> d) "platform select" selects the platform with the given /instance/ name
>  - for convenience and compatibility if the name does not refer to any existing platform instance, but it *does* refer to a platform plugin, it would create a platform instance with the same name as the class. (So the first "platform select remote-linux" would create a new instance (also called remote-linux) and all subsequent selects would switch to that one -- a change to existing behavior)

that is fine. We just have to make sure that this still works:

(lldb) platform select remote-linux
(lldb) file /path/to/ios/binary/Foo.app

The target created with "/path/to/ios/binary/Foo.app" should select the "remote-ios" platform. It is fine to always check if "remote-linux" platform would work for this binary first, but when it clearly doesn't, it should fall back to the mechanism that we currently have where we auto select a compatible platform.

The other option is to let "platform select <name>" create a new instance of the platform if an instance already exists? If we are in interactive mode, like in the command interpreter, we can query the user to say "There is already an instance of platform "<name>" that exists, do you want to create a new one?". 

Might also be nice to add a new option that allows us to create a new instance with "--always-create" or something like that in case we do want to have two instances with the same plug-in. Then users of course can select the platform with the unique instance name.

> e) SBPlatform gets a static factory function taking two string arguments

What are the two arguments? We can't change existing LLDB API, but we can add more. Keep that in mind as we ponder changes.

> f) existing SBPlatform constructor (taking one string) creates a new platform instance with a name selected by us (remote-linux, remote-linux-2, etc.), but its use is discouraged/deprecated.
> g) all other existing APIs (command line and SB) remain unchanged but any "platform name" argument is taken to mean the platform instance name, and it has the "platform select" semantics (select if it exists, create if it doesn't)
> 
> I think this would strike a good balance between a consistent interface and preserving existing semantics. The open questions are:
> - is it worth it? While nice in theory, personally I have never actually needed to connect to more than one machine at the same time.

I don't want to prevent it. So if we can design a way for this to be able to happen still, I would like to see us not disallow this somehow.

> - what to do about platform-specific settings. The functionality has existed for a long time, but there was only one plugin (PlatformDarwinKernel) using it. I've now added a bunch of settings to the qemu-user platform on the assumption that there will only be one instance of the class. These are global, but they would really make more sense on a per-instance basis. We could either leave it be (I don't need multiple instances now), or come up with a way to have per-platform settings, similar like we do for targets. We could also do something with the "platform settings" command, which currently only sets the working directory.

Each setting has the option of saying "I am a global setting" or "I am an instance setting". It should be easy to set the right settings up as global or instance based right?
> 
> Let me know what you think,
> Pavel


So a few things about platforms as they currently work in LLDB: we currently rely on many targets being able to share the same platform when running the remote test suites. This allows you to select the platform, connect to "lldb-server platform ..." that is running on the remote machine, and then create as many targets as you want and debug to that connected platform. We need to make sure this flow is still possible with any changes we make.




More information about the lldb-dev mailing list