This is an archive of the discontinued LLVM Phabricator instance.

[lldb/Plugins] Add memory region support in ScriptedProcess
ClosedPublic

Authored by mib on Aug 30 2021, 3:59 PM.

Details

Summary

This patch adds support for memory regions in Scripted Processes.
This is necessary to read the stack memory region in order to
reconstruct each stackframe of the program.

In order to do so, this patch makes some changes to the SBAPI, namely:

  • Add a new constructor for SBMemoryRegionInfo that takes arguments such as the memory region name, address range, permissions ... This is used when reading memory at some address to compute the offset in the binary blob provided by the user.
  • Add a GetMemoryRegionContainingAddress method to SBMemoryRegionInfoList to simplify the access to a specific memory region.

With these changes, lldb is now able to unwind the stack and reconstruct
each frame. On top of that, reloading the target module at offset 0 allows
lldb to symbolicate the ScriptedProcess using debug info, similarly to an
ordinary Process.

To test this, I wrote a simple program with multiple function calls, ran it in
lldb, stopped at a leaf function and read the registers values and copied
the stack memory into a binary file. These are then used in the python script.

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

Diff Detail

Event Timeline

mib requested review of this revision.Aug 30 2021, 3:59 PM
mib created this revision.
mib updated this revision to Diff 370216.Sep 2 2021, 3:16 AM

Add test.

mib added a comment.Sep 9 2021, 9:15 AM

Following @JDevlieghere question in https://reviews.llvm.org/D107585#2979988, here are some explanations:

In order to read memory from the ScriptedProcess, the process plugin calls the python read_memory_at_address method passing the address at which we should start reading (and the number of bytes to be read).

However, the memory buffer, that provided by the python_script, - usually - starts at offset 0. This is why having memory regions in the python script allows up to:

  1. Check that the address that should be read is in one of the our memory regions.
  2. Shift the address by the region start address so the memory reads are done at the right location.

Using a SB class for Scripted Processes could be risky, since it can introduce a cyclic dependency: If, for instance, we use a facility that is itself backed by an execution context object (process, thread, frame) for one of the Scripted execution context objects, that will cause the C++ object to use a Python object which will again use a C++ object, and so on.

Luckily, this is not an issue for lldb.SBMemoryRegionInfo.

mib updated this revision to Diff 376508.Oct 1 2021, 6:45 AM

Use ScriptedInterface::ErrorWithMessage helper function.

mib updated this revision to Diff 376509.Oct 1 2021, 6:49 AM

Update error message.

I'm slightly worried about the switch from a unique pointer to a shared pointer. It seems like a memory region is a simple enough object that it's warranted to make a copy to avoid this change. WDYT?

mib updated this revision to Diff 377326.Oct 5 2021, 12:10 PM
mib edited the summary of this revision. (Show Details)

Reverted from shared_ptr to unique_ptr for SBMemoryRegionInfo opaque_ptr.

JDevlieghere added inline comments.Oct 5 2021, 8:01 PM
lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
281

If this is the only way out of this loop, does that mean we always return an error here?

mib added inline comments.Oct 6 2021, 6:24 AM
lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
281

In a previous diff, I stopped fetching memory regions if the shared_ptr was null, but now, I only have a memory region object instance which has no IsValid or operator bool() methods ...

Not sure yet how I'll be able to fetch all the memory regions ... I'll have to rethink this.

mib marked an inline comment as done.Oct 6 2021, 4:44 PM
mib updated this revision to Diff 377724.EditedOct 6 2021, 4:47 PM

Change ScriptedProcessPythonInterface::GetMemoryRegionContainingAddress return type to llvm::Optional<MemoryRegionInfo> to stop fetching memory regions without always returning an error.

JDevlieghere accepted this revision.Oct 7 2021, 9:00 AM

LGTM

lldb/examples/python/scripted_process/my_scripted_process.py
126

Aren't format strings only available in Python 3?

This revision is now accepted and ready to land.Oct 7 2021, 9:00 AM
This revision was landed with ongoing or failed builds.Oct 8 2021, 5:55 AM
This revision was automatically updated to reflect the committed changes.