This is an archive of the discontinued LLVM Phabricator instance.

[lldb/crashlog] Make module loading use Scripted Process affordance
Needs ReviewPublic

Authored by mib on Jan 13 2023, 9:42 AM.

Details

Summary

This patch changes the way modules get loaded in lldb when using
interactive crashlog. It takes advantage of a Scripted Process
affordance to let lldb fetch symbols in parallel and load modules itself.

This also allows us to report progress on module loading to the user.

Signed-off-by: Med Ismail Bennani <medismail.bennani@gmail.com>

Diff Detail

Event Timeline

mib created this revision.Jan 13 2023, 9:42 AM
Herald added a project: Restricted Project. · View Herald TranscriptJan 13 2023, 9:42 AM
mib requested review of this revision.Jan 13 2023, 9:42 AM

I'm somewhat unfamiliar with this code so I'll ask some clarifying questions. I think I understand the idea in general though.

lldb/examples/python/scripted_process/crashlog_scripted_process.py
34–38

I don't understand the intent of this part. It looks like you're changing the format of self.loaded_images here. It's still a List, but instead of containing images it contains specific information about specific sections of each image. If the format has changed, don't consumers of get_loaded_images need to be modified as well?

lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
434–440

Shouldn't you be using the result of Symbols::DownloadObjectAndSymbolFile here? I've read through the implementation of DownloadObjectAndSymbolFile and here's what I've surmised:

  • The non-Darwin implementation of DownloadObjectAndSymbolFile simply returns false, so error won't be populated.
  • The Darwin implementation fills in error only as a result of invoking dsymForUUID and subsequent processing of the result. It's entirely possible for the function to return false before dsymForUUID is invoked or without any useful information in error.

Additionally, it looks like you're doing maybe 2-3 things in this patch (Progress reporting, adding a guard rail, changing the format of loaded_images in the scripted process example). You could probably break this up into multiple patches.

mib marked an inline comment as done.Jan 13 2023, 12:32 PM
mib added inline comments.
lldb/examples/python/scripted_process/crashlog_scripted_process.py
34–38

The list for this specific scripted process class was wrong, it expects the current format. Previously we didn't make use of loaded_images for the crashlog_scripted_process class, we just relied on some ad hoc heuristic to load the modules.
The other consumers of get_loaded_images are fine.

lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
434–440

Good catch!

mib updated this revision to Diff 489102.Jan 13 2023, 12:46 PM
mib marked an inline comment as done.
mib added a reviewer: jasonmolenda.

Address @bulbazord feedback

Seems okay to me.
@JDevlieghere How does this look to you?

lldb/examples/python/scripted_process/crashlog_scripted_process.py
34–38

Ah, that makes sense. If one wanted to know what the format of loaded_images *should* be, how would they find out? Is that information documented or encoded anywhere? Or is it more ad-hoc?

mib marked an inline comment as done.Jan 13 2023, 4:00 PM
mib added inline comments.
lldb/examples/python/scripted_process/crashlog_scripted_process.py
34–38

It's documented in the get_loaded_images in the base ScriptedProcess python class.

JDevlieghere added inline comments.Jan 13 2023, 4:15 PM
lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
435

The last argument here is force_lookup (you should probably add that as an inline comment). This means that for any scripted process (not just interactive crashlogs) we're going to do a dSYMForUUID call (like we do for loading a kernel). I suppose that's what you want for interactive crashlogs, but not for a generic scripted process implementation.

mib updated this revision to Diff 489152.Jan 13 2023, 4:33 PM
mib marked 3 inline comments as done.

Only force symbol lookup for crashlog scripted process.

JDevlieghere requested changes to this revision.Jan 17 2023, 11:47 AM
JDevlieghere added inline comments.
lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
392

This seems inverted: rather than the generic scripted process implementation having to know about a concrete implementation, why not make this a capability that the crashlog can opt into?

This revision now requires changes to proceed.Jan 17 2023, 11:47 AM
bulbazord requested changes to this revision.Jan 17 2023, 11:48 AM
bulbazord added inline comments.
lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
392

Instead of relying on the class name being CrashLog, why not ask the scripted metadata for its capabilities? Something like bool force_lookup = m_scripted_metadata.ShouldForceSymbolFileLookup(); or something to this effect?

mib added inline comments.Jan 18 2023, 1:39 AM
lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
497–498

I'm just thinking about this but I don't see any reason not to run this loop in parallel to accelerate dependency loading ... That could potentially mess up the progress reporting but I think in parallel it might not even be needed. @JDevlieghere Any objections ?

mib updated this revision to Diff 491006.Jan 20 2023, 4:40 PM
mib updated this revision to Diff 491007.
mib edited the summary of this revision. (Show Details)

Address @JDevlieghere & @bulbazord comments

  • Use D142059's ScriptedProcess::GetCapabilities to decide whether we should force symbol lookup.
  • Make symbol fetching parallel.
mib added inline comments.Jan 20 2023, 4:50 PM
lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
505–511

This is not behaving as expected:

  1. During the symbol fetching stage (in parallel), I can see from the progress report messages that it goes pretty fast originally, but when it gets close to end, it gets stuck for few seconds. When I profile LLDB at that point, I can still see multiple calls to DownloadObjectAndSymbolFile which lets me think that the progress reporting doesn't reflect the completion of the symbol fetching but rather just to the creation of dsymForUUID process.
  1. I don't know if this is related to 1. but for some reason, when I try to load the modules, only the module executable gets reloaded. I need to investigate more but may be @JDevlieghere you can see a problem with this implementation ?
JDevlieghere added inline comments.Jan 20 2023, 5:41 PM
lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
505–511
  1. In fetch_symbols you don't increment the progress count when the dsymForUUID calls fails, so as soon as one fails, the progress will never complete. You'll need to either increment the count in the failure path or scope the progress to match the scope of the thread pool. But that doesn't explain why you're still seeing DownloadObjectAndSymbolFile instances.
  2. You need to call debugger::ReportSymbolChange(module_spec); to let the debugger know it needs to reload the symbols.
mib updated this revision to Diff 493453.Jan 30 2023, 4:59 PM

Address @JDevlieghere comments.

mib marked 3 inline comments as done.Feb 8 2023, 1:14 PM
mib updated this revision to Diff 495933.Feb 8 2023, 1:19 PM

Fixed module loading issue.

Just a personal preference but making those lambdas into static functions may make it easier to read.

bulbazord accepted this revision.Aug 10 2023, 10:23 AM

Sorry, this fell off my radar for a while. I re-read through it and it looks fine to me, the lambda vs static methods function thing doesn't really matter much. LGTM.