Skip to content

Commit dc3d3f0

Browse files
author
git apple-llvm automerger
committed
Merge commit 'a6fb3b3c18fd' from llvm.org/main into next
2 parents 2619e5f + a6fb3b3 commit dc3d3f0

File tree

5 files changed

+91
-20
lines changed

5 files changed

+91
-20
lines changed

lldb/source/Plugins/Process/minidump/MinidumpParser.cpp

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -108,13 +108,21 @@ MinidumpParser::GetThreadContext(const minidump::Thread &td) {
108108

109109
llvm::ArrayRef<uint8_t>
110110
MinidumpParser::GetThreadContextWow64(const minidump::Thread &td) {
111+
Log *log = GetLog(LLDBLog::Process);
111112
// On Windows, a 32-bit process can run on a 64-bit machine under WOW64. If
112113
// the minidump was captured with a 64-bit debugger, then the CONTEXT we just
113114
// grabbed from the mini_dump_thread is the one for the 64-bit "native"
114115
// process rather than the 32-bit "guest" process we care about. In this
115116
// case, we can get the 32-bit CONTEXT from the TEB (Thread Environment
116117
// Block) of the 64-bit process.
117-
auto teb_mem = GetMemory(td.EnvironmentBlock, sizeof(TEB64));
118+
auto teb_mem_maybe = GetMemory(td.EnvironmentBlock, sizeof(TEB64));
119+
if (!teb_mem_maybe) {
120+
LLDB_LOG_ERROR(log, teb_mem_maybe.takeError(),
121+
"Failed to read Thread Environment Block: {0}");
122+
return {};
123+
}
124+
125+
auto teb_mem = *teb_mem_maybe;
118126
if (teb_mem.empty())
119127
return {};
120128

@@ -126,8 +134,16 @@ MinidumpParser::GetThreadContextWow64(const minidump::Thread &td) {
126134
// Slot 1 of the thread-local storage in the 64-bit TEB points to a structure
127135
// that includes the 32-bit CONTEXT (after a ULONG). See:
128136
// https://msdn.microsoft.com/en-us/library/ms681670.aspx
129-
auto context =
137+
auto context_maybe =
130138
GetMemory(wow64teb->tls_slots[1] + 4, sizeof(MinidumpContext_x86_32));
139+
if (!context_maybe) {
140+
LLDB_LOG_ERROR(log, context_maybe.takeError(),
141+
"Failed to read WOW Thread Context: {0}");
142+
return {};
143+
}
144+
145+
auto context = *context_maybe;
146+
131147
if (context.size() < sizeof(MinidumpContext_x86_32))
132148
return {};
133149

@@ -478,11 +494,13 @@ void MinidumpParser::PopulateMemoryRanges() {
478494
m_memory_ranges.Sort();
479495
}
480496

481-
llvm::ArrayRef<uint8_t> MinidumpParser::GetMemory(lldb::addr_t addr,
482-
size_t size) {
497+
llvm::Expected<llvm::ArrayRef<uint8_t>>
498+
MinidumpParser::GetMemory(lldb::addr_t addr, size_t size) {
483499
std::optional<minidump::Range> range = FindMemoryRange(addr);
484500
if (!range)
485-
return {};
501+
return llvm::createStringError(
502+
llvm::inconvertibleErrorCode(),
503+
"No memory range found for address (0x%" PRIx64 ")", addr);
486504

487505
// There's at least some overlap between the beginning of the desired range
488506
// (addr) and the current range. Figure out where the overlap begins and
@@ -491,7 +509,11 @@ llvm::ArrayRef<uint8_t> MinidumpParser::GetMemory(lldb::addr_t addr,
491509
const size_t offset = addr - range->start;
492510

493511
if (addr < range->start || offset >= range->range_ref.size())
494-
return {};
512+
return llvm::createStringError(
513+
llvm::inconvertibleErrorCode(),
514+
"Address (0x%" PRIx64 ") is not in range [0x%" PRIx64 " - 0x%" PRIx64
515+
")",
516+
addr, range->start, range->start + range->range_ref.size());
495517

496518
const size_t overlap = std::min(size, range->range_ref.size() - offset);
497519
return range->range_ref.slice(offset, overlap);

lldb/source/Plugins/Process/minidump/MinidumpParser.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,8 @@ class MinidumpParser {
104104

105105
std::optional<Range> FindMemoryRange(lldb::addr_t addr);
106106

107-
llvm::ArrayRef<uint8_t> GetMemory(lldb::addr_t addr, size_t size);
107+
llvm::Expected<llvm::ArrayRef<uint8_t>> GetMemory(lldb::addr_t addr,
108+
size_t size);
108109

109110
/// Returns a list of memory regions and a flag indicating whether the list is
110111
/// complete (includes all regions mapped into the process memory).

lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -322,12 +322,15 @@ size_t ProcessMinidump::ReadMemory(lldb::addr_t addr, void *buf, size_t size,
322322
size_t ProcessMinidump::DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
323323
Status &error) {
324324

325-
llvm::ArrayRef<uint8_t> mem = m_minidump_parser->GetMemory(addr, size);
326-
if (mem.empty()) {
327-
error = Status::FromErrorString("could not parse memory info");
325+
llvm::Expected<llvm::ArrayRef<uint8_t>> mem_maybe =
326+
m_minidump_parser->GetMemory(addr, size);
327+
if (!mem_maybe) {
328+
error = Status::FromError(mem_maybe.takeError());
328329
return 0;
329330
}
330331

332+
llvm::ArrayRef<uint8_t> mem = *mem_maybe;
333+
331334
std::memcpy(buf, mem.data(), mem.size());
332335
return mem.size();
333336
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Check that looking up a memory region not present in the Minidump fails
2+
# even if it's in the /proc/<pid>/maps file.
3+
4+
# RUN: yaml2obj %s -o %t
5+
# RUN: %lldb -c %t -o "memory read 0x5000" 2>&1 | FileCheck %s
6+
7+
# CHECK-LABEL: (lldb) memory read 0x5000
8+
# CHECK-NEXT: error: No memory range found for address (0x5000)
9+
10+
--- !minidump
11+
Streams:
12+
- Type: SystemInfo
13+
Processor Arch: AMD64
14+
Processor Level: 6
15+
Processor Revision: 15876
16+
Number of Processors: 40
17+
Platform ID: Linux
18+
CSD Version: 'Linux 3.13.0-91-generic #138-Ubuntu SMP Fri Jun 24 17:00:34 UTC 2016 x86_64'
19+
CPU:
20+
Vendor ID: GenuineIntel
21+
Version Info: 0x00000000
22+
Feature Info: 0x00000000
23+
- Type: LinuxProcStatus
24+
Text: |
25+
Name: test-yaml
26+
Umask: 0002
27+
State: t (tracing stop)
28+
Pid: 8567
29+
- Type: LinuxMaps
30+
Text: |
31+
0x1000-0x1100 r-xp 00000000 00:00 0
32+
0x2000-0x2200 rw-p 00000000 00:00 0
33+
0x4000-0x6000 rw-- 00000000 00:00 0
34+
- Type: Memory64List
35+
Memory Ranges:
36+
- Start of Memory Range: 0x1000
37+
Data Size: 0x100
38+
Content : ''
39+
- Start of Memory Range: 0x2000
40+
Data Size: 0x200
41+
Content : ''
42+
...

lldb/unittests/Process/minidump/MinidumpParserTest.cpp

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -308,16 +308,19 @@ TEST_F(MinidumpParserTest, GetMemory) {
308308
)"),
309309
llvm::Succeeded());
310310

311-
EXPECT_EQ((llvm::ArrayRef<uint8_t>{0x54}), parser->GetMemory(0x401d46, 1));
312-
EXPECT_EQ((llvm::ArrayRef<uint8_t>{0x54, 0x21}),
313-
parser->GetMemory(0x401d46, 4));
314-
315-
EXPECT_EQ((llvm::ArrayRef<uint8_t>{0xc8, 0x4d, 0x04, 0xbc, 0xe9}),
316-
parser->GetMemory(0x7ffceb34a000, 5));
317-
EXPECT_EQ((llvm::ArrayRef<uint8_t>{0xc8, 0x4d, 0x04}),
318-
parser->GetMemory(0x7ffceb34a000, 3));
319-
320-
EXPECT_EQ(llvm::ArrayRef<uint8_t>(), parser->GetMemory(0x500000, 512));
311+
EXPECT_THAT_EXPECTED(parser->GetMemory(0x401d46, 1),
312+
llvm::HasValue(llvm::ArrayRef<uint8_t>{0x54}));
313+
EXPECT_THAT_EXPECTED(parser->GetMemory(0x401d46, 4),
314+
llvm::HasValue(llvm::ArrayRef<uint8_t>{0x54, 0x21}));
315+
EXPECT_THAT_EXPECTED(
316+
parser->GetMemory(0x7ffceb34a000, 5),
317+
llvm::HasValue(llvm::ArrayRef<uint8_t>{0xc8, 0x4d, 0x04, 0xbc, 0xe9}));
318+
EXPECT_THAT_EXPECTED(
319+
parser->GetMemory(0x7ffceb34a000, 3),
320+
llvm::HasValue(llvm::ArrayRef<uint8_t>{0xc8, 0x4d, 0x04}));
321+
EXPECT_THAT_EXPECTED(
322+
parser->GetMemory(0x500000, 512),
323+
llvm::FailedWithMessage("No memory range found for address (0x500000)"));
321324
}
322325

323326
TEST_F(MinidumpParserTest, FindMemoryRangeWithFullMemoryMinidump) {

0 commit comments

Comments
 (0)