This is an archive of the discontinued LLVM Phabricator instance.

Make remote-android local ports configurable
ClosedPublic

Authored by mark2185 on Oct 21 2022, 9:42 AM.

Details

Summary

The local ports for platform connect and attach were always random, this allows the user to configure them.
This is useful for debugging a truly remote android (when the android in question is connected to a remote server).

There is a lengthier discussion on github - https://github.com/llvm/llvm-project/issues/58114

Diff Detail

Event Timeline

mark2185 created this revision.Oct 21 2022, 9:42 AM
Herald added a project: Restricted Project. · View Herald TranscriptOct 21 2022, 9:42 AM
Herald added a subscriber: danielkiss. · View Herald Transcript
mark2185 requested review of this revision.Oct 21 2022, 9:42 AM
Herald added a project: Restricted Project. · View Herald TranscriptOct 21 2022, 9:42 AM
mark2185 edited the summary of this revision. (Show Details)Oct 21 2022, 9:44 AM
mark2185 added reviewers: clayborg, jingham.

I don't have the expertise to review, but have one question.

Does this account for the situation where you spawn many gdbserver from the platform and therefore need more ports? Does it even need to? (just guessing that that could have been the reason for selecting random ports, though not for the platform)

Does this account for the situation where you spawn many gdbserver from the platform and therefore need more ports? Does it even need to? (just guessing that that could have been the reason for selecting random ports, though not for the platform)

To be honest, I don't know. In all of my testing of practical use cases (i.e. launching an app and debugging it either through CodeLLDB/vscode-lldb or Android Studio), I've only ever seen two ports. One for the platform (when running platform connect), and one for gdb (when trying to attach to a PID).

git blame points to this, as previously it was using the port specified when launching lldb-server for the local port, but it turns out it's better to have a random one and then forward it. And it makes sense, since the device you're trying to debug is very likely plugged into the same machine as you're running ADB on, which is perfect for local development.

But that wasn't good enough for the use case I have.

Ok, so this change means that the randomisation still happens, unless you override it with these environment variables? This seems like a good way to do it.

Where do these env vars need to be set? On the local machine, on the lldb-server machine, on the device?

Ok, so this change means that the randomisation still happens, unless you override it with these environment variables? This seems like a good way to do it.

Exactly, this is completely opt-in. This approach with environment variables was easy enough, and it was used in other things related to adb so it seemed fitting. Maybe it would be better to set it through platform settings, but I'd rather have someone chip in on that.

Also the burden of making sure the ports are actually free is on the user, but I'm guessing the user is aware of this since they are using custom ports.

Where do these env vars need to be set? On the local machine, on the lldb-server machine, on the device?

These are client-side variables, since that is where the user is launching lldb from. adb will only get a request forward tcp:<my-port> tcp:<platform-port> instead of forward tcp:<random> tcp:<platform-port>.

Is there any way to test this?

lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp
95–97

remove {} for single line if statements per LLVM coding guidelines

136–138

remove {} for single line if statements per LLVM coding guidelines

Is there any way to test this?

Through the test suite? I couldn't find any android platform related tests, and this would require adb to be running in the background, so I'm not sure how to approach it.

As for manually testing, three shells are needed (one for lldb-server, one for lldb, and one to check the ports).

(shell-1) $> adb push /path/to/correct/cpu/arch/lldb-server /data/local/tmp   # (android studio comes with prebuilt servers)
(shell-1) $> adb shell /data/local/tmp/lldb-server platform --listen "*:5555"
(shell-2) $> ANDROID_PLATFORM_LOCAL_PORT=8888 lldb
(lldb) $> platform select remote-android
(lldb) $> platform connect connect://localhost:5555
(shell-3) $> adb forward --list
<phone-serial-ID> tcp:8888 tcp:5555

If one were to omit the ANDROID_PLATFORM_LOCAL_PORT variable, the forwarded port will be random.

As for testing the ANDROID_PLATFORM_LOCAL_GDB_PORT, one would need to:

  • install an app on the device
  • run the lldb-server as that app ( adb shell run-as com.full.package.App ./lldb-server platform... ) so it can attach to its PID
  • after platform connect run attach <PID>
  • adb forward --list will now show two forwarded ports
    • the ANDROID_PLATFORM_LOCAL_PORT from before
    • the ANDROID_PLATFORM_LOCAL_GDB_PORT, forwarded to some port on the device (that destination port is also random, unless lldb-server is started with the --gdbserver-port argument, or --min-gdbserver-port and --max-gdbserver-port that limit its possible range)
mark2185 updated this revision to Diff 470381.Oct 24 2022, 11:20 PM

Remove {} for single line if statements per LLVM coding guidelines

mark2185 marked 2 inline comments as done.Oct 24 2022, 11:25 PM

Did I just overwrite the initial commit with a new one, instead of just creating a diff based on the two comments?

I'm terribly sorry, should I just squash my two commits and run arc diff --update=D136465 again?

Yes, somehow, and yes just update again.

Happens to us all, I have learned to not try to be clever with arc and just keep one commit per review.

Tip: if you look in the "Revision Contents" box there is a "history" and you can diff between versions of the patch, if you're ever not sure of what actually changed.

mark2185 updated this revision to Diff 470421.Oct 25 2022, 2:13 AM

Make remote-android local ports configurable

The local ports for platform connect and attach were always random, this allows the user to configure them.
This is useful for debugging a truly remote android (when the android in question is connected to a remote server).

Looks ok to me. I don't do Android stuff on a daily basis. As long as the old way of connecting still works I think this is ok.

It would be great to get more stuff in the Android remove platform connection working at some point. Users still have to manually install things and a lot of the work gets done by the Android Studio IDE kind of like Xcode does. I would love to us add some features in the future:

  • allow a lldb_private::Target to have an application bundle FileSpec, which could be pointed to a .apk file for Android and a .ipa file for iOS
  • Implement PlatformAndroid::LaunchProcess
    • implement "Status PlatformAndroid::Install(const FileSpec &src, const FileSpec &dst)" and handle APK files from target by doing "adb install" if needed
    • Have PlatformAndroid::LaunchProcess do everything that is needed to debug the app
      • start lldb-server for the new process via the connect to the "lldb-server platform" process
      • forward any ports needed

It would be great at some point to be able to do something like:

(lldb) platform select remote-android
(lldb) platform connect ...
(lldb) target create --app-bundle /path/to/foo.apk
(lldb) run

And have PlatformAndroid take care of everything for us.

clayborg accepted this revision.Oct 25 2022, 4:47 PM
This revision is now accepted and ready to land.Oct 25 2022, 4:47 PM

Looks ok to me. I don't do Android stuff on a daily basis. As long as the old way of connecting still works I think this is ok.

Great! I'd just like to note that I do not have commit access, per the guide's instructions.

It would be great to get more stuff in the Android remove platform connection working at some point. Users still have to manually install things and a lot of the work gets done by the Android Studio IDE kind of like Xcode does. I would love to us add some features in the future:

  • allow a lldb_private::Target to have an application bundle FileSpec, which could be pointed to a .apk file for Android and a .ipa file for iOS
  • Implement PlatformAndroid::LaunchProcess
    • implement "Status PlatformAndroid::Install(const FileSpec &src, const FileSpec &dst)" and handle APK files from target by doing "adb install" if needed
    • Have PlatformAndroid::LaunchProcess do everything that is needed to debug the app
      • start lldb-server for the new process via the connect to the "lldb-server platform" process
      • forward any ports needed

It would be great at some point to be able to do something like:

(lldb) platform select remote-android
(lldb) platform connect ...
(lldb) target create --app-bundle /path/to/foo.apk
(lldb) run

And have PlatformAndroid take care of everything for us.

That does sound pretty useful, and even Android Studio would benefit from it since currently it just pushes a shell script that launches the lldb-server. I'll see what I can do.

Great! I'd just like to note that I do not have commit access, per the guide's instructions.

What name/email address do you want on the commit?

mark2185 added a comment.EditedOct 26 2022, 12:28 AM

What name/email address do you want on the commit?

Luka Markušić (markusicluka@gmail.com)

Thanks!

This revision was automatically updated to reflect the committed changes.

Thanks for your efforts here, very much appreciated.