Returning multiple values in Python API function

Hi all,

I'm looking to add Platform::LaunchGDBServer() to the SBPlatform API,
but it requires two return values - an lldb::pid_t and a string url.
Internally, we just pass by reference, but we can't do that in the
API. Any suggestions on how to do this, since we can't pass primitives
by reference from Python?

My current thinking was to use the pid_t as the return value, and then
figure out a way to communicate the string information as an "out"
function parameter. Ideas there included using an SBStream&, as the
GetDescription() functions do, but that doesn't seem optimal.

In standard Python, we'd just use a tuple return value, but I don't
see any way to do that using the swig interface.

The reasoning behind adding this API function is to prevent the
platform-mode GdbRemote tests from launching the gdbserver using an
'A' packet instead of the standard 'qLaunchGDBServer' packet.

Thanks,
Francis

I am still unclear as to why you want this? An lldb-server that is launched in platform mode shouldn't use the 'A' packet at all. Can you elaborate on why you need this more? Why do we need to prevent it from using an 'A' packet in the first place? What is leading to this happening? Why do you want to launch on manually?

Greg

Hi all,

I'm looking to add Platform::LaunchGDBServer() to the SBPlatform API,
but it requires two return values - an lldb::pid_t and a string url.
Internally, we just pass by reference, but we can't do that in the
API. Any suggestions on how to do this, since we can't pass primitives
by reference from Python?

My current thinking was to use the pid_t as the return value, and then
figure out a way to communicate the string information as an "out"
function parameter. Ideas there included using an SBStream&, as the
GetDescription() functions do, but that doesn't seem optimal.

In standard Python, we'd just use a tuple return value, but I don't
see any way to do that using the swig interface.

The reasoning behind adding this API function is to prevent the
platform-mode GdbRemote tests from launching the gdbserver using an
'A' packet instead of the standard 'qLaunchGDBServer' packet.

I am still unclear as to why you want this? An lldb-server that is launched in platform mode shouldn't use the 'A' packet at all.

Right. The problem is that our test suite (specifically the
lldb-server tests) uses the 'A' packet to spawn the inferior for
lldb-server's which are launched in platform mode.

Can you elaborate on why you need this more? Why do we need to prevent it from using an 'A' packet in the first place? What is leading to this happening?

gdbremote_testcase.py, in launch_debug_monitor, calls
self.spawnSubprocess() on the lldb-server exe.

This in turn calls _RemoteProcess.launch() in lldbtest.py, which calls
lldb.remote_platform.Launch(), which will use the 'A' packet, with the
path to the lldb-server.

I think this is broken, and the qLaunchGDBServer packet should be used
instead. The problem is that there currently isn't a good way to use
this packet from the Python API.

It is somewhat odd to me that the platform-mode lldb-server even
accepts the 'A' packet, but it appears to, given that the `Handle_A`
method is contained in `GDBRemoteCommunicationServerCommon` and not
`GDBRemoteCommunicationServerLLGS`.

Why do you want to launch on manually?

As far as I know, the lldb-server tests send packets manually in
general, since they don't run with the full lldb, and just a python
stub to test the remote protocols.

Yes, but then it calls into virtual
GDBRemoteCommunicationServerCommon::LaunchProcess, which is
implemented differently in the platform and gdb-remote instance.

What is the actual problem you are trying to solve here? It it's just
the fact that we use the A packet to launch non-debuggable processes,
then I think you should just change which packet is used by
PlatformRemoteGDBServer::LaunchProcess. I don't see the need for a new
API.

Is there any issue that arises from launching the server instance via
A packet instead of qLaunchGDBServer? The way I understand these
tests, they're supposed to test the capabilities of LLGS in isolation.
The way you start the LLGS instance is peripheral. In fact it may be
even better to isolate the launching process from whatever magic
qLaunchGDBServer is doing. Also, giving the tests more control over
how you start the LLGS instance means you can test starting it in a
way that it would not be started by qLaunchGDBServer. (e.g. I don't
think you can convince that packet to run LLGS in the
"inferior-supplied-on-the-command-line mode" (lldb-server g --
./a.out), which is still a valid mode of using the tool and needs to
be tested).

pl

The 'A' packet is for launching a process that is to be debugged only, it isn't supposed to be used just to launch a process that should just run. If the 'A' packet is being used in lldb-server in platform mode, then it is just wrong. We should probably pull it out of the server, or return an error if it gets used in platform mode.

Greg