This is an archive of the discontinued LLVM Phabricator instance.

gdb-remote: Add jModulesInfo packet
ClosedPublic

Authored by labath on Sep 5 2016, 8:13 AM.

Details

Summary

This adds the jModulesInfo packet, which is the equivalent of qModulesInfo, but it enables us to
query multiple modules at once. This makes a significant speed improvement in case the
application has many (over a hundred) modules, and the communication link has a non-negligible
latency. This functionality is accessed by ProcessGdbRemote::PrefetchModuleSpecs(), which does
the caching. GetModuleSpecs() is modified to first consult the cache before asking the remote
stub. PrefetchModuleSpecs is currently only called from POSIX-DYLD dynamic loader plugin, after
it reads the list of modules from the inferior memory, but other uses are possible.

This decreases the attach time to an android application by about 40%.

Diff Detail

Repository
rL LLVM

Event Timeline

labath updated this revision to Diff 70333.Sep 5 2016, 8:13 AM
labath retitled this revision from to gdb-remote: Add jModulesInfo packet.
labath updated this object.
labath added a reviewer: clayborg.
labath added a subscriber: lldb-commits.
labath updated this revision to Diff 70409.Sep 6 2016, 9:08 AM
  • fix a bug where we would mark all modules as invalid if communicating with a stub which does not support this packet
  • extend the packet documentation about what to do when modules are not found and the server volunteering information
clayborg requested changes to this revision.Sep 6 2016, 9:32 AM
clayborg edited edge metadata.

Jason Molenda already has a packet that does multiple module infos. Is this change using his packet format? Look for "jGetLoadedDynamicLibrariesInfos". We should try to use the same format since this already exists.

This revision now requires changes to proceed.Sep 6 2016, 9:32 AM

Hm... I was not aware of that packet. It does not appear to be directly applicable to this situation, because it queries the module information by load address, whereas here I query by file path. Also my packet does not return the segment/section information.

However, the dynamic linker plugin does know about load addresses so it could possibly be made to work with that packet. I'll need to study this tomorrow to understand how is that packet used. Consistency sounds like a good thing here, although the packet does seem to be making a lot of mac-specific assumptions.

Just take a look and see if there is anything worth re-using. If there is too much mac specific stuff in there, then just use the one created, but be sure to make it your new format completely agnostic to any platform so it can work for anything. It is OK to include platform specific keys that might be needed if the format, just place them in an appropriate dictionary, like

"macos" : { "cputype" : 123, "cpusubtype" : 234 }

If you need info on all shared libraries though, why not just use the XML version that already exists?

Error ProcessGDBRemote::GetLoadedModuleList (LoadedModuleInfoList & list);

This uses the "libraries-svr4" packet that gets XML for all shared libraries. Is there information missing in that format that you require?

labath added a comment.Sep 7 2016, 8:51 AM

Ok, after a bit more digging, this is what I have found:

Error ProcessGDBRemote::GetLoadedModuleList (LoadedModuleInfoList & list);

This packet is not usable in it's current form as it does not include the UUID of the module. As far as I can tell, it is intended to provide the information present in the dynamic linker's rendezvous structure, which is something that we retrieve using memory reads at the moment (POSIX-DYLD plugin has support for the packet, but lldb-server does not implement it). It would probably be possible to extend that packet to include the UUID, but that would not be competely trivial as it would require the reimplementation of a large part (the one that reads out the rendezvous structure) of the POSIX-DYLD plugin on the server side. This is something we may want to do eventually, as reading out of the rendezvous structure (it's a linked list) is also quite slow, but it is not the bottleneck at the moment. So I am a bit reluctant to tie these two things together, as this is a big win already.

jGetLoadedDynamicLibrariesInfos

This looks like a mac-specific version of the previous packet. It does include the UUID, but it also includes some mac-specific fields I don't need. It also has the same issue that it would require the remote side to traverse the rendezvous structure to retrieve the list of libraries. Given the choice between these two packets, I'd go with extending the first one, as POSIX-DYLD plugin already has some support for the "libraries-svr4" packet.

In a way, the packet I am introducing is not really comparable the these two packets. It queries the UUID based on file name, which is an operation which does not even require a running process, whereas the previous two packets deal with reading out the loaded modules from an existing process - it's basically a batch version of the qModuleInfo packet - it's only connection to the dynamic linker is that the dynamic linker knows the names of the modules we will query. (BTW, is the qModuleInfo packet used on darwin targets?)

So, my proposal would be the following: keep this packet as-is (it contains no platform-specific info, so it can be used elsewhere in similar ways that qModuleInfo is), and if we do implement server-side rendezvous structure parsing, then we can remove this packet (assuming to new uses for it have been invented).

What do you think?

clayborg accepted this revision.Sep 7 2016, 8:56 AM
clayborg edited edge metadata.

Sounds good. As long as we know what is there (the XML and Jason's other packet) and know that the desired functionalities do not overlap I am fine with the approach that you suggest! Thanks for looking into it and making sure we don't duplicate functionality.

This revision is now accepted and ready to land.Sep 7 2016, 8:56 AM
This revision was automatically updated to reflect the committed changes.