Skip to content

Commit 499f723

Browse files
committed
[lldb][core] Fix getting summary of a variable pointing to r/o memory
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 0389640 commit 499f723

File tree

4 files changed

+39
-1
lines changed

4 files changed

+39
-1
lines changed

lldb/source/ValueObject/ValueObject.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -735,14 +735,25 @@ size_t ValueObject::GetPointeeData(DataExtractor &data, uint32_t item_idx,
735735
case eAddressTypeLoad: {
736736
ExecutionContext exe_ctx(GetExecutionContextRef());
737737
Process *process = exe_ctx.GetProcessPtr();
738-
if (process) {
738+
if (process && process->IsLiveDebugSession()) {
739739
heap_buf_ptr->SetByteSize(bytes);
740740
size_t bytes_read = process->ReadMemory(
741741
addr + offset, heap_buf_ptr->GetBytes(), bytes, error);
742742
if (error.Success() || bytes_read > 0) {
743743
data.SetData(data_sp);
744744
return bytes_read;
745745
}
746+
} else if (Target *target = exe_ctx.GetTargetPtr()) {
747+
Address target_addr;
748+
target_addr.SetLoadAddress(addr + offset, target);
749+
heap_buf_ptr->SetByteSize(bytes);
750+
size_t bytes_read =
751+
target->ReadMemory(target_addr, heap_buf_ptr->GetBytes(), bytes,
752+
error, /*force_live_memory=*/true);
753+
if (error.Success() || bytes_read > 0) {
754+
data.SetData(data_sp);
755+
return bytes_read;
756+
}
746757
}
747758
} break;
748759
case eAddressTypeHost: {

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

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -977,6 +977,33 @@ 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_ro_cstring(self):
982+
"""
983+
Test that we can show the summary for a cstring variable that points
984+
to a r/o 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 RO segment that is not dumped to the core
996+
# file and thus process.ReadCStringFromMemory() cannot get the value.
997+
error = lldb.SBError()
998+
cstr = process.ReadCStringFromMemory(var.GetValueAsUnsigned(), 256, error)
999+
self.assertFailure(error, error_str="core file does not contain 0x804a000")
1000+
self.assertEqual(cstr, "")
1001+
1002+
# Nevertheless, when getting the summary, the value can be read from the
1003+
# application binary.
1004+
cstr = var.GetSummary()
1005+
self.assertEqual(cstr, '"_start"')
1006+
9801007
def check_memory_regions(self, process, region_count):
9811008
region_list = process.GetMemoryRegions()
9821009
self.assertEqual(region_list.GetSize(), region_count)
Binary file not shown.
9.55 KB
Binary file not shown.

0 commit comments

Comments
 (0)