Skip to content

Commit 3f196e0

Browse files
authored
[lldb][core] Fix getting summary of a variable pointing to r/o memory (#139196)
Motivation example: ``` > lldb -c altmain2.core ... (lldb) var F (const char *) F = 0x0804a000 "" ``` The variable `F` points to a read-only memory page not dumped to the core file, so `Process::ReadMemory()` cannot read the data. The patch switches to `Target::ReadMemory()`, which can read data both from the process memory and the application binary.
1 parent 5aa3171 commit 3f196e0

File tree

4 files changed

+34
-4
lines changed

4 files changed

+34
-4
lines changed

lldb/source/ValueObject/ValueObject.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -734,11 +734,13 @@ size_t ValueObject::GetPointeeData(DataExtractor &data, uint32_t item_idx,
734734
} break;
735735
case eAddressTypeLoad: {
736736
ExecutionContext exe_ctx(GetExecutionContextRef());
737-
Process *process = exe_ctx.GetProcessPtr();
738-
if (process) {
737+
if (Target *target = exe_ctx.GetTargetPtr()) {
739738
heap_buf_ptr->SetByteSize(bytes);
740-
size_t bytes_read = process->ReadMemory(
741-
addr + offset, heap_buf_ptr->GetBytes(), bytes, error);
739+
Address target_addr;
740+
target_addr.SetLoadAddress(addr + offset, target);
741+
size_t bytes_read =
742+
target->ReadMemory(target_addr, heap_buf_ptr->GetBytes(), bytes,
743+
error, /*force_live_memory=*/true);
742744
if (error.Success() || bytes_read > 0) {
743745
data.SetData(data_sp);
744746
return bytes_read;

lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -977,6 +977,34 @@ def test_get_core_file_api(self):
977977
self.assertEqual(process.GetCoreFile().GetFilename(), core_file_name)
978978
self.dbg.DeleteTarget(target)
979979

980+
@skipIfLLVMTargetMissing("X86")
981+
def test_read_only_cstring(self):
982+
"""
983+
Test that we can show the summary for a cstring variable that points
984+
to a read-only memory page which is not dumped to a core file.
985+
"""
986+
target = self.dbg.CreateTarget("altmain2.out")
987+
process = target.LoadCore("altmain2.core")
988+
self.assertTrue(process, PROCESS_IS_VALID)
989+
990+
frame = process.GetSelectedThread().GetFrameAtIndex(0)
991+
self.assertEqual(frame.GetFunctionName(), "_start")
992+
993+
var = frame.FindVariable("F")
994+
995+
# The variable points to a read-only segment that is not dumped to
996+
# the core file and thus 'process.ReadCStringFromMemory()' cannot get
997+
# the value.
998+
error = lldb.SBError()
999+
cstr = process.ReadCStringFromMemory(var.GetValueAsUnsigned(), 256, error)
1000+
self.assertFailure(error, error_str="core file does not contain 0x804a000")
1001+
self.assertEqual(cstr, "")
1002+
1003+
# Nevertheless, when getting the summary, the value can be read from the
1004+
# application binary.
1005+
cstr = var.GetSummary()
1006+
self.assertEqual(cstr, '"_start"')
1007+
9801008
def check_memory_regions(self, process, region_count):
9811009
region_list = process.GetMemoryRegions()
9821010
self.assertEqual(region_list.GetSize(), region_count)
Binary file not shown.
Binary file not shown.

0 commit comments

Comments
 (0)