https://github.com/Jlalond updated 
https://github.com/llvm/llvm-project/pull/149401

>From 4e692b251329196ff09aa8fc7d0e329c42df1b50 Mon Sep 17 00:00:00 2001
From: Jacob Lalonde <jalalo...@fb.com>
Date: Wed, 16 Jul 2025 12:57:58 -0700
Subject: [PATCH 1/4] Add check-memory command to see if an address is in a
 Minidump

---
 lldb/include/lldb/Target/MemoryRegionInfo.h   | 30 +++++++
 lldb/include/lldb/Utility/RangeMap.h          | 21 +++++
 .../Process/minidump/MinidumpParser.cpp       | 22 ++++++
 .../Plugins/Process/minidump/MinidumpParser.h |  5 ++
 .../Process/minidump/ProcessMinidump.cpp      | 79 +++++++++++++++++++
 .../Process/minidump/ProcessMinidump.h        |  4 +
 6 files changed, 161 insertions(+)

diff --git a/lldb/include/lldb/Target/MemoryRegionInfo.h 
b/lldb/include/lldb/Target/MemoryRegionInfo.h
index dc37a7dbeda52..ad254084a40d3 100644
--- a/lldb/include/lldb/Target/MemoryRegionInfo.h
+++ b/lldb/include/lldb/Target/MemoryRegionInfo.h
@@ -14,6 +14,7 @@
 #include <vector>
 
 #include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/StreamString.h"
 #include "lldb/Utility/RangeMap.h"
 #include "llvm/Support/FormatProviders.h"
 
@@ -141,6 +142,35 @@ class MemoryRegionInfo {
     m_dirty_pages = std::move(pagelist);
   }
 
+  std::string Dump() const {
+    lldb_private::StreamString stream;
+    stream << "[";
+    stream.PutHex64(GetRange().GetRangeBase());
+    stream << "-";
+    stream.PutHex64(GetRange().GetRangeEnd());
+    stream << ") ";
+    if (m_read == eYes)
+      stream << "r";
+    else if (m_read == eNo)
+      stream << "-";
+    else
+      stream << "?";
+    if (m_write == eYes)
+      stream << "w";
+    else if (m_write == eNo)
+      stream << "-";
+    else
+      stream << "?";
+    if (m_execute == eYes)
+      stream << "x";
+    else if (m_execute == eNo)
+      stream << "-";
+    else 
+      stream << "?";
+
+    return stream.GetString().str();
+  }
+
 protected:
   RangeType m_range;
   OptionalBool m_read = eDontKnow;
diff --git a/lldb/include/lldb/Utility/RangeMap.h 
b/lldb/include/lldb/Utility/RangeMap.h
index e701ae1ba96c8..5bb3d67309cbd 100644
--- a/lldb/include/lldb/Utility/RangeMap.h
+++ b/lldb/include/lldb/Utility/RangeMap.h
@@ -648,6 +648,27 @@ class RangeDataVector {
     return nullptr;
   }
 
+  const Entry *FindEntryThatContainsOrPrior(B addr) const {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+    assert(IsSorted());
+#endif
+    if (!m_entries.empty()) {
+      typename Collection::const_iterator begin = m_entries.begin();
+      typename Collection::const_iterator end = m_entries.end();
+      typename Collection::const_iterator pos = llvm::lower_bound(
+          m_entries, addr, [](const Entry &lhs, B rhs_base) -> bool {
+            return lhs.GetRangeEnd() <= rhs_base;
+          });
+
+      while (pos != begin && pos[-1].Contains(addr))
+        ++pos;
+
+      if (pos != end)
+        return &(*pos);
+    }
+    return nullptr;
+  }
+
   uint32_t FindEntryIndexThatContainsOrFollows(B addr) const {
 #ifdef ASSERT_RANGEMAP_ARE_SORTED
     assert(IsSorted());
diff --git a/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp 
b/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
index 58ebb7be11994..a81213ed858c8 100644
--- a/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
+++ b/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
@@ -711,3 +711,25 @@ MinidumpParser::GetMemoryRegionInfo(const 
MemoryRegionInfos &regions,
   region.SetMapped(MemoryRegionInfo::eNo);
   return region;
 }
+
+std::optional<minidump::Range> 
MinidumpParser::GetClosestPriorRegion(lldb::addr_t load_addr) {
+  if (m_memory_ranges.IsEmpty())
+    PopulateMemoryRanges();
+
+  const MemoryRangeVector::Entry *entry = 
m_memory_ranges.FindEntryThatContainsOrPrior(load_addr);
+  if (!entry)
+    return std::nullopt;
+
+  return entry->data;
+}
+
+std::optional<minidump::Range> 
MinidumpParser::GetClosestFollowingRegion(lldb::addr_t load_addr) {
+  if (m_memory_ranges.IsEmpty())
+    PopulateMemoryRanges();
+
+  const MemoryRangeVector::Entry *entry = 
m_memory_ranges.FindEntryThatContainsOrFollows(load_addr);
+  if (!entry)
+    return std::nullopt;
+
+  return entry->data;
+}
diff --git a/lldb/source/Plugins/Process/minidump/MinidumpParser.h 
b/lldb/source/Plugins/Process/minidump/MinidumpParser.h
index 3b7d33daca717..fdd8600d15054 100644
--- a/lldb/source/Plugins/Process/minidump/MinidumpParser.h
+++ b/lldb/source/Plugins/Process/minidump/MinidumpParser.h
@@ -107,6 +107,11 @@ class MinidumpParser {
   llvm::Expected<llvm::ArrayRef<uint8_t>> GetMemory(lldb::addr_t addr,
                                                     size_t size);
 
+  // Pair of functions to get relative memory regions from the minidump file. 
These aren't for
+  // evaluating the data, but checking the ranges stored in the minidump and 
their permissions.
+  std::optional<Range> GetClosestPriorRegion(lldb::addr_t addr);
+  std::optional<Range> GetClosestFollowingRegion(lldb::addr_t addr);
+
   /// Returns a list of memory regions and a flag indicating whether the list 
is
   /// complete (includes all regions mapped into the process memory).
   std::pair<MemoryRegionInfos, bool> BuildMemoryRegions();
diff --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp 
b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
index 17a421a722743..29494fc13c9ff 100644
--- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
+++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
@@ -601,6 +601,25 @@ bool ProcessMinidump::GetProcessInfo(ProcessInstanceInfo 
&info) {
   return true;
 }
 
+std::optional<lldb_private::MemoryRegionInfo> 
ProcessMinidump::TryGetMemoryRegionInCore(lldb::addr_t addr, 
std::optional<lldb_private::MemoryRegionInfo> &closest_prior_region, 
std::optional<lldb_private::MemoryRegionInfo> &  closest_following_region) {
+  std::optional<minidump::Range> addr_region_maybe = 
m_minidump_parser->FindMemoryRange(addr);
+  if (addr_region_maybe) {
+    MemoryRegionInfo region = 
MinidumpParser::GetMemoryRegionInfo(*m_memory_regions, 
addr_region_maybe->start);
+    return region;
+  }
+
+  // If we didn't find a region, try to find the closest prior and following
+  std::optional<minidump::Range> closest_prior_range_maybe = 
m_minidump_parser->GetClosestPriorRegion(addr);
+  if (closest_prior_range_maybe)
+    closest_prior_region = 
MinidumpParser::GetMemoryRegionInfo(*m_memory_regions, 
closest_prior_range_maybe->start);
+
+  std::optional<minidump::Range> closest_following_range_maybe = 
m_minidump_parser->GetClosestFollowingRegion(addr);
+  if (closest_following_range_maybe)
+    closest_following_region = 
MinidumpParser::GetMemoryRegionInfo(*m_memory_regions, 
closest_following_range_maybe->start);
+
+  return std::nullopt;
+}
+
 // For minidumps there's no runtime generated code so we don't need 
JITLoader(s)
 // Avoiding them will also speed up minidump loading since JITLoaders normally
 // try to set up symbolic breakpoints, which in turn may force loading more
@@ -961,6 +980,65 @@ class CommandObjectProcessMinidumpDump : public 
CommandObjectParsed {
   }
 };
 
+class CommandObjectProcessMinidumpCheckMemory : public CommandObjectParsed {
+public:
+  CommandObjectProcessMinidumpCheckMemory(CommandInterpreter &interpreter)
+  : CommandObjectParsed(interpreter, "process plugin check-memory",
+      "Check if a memory address is stored in the Minidump, or the closest 
ranges.", nullptr) {
+        CommandArgumentEntry arg1;
+        CommandArgumentData addr_arg;
+        addr_arg.arg_type = eArgTypeAddressOrExpression;
+
+        arg1.push_back(addr_arg);
+        m_arguments.push_back(arg1);
+      }
+    
+  void DoExecute(Args &command, CommandReturnObject &result) override {
+    const size_t argc = command.GetArgumentCount();
+    if (argc == 0) {
+      result.AppendErrorWithFormat("'%s' Requires a memory address",
+                                   m_cmd_name.c_str());
+      return;
+    }
+
+    Status error;
+    lldb::addr_t address = OptionArgParser::ToAddress(&m_exe_ctx, 
command[0].ref(),
+                                LLDB_INVALID_ADDRESS, &error);
+
+    if (error.Fail() || address == LLDB_INVALID_ADDRESS) {
+      result.AppendErrorWithFormat("'%s' Is an invalid address.", 
command[0].c_str());
+      return;
+    }
+
+    ProcessMinidump *process = static_cast<ProcessMinidump *>(
+      m_interpreter.GetExecutionContext().GetProcessPtr());
+
+    result.SetStatus(eReturnStatusSuccessFinishResult);
+    std::optional<lldb_private::MemoryRegionInfo> closest_prior_region;
+    std::optional<lldb_private::MemoryRegionInfo> closest_following_region;
+    std::optional<lldb_private::MemoryRegionInfo> memory_region_maybe = 
+        process->TryGetMemoryRegionInCore(address, closest_prior_region, 
closest_following_region);
+
+    if (memory_region_maybe) {
+      result.AppendMessageWithFormat("Address found in Minidump. Address 
located in range: %s", memory_region_maybe->Dump().c_str());
+      return;
+    }
+
+    lldb_private::StreamString result_stream;
+    result_stream << "Address not found in Minidump";
+    if (closest_prior_region)
+      result_stream << "Closest prior range: " << 
closest_prior_region->Dump().c_str();
+    else 
+      result_stream << "No prior range found";
+    if (closest_following_region)
+      result_stream << "Closest superior range: " << 
closest_following_region->Dump().c_str();
+    else 
+      result_stream << "No superior range found";
+    
+    result.AppendMessage(result_stream.GetString());
+  }
+};
+
 class CommandObjectMultiwordProcessMinidump : public CommandObjectMultiword {
 public:
   CommandObjectMultiwordProcessMinidump(CommandInterpreter &interpreter)
@@ -969,6 +1047,7 @@ class CommandObjectMultiwordProcessMinidump : public 
CommandObjectMultiword {
           "process plugin <subcommand> [<subcommand-options>]") {
     LoadSubCommand("dump",
         CommandObjectSP(new CommandObjectProcessMinidumpDump(interpreter)));
+    LoadSubCommand("check-memory", CommandObjectSP(new 
CommandObjectProcessMinidumpCheckMemory(interpreter)));
   }
 
   ~CommandObjectMultiwordProcessMinidump() override = default;
diff --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.h 
b/lldb/source/Plugins/Process/minidump/ProcessMinidump.h
index ad8d0ed7a4832..41132c5d2eacd 100644
--- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.h
+++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.h
@@ -74,6 +74,10 @@ class ProcessMinidump : public PostMortemProcess {
   size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
                       Status &error) override;
 
+  std::optional<lldb_private::MemoryRegionInfo> 
TryGetMemoryRegionInCore(lldb::addr_t addr, 
+                                          
std::optional<lldb_private::MemoryRegionInfo> &closest_prior_region,
+                                          
std::optional<lldb_private::MemoryRegionInfo> &closest_following_region);
+
   ArchSpec GetArchitecture();
 
   Status

>From ff66c231c82da9da77546a8c799ceab962bc424f Mon Sep 17 00:00:00 2001
From: Jacob Lalonde <jalalo...@fb.com>
Date: Thu, 17 Jul 2025 13:27:49 -0700
Subject: [PATCH 2/4] Fix rangemap for entry or prior and add test

---
 lldb/include/lldb/Utility/RangeMap.h          | 11 ++--
 .../Process/minidump/ProcessMinidump.cpp      | 15 +++---
 lldb/test/Shell/Minidump/check-memory.yaml    | 52 +++++++++++++++++++
 3 files changed, 66 insertions(+), 12 deletions(-)
 create mode 100644 lldb/test/Shell/Minidump/check-memory.yaml

diff --git a/lldb/include/lldb/Utility/RangeMap.h 
b/lldb/include/lldb/Utility/RangeMap.h
index 5bb3d67309cbd..894b08493a5cd 100644
--- a/lldb/include/lldb/Utility/RangeMap.h
+++ b/lldb/include/lldb/Utility/RangeMap.h
@@ -654,17 +654,16 @@ class RangeDataVector {
 #endif
     if (!m_entries.empty()) {
       typename Collection::const_iterator begin = m_entries.begin();
-      typename Collection::const_iterator end = m_entries.end();
       typename Collection::const_iterator pos = llvm::lower_bound(
           m_entries, addr, [](const Entry &lhs, B rhs_base) -> bool {
             return lhs.GetRangeEnd() <= rhs_base;
           });
+      
+      if (pos->Contains(addr))
+          return &(*pos);
 
-      while (pos != begin && pos[-1].Contains(addr))
-        ++pos;
-
-      if (pos != end)
-        return &(*pos);
+      if (pos != begin)
+        return &(*std::prev(pos));
     }
     return nullptr;
   }
diff --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp 
b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
index 29494fc13c9ff..4fa312d7533e8 100644
--- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
+++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
@@ -602,6 +602,10 @@ bool ProcessMinidump::GetProcessInfo(ProcessInstanceInfo 
&info) {
 }
 
 std::optional<lldb_private::MemoryRegionInfo> 
ProcessMinidump::TryGetMemoryRegionInCore(lldb::addr_t addr, 
std::optional<lldb_private::MemoryRegionInfo> &closest_prior_region, 
std::optional<lldb_private::MemoryRegionInfo> &  closest_following_region) {
+  // Ensure memory regions are built!
+  BuildMemoryRegions();
+
+  // First try to find the region that contains the address (if any
   std::optional<minidump::Range> addr_region_maybe = 
m_minidump_parser->FindMemoryRange(addr);
   if (addr_region_maybe) {
     MemoryRegionInfo region = 
MinidumpParser::GetMemoryRegionInfo(*m_memory_regions, 
addr_region_maybe->start);
@@ -622,7 +626,6 @@ std::optional<lldb_private::MemoryRegionInfo> 
ProcessMinidump::TryGetMemoryRegio
 
 // For minidumps there's no runtime generated code so we don't need 
JITLoader(s)
 // Avoiding them will also speed up minidump loading since JITLoaders normally
-// try to set up symbolic breakpoints, which in turn may force loading more
 // debug information than needed.
 JITLoaderList &ProcessMinidump::GetJITLoaders() {
   if (!m_jit_loaders_up) {
@@ -1025,15 +1028,15 @@ class CommandObjectProcessMinidumpCheckMemory : public 
CommandObjectParsed {
     }
 
     lldb_private::StreamString result_stream;
-    result_stream << "Address not found in Minidump";
+    result_stream << "Address not found in Minidump" << "\n";
     if (closest_prior_region)
-      result_stream << "Closest prior range: " << 
closest_prior_region->Dump().c_str();
+      result_stream << "Closest prior range: " << 
closest_prior_region->Dump().c_str() << "\n";
     else 
-      result_stream << "No prior range found";
+      result_stream << "No prior range found" << "\n";
     if (closest_following_region)
-      result_stream << "Closest superior range: " << 
closest_following_region->Dump().c_str();
+      result_stream << "Closest following range: " << 
closest_following_region->Dump().c_str() << "\n";
     else 
-      result_stream << "No superior range found";
+      result_stream << "No following range found" << "\n";
     
     result.AppendMessage(result_stream.GetString());
   }
diff --git a/lldb/test/Shell/Minidump/check-memory.yaml 
b/lldb/test/Shell/Minidump/check-memory.yaml
new file mode 100644
index 0000000000000..cce315fb687fe
--- /dev/null
+++ b/lldb/test/Shell/Minidump/check-memory.yaml
@@ -0,0 +1,52 @@
+# Check that looking up a memory region not present in the Minidump fails
+# even if it's in the /proc/<pid>/maps file.
+
+# RUN: yaml2obj %s -o %t
+# RUN: %lldb -c %t -o "process plugin check-memory 0x1000" \
+# RUN:             -o "process plugin check-memory 0x800" \
+# RUN:             -o "process plugin check-memory 0x1500" \
+# RUN:             -o "process plugin check-memory 0x2400" | FileCheck %s
+
+# CHECK-LABEL: (lldb) process plugin check-memory 0x1000
+# CHECK-NEXT: Address found in Minidump. Address located in range: 
[0000000000001000-0000000000001100) r??
+# CHECK-LABEL: (lldb) process plugin check-memory 0x800
+# CHECK-NEXT: Address not found in Minidump
+# CHECK-NEXT: No prior range found
+# CHECK-NEXT: Closest following range: [0000000000001000-0000000000001100) r??
+# CHECK-LABEL: (lldb) process plugin check-memory 0x1500
+# CHECK-NEXT: Address not found in Minidump
+# CHECK-NEXT: Closest prior range: [0000000000001000-0000000000001100) r??
+# CHECK-NEXT: Closest following range: [0000000000002000-0000000000002200) r??
+# CHECK-LABEL: (lldb) process plugin check-memory 0x2400
+# CHECK-NEXT: Address not found in Minidump
+# CHECK-NEXT: Closest prior range: [0000000000002000-0000000000002200) r??
+# CHECK-NEXT: No following range found
+
+--- !minidump
+Streams:
+  - Type:            SystemInfo
+    Processor Arch:  AMD64
+    Processor Level: 6
+    Processor Revision: 15876
+    Number of Processors: 40
+    Platform ID:     Linux
+    CSD Version:     'Linux 3.13.0-91-generic #138-Ubuntu SMP Fri Jun 24 
17:00:34 UTC 2016 x86_64'
+    CPU:
+      Vendor ID:       GenuineIntel
+      Version Info:    0x00000000
+      Feature Info:    0x00000000
+  - Type:            LinuxProcStatus
+    Text:             |
+      Name:    test-yaml
+      Umask:   0002
+      State:   t (tracing stop)
+      Pid:     8567
+  - Type:            Memory64List
+    Memory Ranges:
+      - Start of Memory Range: 0x1000
+        Data Size:       0x100
+        Content :        ''
+      - Start of Memory Range: 0x2000
+        Data Size:       0x200
+        Content :        ''
+...

>From 9c9866dae9794aea76f3f94fe5f614fd610116f1 Mon Sep 17 00:00:00 2001
From: Jacob Lalonde <jalalo...@fb.com>
Date: Thu, 17 Jul 2025 13:28:04 -0700
Subject: [PATCH 3/4] Formatting

---
 lldb/include/lldb/Target/MemoryRegionInfo.h   |  4 +-
 lldb/include/lldb/Utility/RangeMap.h          |  4 +-
 .../Process/minidump/MinidumpParser.cpp       | 12 ++-
 .../Plugins/Process/minidump/MinidumpParser.h |  5 +-
 .../Process/minidump/ProcessMinidump.cpp      | 80 ++++++++++++-------
 .../Process/minidump/ProcessMinidump.h        |  7 +-
 6 files changed, 69 insertions(+), 43 deletions(-)

diff --git a/lldb/include/lldb/Target/MemoryRegionInfo.h 
b/lldb/include/lldb/Target/MemoryRegionInfo.h
index ad254084a40d3..2957709692307 100644
--- a/lldb/include/lldb/Target/MemoryRegionInfo.h
+++ b/lldb/include/lldb/Target/MemoryRegionInfo.h
@@ -14,8 +14,8 @@
 #include <vector>
 
 #include "lldb/Utility/ConstString.h"
-#include "lldb/Utility/StreamString.h"
 #include "lldb/Utility/RangeMap.h"
+#include "lldb/Utility/StreamString.h"
 #include "llvm/Support/FormatProviders.h"
 
 namespace lldb_private {
@@ -165,7 +165,7 @@ class MemoryRegionInfo {
       stream << "x";
     else if (m_execute == eNo)
       stream << "-";
-    else 
+    else
       stream << "?";
 
     return stream.GetString().str();
diff --git a/lldb/include/lldb/Utility/RangeMap.h 
b/lldb/include/lldb/Utility/RangeMap.h
index 894b08493a5cd..da17aee1fde1d 100644
--- a/lldb/include/lldb/Utility/RangeMap.h
+++ b/lldb/include/lldb/Utility/RangeMap.h
@@ -658,9 +658,9 @@ class RangeDataVector {
           m_entries, addr, [](const Entry &lhs, B rhs_base) -> bool {
             return lhs.GetRangeEnd() <= rhs_base;
           });
-      
+
       if (pos->Contains(addr))
-          return &(*pos);
+        return &(*pos);
 
       if (pos != begin)
         return &(*std::prev(pos));
diff --git a/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp 
b/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
index a81213ed858c8..16eeb99d91ad8 100644
--- a/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
+++ b/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
@@ -712,22 +712,26 @@ MinidumpParser::GetMemoryRegionInfo(const 
MemoryRegionInfos &regions,
   return region;
 }
 
-std::optional<minidump::Range> 
MinidumpParser::GetClosestPriorRegion(lldb::addr_t load_addr) {
+std::optional<minidump::Range>
+MinidumpParser::GetClosestPriorRegion(lldb::addr_t load_addr) {
   if (m_memory_ranges.IsEmpty())
     PopulateMemoryRanges();
 
-  const MemoryRangeVector::Entry *entry = 
m_memory_ranges.FindEntryThatContainsOrPrior(load_addr);
+  const MemoryRangeVector::Entry *entry =
+      m_memory_ranges.FindEntryThatContainsOrPrior(load_addr);
   if (!entry)
     return std::nullopt;
 
   return entry->data;
 }
 
-std::optional<minidump::Range> 
MinidumpParser::GetClosestFollowingRegion(lldb::addr_t load_addr) {
+std::optional<minidump::Range>
+MinidumpParser::GetClosestFollowingRegion(lldb::addr_t load_addr) {
   if (m_memory_ranges.IsEmpty())
     PopulateMemoryRanges();
 
-  const MemoryRangeVector::Entry *entry = 
m_memory_ranges.FindEntryThatContainsOrFollows(load_addr);
+  const MemoryRangeVector::Entry *entry =
+      m_memory_ranges.FindEntryThatContainsOrFollows(load_addr);
   if (!entry)
     return std::nullopt;
 
diff --git a/lldb/source/Plugins/Process/minidump/MinidumpParser.h 
b/lldb/source/Plugins/Process/minidump/MinidumpParser.h
index fdd8600d15054..ac8fc682925ee 100644
--- a/lldb/source/Plugins/Process/minidump/MinidumpParser.h
+++ b/lldb/source/Plugins/Process/minidump/MinidumpParser.h
@@ -107,8 +107,9 @@ class MinidumpParser {
   llvm::Expected<llvm::ArrayRef<uint8_t>> GetMemory(lldb::addr_t addr,
                                                     size_t size);
 
-  // Pair of functions to get relative memory regions from the minidump file. 
These aren't for
-  // evaluating the data, but checking the ranges stored in the minidump and 
their permissions.
+  // Pair of functions to get relative memory regions from the minidump file.
+  // These aren't for evaluating the data, but checking the ranges stored in 
the
+  // minidump and their permissions.
   std::optional<Range> GetClosestPriorRegion(lldb::addr_t addr);
   std::optional<Range> GetClosestFollowingRegion(lldb::addr_t addr);
 
diff --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp 
b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
index 4fa312d7533e8..79ccafe7a561c 100644
--- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
+++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
@@ -601,25 +601,35 @@ bool ProcessMinidump::GetProcessInfo(ProcessInstanceInfo 
&info) {
   return true;
 }
 
-std::optional<lldb_private::MemoryRegionInfo> 
ProcessMinidump::TryGetMemoryRegionInCore(lldb::addr_t addr, 
std::optional<lldb_private::MemoryRegionInfo> &closest_prior_region, 
std::optional<lldb_private::MemoryRegionInfo> &  closest_following_region) {
+std::optional<lldb_private::MemoryRegionInfo>
+ProcessMinidump::TryGetMemoryRegionInCore(
+    lldb::addr_t addr,
+    std::optional<lldb_private::MemoryRegionInfo> &closest_prior_region,
+    std::optional<lldb_private::MemoryRegionInfo> &closest_following_region) {
   // Ensure memory regions are built!
   BuildMemoryRegions();
 
   // First try to find the region that contains the address (if any
-  std::optional<minidump::Range> addr_region_maybe = 
m_minidump_parser->FindMemoryRange(addr);
+  std::optional<minidump::Range> addr_region_maybe =
+      m_minidump_parser->FindMemoryRange(addr);
   if (addr_region_maybe) {
-    MemoryRegionInfo region = 
MinidumpParser::GetMemoryRegionInfo(*m_memory_regions, 
addr_region_maybe->start);
+    MemoryRegionInfo region = MinidumpParser::GetMemoryRegionInfo(
+        *m_memory_regions, addr_region_maybe->start);
     return region;
   }
 
   // If we didn't find a region, try to find the closest prior and following
-  std::optional<minidump::Range> closest_prior_range_maybe = 
m_minidump_parser->GetClosestPriorRegion(addr);
+  std::optional<minidump::Range> closest_prior_range_maybe =
+      m_minidump_parser->GetClosestPriorRegion(addr);
   if (closest_prior_range_maybe)
-    closest_prior_region = 
MinidumpParser::GetMemoryRegionInfo(*m_memory_regions, 
closest_prior_range_maybe->start);
+    closest_prior_region = MinidumpParser::GetMemoryRegionInfo(
+        *m_memory_regions, closest_prior_range_maybe->start);
 
-  std::optional<minidump::Range> closest_following_range_maybe = 
m_minidump_parser->GetClosestFollowingRegion(addr);
+  std::optional<minidump::Range> closest_following_range_maybe =
+      m_minidump_parser->GetClosestFollowingRegion(addr);
   if (closest_following_range_maybe)
-    closest_following_region = 
MinidumpParser::GetMemoryRegionInfo(*m_memory_regions, 
closest_following_range_maybe->start);
+    closest_following_region = MinidumpParser::GetMemoryRegionInfo(
+        *m_memory_regions, closest_following_range_maybe->start);
 
   return std::nullopt;
 }
@@ -986,16 +996,18 @@ class CommandObjectProcessMinidumpDump : public 
CommandObjectParsed {
 class CommandObjectProcessMinidumpCheckMemory : public CommandObjectParsed {
 public:
   CommandObjectProcessMinidumpCheckMemory(CommandInterpreter &interpreter)
-  : CommandObjectParsed(interpreter, "process plugin check-memory",
-      "Check if a memory address is stored in the Minidump, or the closest 
ranges.", nullptr) {
-        CommandArgumentEntry arg1;
-        CommandArgumentData addr_arg;
-        addr_arg.arg_type = eArgTypeAddressOrExpression;
-
-        arg1.push_back(addr_arg);
-        m_arguments.push_back(arg1);
-      }
-    
+      : CommandObjectParsed(interpreter, "process plugin check-memory",
+                            "Check if a memory address is stored in the "
+                            "Minidump, or the closest ranges.",
+                            nullptr) {
+    CommandArgumentEntry arg1;
+    CommandArgumentData addr_arg;
+    addr_arg.arg_type = eArgTypeAddressOrExpression;
+
+    arg1.push_back(addr_arg);
+    m_arguments.push_back(arg1);
+  }
+
   void DoExecute(Args &command, CommandReturnObject &result) override {
     const size_t argc = command.GetArgumentCount();
     if (argc == 0) {
@@ -1005,39 +1017,45 @@ class CommandObjectProcessMinidumpCheckMemory : public 
CommandObjectParsed {
     }
 
     Status error;
-    lldb::addr_t address = OptionArgParser::ToAddress(&m_exe_ctx, 
command[0].ref(),
-                                LLDB_INVALID_ADDRESS, &error);
+    lldb::addr_t address = OptionArgParser::ToAddress(
+        &m_exe_ctx, command[0].ref(), LLDB_INVALID_ADDRESS, &error);
 
     if (error.Fail() || address == LLDB_INVALID_ADDRESS) {
-      result.AppendErrorWithFormat("'%s' Is an invalid address.", 
command[0].c_str());
+      result.AppendErrorWithFormat("'%s' Is an invalid address.",
+                                   command[0].c_str());
       return;
     }
 
     ProcessMinidump *process = static_cast<ProcessMinidump *>(
-      m_interpreter.GetExecutionContext().GetProcessPtr());
+        m_interpreter.GetExecutionContext().GetProcessPtr());
 
     result.SetStatus(eReturnStatusSuccessFinishResult);
     std::optional<lldb_private::MemoryRegionInfo> closest_prior_region;
     std::optional<lldb_private::MemoryRegionInfo> closest_following_region;
-    std::optional<lldb_private::MemoryRegionInfo> memory_region_maybe = 
-        process->TryGetMemoryRegionInCore(address, closest_prior_region, 
closest_following_region);
+    std::optional<lldb_private::MemoryRegionInfo> memory_region_maybe =
+        process->TryGetMemoryRegionInCore(address, closest_prior_region,
+                                          closest_following_region);
 
     if (memory_region_maybe) {
-      result.AppendMessageWithFormat("Address found in Minidump. Address 
located in range: %s", memory_region_maybe->Dump().c_str());
+      result.AppendMessageWithFormat(
+          "Address found in Minidump. Address located in range: %s",
+          memory_region_maybe->Dump().c_str());
       return;
     }
 
     lldb_private::StreamString result_stream;
     result_stream << "Address not found in Minidump" << "\n";
     if (closest_prior_region)
-      result_stream << "Closest prior range: " << 
closest_prior_region->Dump().c_str() << "\n";
-    else 
+      result_stream << "Closest prior range: "
+                    << closest_prior_region->Dump().c_str() << "\n";
+    else
       result_stream << "No prior range found" << "\n";
     if (closest_following_region)
-      result_stream << "Closest following range: " << 
closest_following_region->Dump().c_str() << "\n";
-    else 
+      result_stream << "Closest following range: "
+                    << closest_following_region->Dump().c_str() << "\n";
+    else
       result_stream << "No following range found" << "\n";
-    
+
     result.AppendMessage(result_stream.GetString());
   }
 };
@@ -1050,7 +1068,9 @@ class CommandObjectMultiwordProcessMinidump : public 
CommandObjectMultiword {
           "process plugin <subcommand> [<subcommand-options>]") {
     LoadSubCommand("dump",
         CommandObjectSP(new CommandObjectProcessMinidumpDump(interpreter)));
-    LoadSubCommand("check-memory", CommandObjectSP(new 
CommandObjectProcessMinidumpCheckMemory(interpreter)));
+    LoadSubCommand("check-memory",
+                   CommandObjectSP(new CommandObjectProcessMinidumpCheckMemory(
+                       interpreter)));
   }
 
   ~CommandObjectMultiwordProcessMinidump() override = default;
diff --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.h 
b/lldb/source/Plugins/Process/minidump/ProcessMinidump.h
index 41132c5d2eacd..f5a3a87260521 100644
--- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.h
+++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.h
@@ -74,9 +74,10 @@ class ProcessMinidump : public PostMortemProcess {
   size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
                       Status &error) override;
 
-  std::optional<lldb_private::MemoryRegionInfo> 
TryGetMemoryRegionInCore(lldb::addr_t addr, 
-                                          
std::optional<lldb_private::MemoryRegionInfo> &closest_prior_region,
-                                          
std::optional<lldb_private::MemoryRegionInfo> &closest_following_region);
+  std::optional<lldb_private::MemoryRegionInfo> TryGetMemoryRegionInCore(
+      lldb::addr_t addr,
+      std::optional<lldb_private::MemoryRegionInfo> &closest_prior_region,
+      std::optional<lldb_private::MemoryRegionInfo> &closest_following_region);
 
   ArchSpec GetArchitecture();
 

>From cc41f5f40c09997544147af37cc6918142690406 Mon Sep 17 00:00:00 2001
From: Jacob Lalonde <jalalo...@fb.com>
Date: Fri, 18 Jul 2025 13:34:40 -0700
Subject: [PATCH 4/4] Add a check for the iterator being equal to end before
 checking contains

---
 lldb/include/lldb/Utility/RangeMap.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lldb/include/lldb/Utility/RangeMap.h 
b/lldb/include/lldb/Utility/RangeMap.h
index da17aee1fde1d..81be259b5366d 100644
--- a/lldb/include/lldb/Utility/RangeMap.h
+++ b/lldb/include/lldb/Utility/RangeMap.h
@@ -654,12 +654,13 @@ class RangeDataVector {
 #endif
     if (!m_entries.empty()) {
       typename Collection::const_iterator begin = m_entries.begin();
+      typename Collection::const_iterator end = m_entries.end();
       typename Collection::const_iterator pos = llvm::lower_bound(
           m_entries, addr, [](const Entry &lhs, B rhs_base) -> bool {
             return lhs.GetRangeEnd() <= rhs_base;
           });
 
-      if (pos->Contains(addr))
+      if (pos != end && pos->Contains(addr))
         return &(*pos);
 
       if (pos != begin)

_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to