https://github.com/mbucko created https://github.com/llvm/llvm-project/pull/95007
Test Plan: llvm-lit llvm-project/lldb/test/API/python_api/find_in_memory/TestFindInMemory.py llvm-project/lldb/test/API/python_api/find_in_memory/TestFindRangesInMemory.py Reviewers: clayborg Tasks: lldb >From da8f23bf675abbb6742987e41939710ccb1c18ac Mon Sep 17 00:00:00 2001 From: Miro Bucko <mbu...@meta.com> Date: Tue, 4 Jun 2024 12:01:48 -0700 Subject: [PATCH] [lldb][API] Add Find(Ranges)InMemory() to Process SB API Test Plan: llvm-lit llvm-project/lldb/test/API/python_api/find_in_memory/TestFindInMemory.py llvm-project/lldb/test/API/python_api/find_in_memory/TestFindRangesInMemory.py Reviewers: clayborg Tasks: lldb --- lldb/bindings/python/python-typemaps.swig | 3 +- lldb/include/lldb/API/SBProcess.h | 8 ++ lldb/include/lldb/Core/AddressRangeListImpl.h | 2 + lldb/include/lldb/Target/Process.h | 11 ++ lldb/source/API/SBProcess.cpp | 115 ++++++++++++++++- lldb/source/Target/Process.cpp | 117 +++++++++++++++++ .../API/python_api/find_in_memory/Makefile | 3 + .../find_in_memory/TestFindInMemory.py | 85 +++++++++++++ .../find_in_memory/TestFindRangesInMemory.py | 120 ++++++++++++++++++ .../find_in_memory/address_ranges_helper.py | 30 +++++ .../API/python_api/find_in_memory/main.cpp | 21 +++ 11 files changed, 509 insertions(+), 6 deletions(-) create mode 100644 lldb/test/API/python_api/find_in_memory/Makefile create mode 100644 lldb/test/API/python_api/find_in_memory/TestFindInMemory.py create mode 100644 lldb/test/API/python_api/find_in_memory/TestFindRangesInMemory.py create mode 100644 lldb/test/API/python_api/find_in_memory/address_ranges_helper.py create mode 100644 lldb/test/API/python_api/find_in_memory/main.cpp diff --git a/lldb/bindings/python/python-typemaps.swig b/lldb/bindings/python/python-typemaps.swig index 8d4b740e5f35c..923a787e77c88 100644 --- a/lldb/bindings/python/python-typemaps.swig +++ b/lldb/bindings/python/python-typemaps.swig @@ -257,7 +257,8 @@ AND call SWIG_fail at the same time, because it will result in a double free. } // For SBProcess::WriteMemory, SBTarget::GetInstructions and SBDebugger::DispatchInput. %typemap(in) (const void *buf, size_t size), - (const void *data, size_t data_len) { + (const void *data, size_t data_len), + (const void *buf, uint64_t size) { if (PythonString::Check($input)) { PythonString str(PyRefType::Borrowed, $input); $1 = (void *)str.GetString().data(); diff --git a/lldb/include/lldb/API/SBProcess.h b/lldb/include/lldb/API/SBProcess.h index f1b5d1fb92ce2..eb7441629108c 100644 --- a/lldb/include/lldb/API/SBProcess.h +++ b/lldb/include/lldb/API/SBProcess.h @@ -209,6 +209,14 @@ class LLDB_API SBProcess { lldb::addr_t ReadPointerFromMemory(addr_t addr, lldb::SBError &error); + lldb::SBAddressRangeList FindRangesInMemory(const void *buf, uint64_t size, + SBAddressRangeList &ranges, + uint32_t alignment, + uint32_t max_matches); + + lldb::addr_t FindInMemory(const void *buf, uint64_t size, + SBAddressRange &range, uint32_t alignment); + // Events static lldb::StateType GetStateFromEvent(const lldb::SBEvent &event); diff --git a/lldb/include/lldb/Core/AddressRangeListImpl.h b/lldb/include/lldb/Core/AddressRangeListImpl.h index 46ebfe73d4d92..777cf81e2b1c3 100644 --- a/lldb/include/lldb/Core/AddressRangeListImpl.h +++ b/lldb/include/lldb/Core/AddressRangeListImpl.h @@ -14,6 +14,7 @@ namespace lldb { class SBBlock; +class SBProcess; } namespace lldb_private { @@ -40,6 +41,7 @@ class AddressRangeListImpl { private: friend class lldb::SBBlock; + friend class lldb::SBProcess; AddressRanges &ref(); diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h index eec337c15f7ed..176eb2b19f226 100644 --- a/lldb/include/lldb/Target/Process.h +++ b/lldb/include/lldb/Target/Process.h @@ -2685,6 +2685,13 @@ void PruneThreadPlans(); lldb::addr_t FindInMemory(lldb::addr_t low, lldb::addr_t high, const uint8_t *buf, size_t size); + Status FindInMemory(AddressRanges &matches, const uint8_t *buf, size_t size, + const AddressRanges &ranges, size_t alignment, + size_t max_count); + + lldb::addr_t FindInMemory(const AddressRange &range, const uint8_t *buf, + size_t size, size_t alignment); + protected: friend class Trace; @@ -2800,6 +2807,10 @@ void PruneThreadPlans(); virtual size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size, Status &error) = 0; + void DoFindInMemory(lldb::addr_t start_addr, lldb::addr_t end_addr, + const uint8_t *buf, size_t size, AddressRanges &matches, + size_t alignment, size_t max_count); + /// DoGetMemoryRegionInfo is called by GetMemoryRegionInfo after it has /// removed non address bits from load_addr. Override this method in /// subclasses of Process. diff --git a/lldb/source/API/SBProcess.cpp b/lldb/source/API/SBProcess.cpp index c37c111c5a58e..d935c5d23653e 100644 --- a/lldb/source/API/SBProcess.cpp +++ b/lldb/source/API/SBProcess.cpp @@ -14,6 +14,7 @@ #include "lldb/lldb-defines.h" #include "lldb/lldb-types.h" +#include "lldb/Core/AddressRangeListImpl.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" @@ -26,6 +27,7 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/Args.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/ProcessInfo.h" #include "lldb/Utility/State.h" #include "lldb/Utility/Stream.h" @@ -320,8 +322,8 @@ void SBProcess::ReportEventState(const SBEvent &event, FileSP out) const { if (process_sp) { StreamFile stream(out); const StateType event_state = SBProcess::GetStateFromEvent(event); - stream.Printf("Process %" PRIu64 " %s\n", - process_sp->GetID(), SBDebugger::StateAsCString(event_state)); + stream.Printf("Process %" PRIu64 " %s\n", process_sp->GetID(), + SBDebugger::StateAsCString(event_state)); } } @@ -378,7 +380,6 @@ bool SBProcess::SetSelectedThreadByIndexID(uint32_t index_id) { ret_val = process_sp->GetThreadList().SetSelectedThreadByIndexID(index_id); } - return ret_val; } @@ -546,7 +547,6 @@ ByteOrder SBProcess::GetByteOrder() const { if (process_sp) byteOrder = process_sp->GetTarget().GetArchitecture().GetByteOrder(); - return byteOrder; } @@ -558,7 +558,6 @@ uint32_t SBProcess::GetAddressByteSize() const { if (process_sp) size = process_sp->GetTarget().GetArchitecture().GetAddressByteSize(); - return size; } @@ -810,6 +809,112 @@ const char *SBProcess::GetBroadcasterClass() { return ConstString(Process::GetStaticBroadcasterClass()).AsCString(); } +lldb::SBAddressRangeList +SBProcess::FindRangesInMemory(const void *buf, uint64_t size, + SBAddressRangeList &ranges, uint32_t alignment, + uint32_t max_matches) { + LLDB_INSTRUMENT_VA(this, buf, size, ranges, alignment, max_matches); + + Log *log = GetLog(LLDBLog::Process); + lldb::SBAddressRangeList matches; + + if (alignment == 0) { + LLDB_LOGF(log, "SBProcess::%s allignmet is 0, Must be greater than 0.", + __FUNCTION__); + return matches; + } + + if (buf == nullptr) { + LLDB_LOGF(log, "SBProcess::%s provided 'buffer' is nullptr.", __FUNCTION__); + return matches; + } + + if (size == 0) { + LLDB_LOGF(log, "SBProcess::%s buffer size is 0.", __FUNCTION__); + return matches; + } + + if (ranges.GetSize() == 0) { + LLDB_LOGF(log, "SBProcess::%s provided 'range' is invalid.", __FUNCTION__); + return matches; + } + + ProcessSP process_sp(GetSP()); + if (!process_sp) { + LLDB_LOGF(log, "SBProcess::%s SBProcess is invalid.", __FUNCTION__); + return matches; + } + Process::StopLocker stop_locker; + if (!stop_locker.TryLock(&process_sp->GetRunLock())) { + LLDB_LOGF( + log, + "SBProcess::%s Cannot find process in memory while process is running.", + __FUNCTION__); + return matches; + } + std::lock_guard<std::recursive_mutex> guard( + process_sp->GetTarget().GetAPIMutex()); + lldb::SBError error; + error.ref() = process_sp->FindInMemory( + matches.m_opaque_up->ref(), static_cast<const uint8_t *>(buf), size, + ranges.m_opaque_up->ref(), alignment, max_matches); + if (error.Fail()) { + LLDB_LOGF(log, "SBProcess::%s failed to find pattern in memory.", + __FUNCTION__); + } + return matches; +} + +lldb::addr_t SBProcess::FindInMemory(const void *buf, uint64_t size, + SBAddressRange &range, + uint32_t alignment) { + LLDB_INSTRUMENT_VA(this, buf, size, range, alignment); + + Log *log = GetLog(LLDBLog::Process); + + if (alignment == 0) { + LLDB_LOGF(log, "SBProcess::%s allignmet is 0, Must be greater than 0.", + __FUNCTION__); + return LLDB_INVALID_ADDRESS; + } + + if (buf == nullptr) { + LLDB_LOGF(log, "SBProcess::%s provided 'buffer' is nullptr.", __FUNCTION__); + return LLDB_INVALID_ADDRESS; + } + + if (size == 0) { + LLDB_LOGF(log, "SBProcess::%s buffer size is 0.", __FUNCTION__); + return LLDB_INVALID_ADDRESS; + } + + if (!range.IsValid()) { + LLDB_LOGF(log, "SBProcess::%s provided 'range' is invalid.", __FUNCTION__); + return LLDB_INVALID_ADDRESS; + } + + ProcessSP process_sp(GetSP()); + + if (!process_sp) { + LLDB_LOGF(log, "SBProcess::%s SBProcess is invalid.", __FUNCTION__); + return LLDB_INVALID_ADDRESS; + } + + Process::StopLocker stop_locker; + if (!stop_locker.TryLock(&process_sp->GetRunLock())) { + LLDB_LOGF( + log, + "SBProcess::%s Cannot find process in memory while process is running.", + __FUNCTION__); + return LLDB_INVALID_ADDRESS; + } + + std::lock_guard<std::recursive_mutex> guard( + process_sp->GetTarget().GetAPIMutex()); + return process_sp->FindInMemory( + *range.m_opaque_up, static_cast<const uint8_t *>(buf), size, alignment); +} + size_t SBProcess::ReadMemory(addr_t addr, void *dst, size_t dst_len, SBError &sb_error) { LLDB_INSTRUMENT_VA(this, addr, dst, dst_len, sb_error); diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index 1e321f8bde391..06120be7979f9 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -2007,6 +2007,123 @@ size_t Process::ReadMemory(addr_t addr, void *buf, size_t size, Status &error) { } } +void Process::DoFindInMemory(lldb::addr_t start_addr, lldb::addr_t end_addr, + const uint8_t *buf, size_t size, + AddressRanges &matches, size_t alignment, + size_t max_count) { + // Inputs are already validated in FindInMemory() functions. + assert(buf != nullptr); + assert(size > 0); + assert(alignment > 0); + assert(max_count > 0); + assert(start_addr != LLDB_INVALID_ADDRESS); + assert(end_addr != LLDB_INVALID_ADDRESS); + assert(start_addr < end_addr); + + lldb::addr_t start = start_addr; + while (matches.size() < max_count && (start + size) < end_addr) { + const lldb::addr_t found_addr = FindInMemory(start, end_addr, buf, size); + if (found_addr == LLDB_INVALID_ADDRESS) + break; + matches.emplace_back(found_addr, size); + start = found_addr + alignment; + } +} + +Status Process::FindInMemory(AddressRanges &matches, const uint8_t *buf, + size_t size, const AddressRanges &ranges, + size_t alignment, size_t max_count) { + Status error; + if (alignment == 0) { + error.SetErrorStringWithFormat( + "invalid alignment %zu, must be greater than 0", alignment); + return error; + } + if (buf == nullptr) { + error.SetErrorStringWithFormat("buffer is null"); + return error; + } + if (size == 0) { + error.SetErrorStringWithFormat("size is zero"); + return error; + } + if (ranges.empty()) { + error.SetErrorStringWithFormat("ranges in empty"); + return error; + } + if (max_count == 0) { + error.SetErrorStringWithFormat( + "invalid max_count %zu, must be greater than 0", max_count); + return error; + } + + Target &target = GetTarget(); + Log *log = GetLog(LLDBLog::Process); + for (size_t i = 0; i < ranges.size(); ++i) { + if (matches.size() >= max_count) { + break; + } + const AddressRange &range = ranges[i]; + if (range.IsValid() == false) { + LLDB_LOGF(log, "Process::%s range is invalid", __FUNCTION__); + continue; + } + + const lldb::addr_t start_addr = + range.GetBaseAddress().GetLoadAddress(&target); + if (start_addr == LLDB_INVALID_ADDRESS) { + LLDB_LOGF(log, + "Process::%s range load start address is invalid, skipping", + __FUNCTION__); + continue; + } + const lldb::addr_t end_addr = start_addr + range.GetByteSize(); + DoFindInMemory(start_addr, end_addr, buf, size, matches, alignment, + max_count); + } + + return Status(); +} + +lldb::addr_t Process::FindInMemory(const AddressRange &range, + const uint8_t *buf, size_t size, + size_t alignment) { + Log *log = GetLog(LLDBLog::Process); + if (buf == nullptr) { + LLDB_LOGF(log, "Process::%s buffer is null", __FUNCTION__); + return LLDB_INVALID_ADDRESS; + } + if (size == 0) { + LLDB_LOGF(log, "Process::%s size is zero", __FUNCTION__); + return LLDB_INVALID_ADDRESS; + } + if (alignment == 0) { + LLDB_LOGF(log, "Process::%s alignment is zero, returning", __FUNCTION__); + return LLDB_INVALID_ADDRESS; + } + if (range.IsValid() == false) { + LLDB_LOGF(log, "Process::%s range is invalid", __FUNCTION__); + return LLDB_INVALID_ADDRESS; + } + + Target &target = GetTarget(); + const lldb::addr_t start_addr = + range.GetBaseAddress().GetLoadAddress(&target); + if (start_addr == LLDB_INVALID_ADDRESS) { + LLDB_LOGF(log, "Process::%s range load start address is invalid, returning", + __FUNCTION__); + return LLDB_INVALID_ADDRESS; + } + const lldb::addr_t end_addr = start_addr + range.GetByteSize(); + + AddressRanges matches; + DoFindInMemory(start_addr, end_addr, buf, size, matches, alignment, 1); + if (matches.empty()) + return LLDB_INVALID_ADDRESS; + + return matches[0].GetBaseAddress().GetLoadAddress(&target); +} + size_t Process::ReadCStringFromMemory(addr_t addr, std::string &out_str, Status &error) { char buf[256]; diff --git a/lldb/test/API/python_api/find_in_memory/Makefile b/lldb/test/API/python_api/find_in_memory/Makefile new file mode 100644 index 0000000000000..99998b20bcb05 --- /dev/null +++ b/lldb/test/API/python_api/find_in_memory/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/lldb/test/API/python_api/find_in_memory/TestFindInMemory.py b/lldb/test/API/python_api/find_in_memory/TestFindInMemory.py new file mode 100644 index 0000000000000..95ea9b75cdc31 --- /dev/null +++ b/lldb/test/API/python_api/find_in_memory/TestFindInMemory.py @@ -0,0 +1,85 @@ +""" +Test Process::FindInMemory. +""" + +import lldb +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil +from address_ranges_helper import GetAddressRanges +from address_ranges_helper import SINGLE_INSTANCE_PATTERN + +class FindInMemoryTestCase(TestBase): + NO_DEBUG_INFO_TESTCASE = True + + def setUp(self): + TestBase.setUp(self) + + self.build() + self.target, self.process, self.thread, self.bp = ( + lldbutil.run_to_source_breakpoint( + self, "break here", lldb.SBFileSpec("main.cpp") + ) + ) + self.assertTrue(self.bp.IsValid()) + + def test_find_in_memory_ok(self): + """Make sure a match exists in the heap memory and the right address ranges are provided""" + self.assertTrue(self.process, PROCESS_IS_VALID) + self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED) + + addr_ranges = GetAddressRanges(self) + + for addr_range in addr_ranges: + addr = self.process.FindInMemory( + SINGLE_INSTANCE_PATTERN, + addr_range, + 1, + ) + + if addr != lldb.LLDB_INVALID_ADDRESS: + break + + self.assertNotEqual(addr, lldb.LLDB_INVALID_ADDRESS) + + def test_find_in_memory_invalid_alignment(self): + """Make sure the alignment 0 is failing""" + self.assertTrue(self.process, PROCESS_IS_VALID) + self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED) + + addr_ranges = GetAddressRanges(self) + + addr = self.process.FindInMemory( + SINGLE_INSTANCE_PATTERN, + addr_ranges[0], + 0, + ) + + self.assertEqual(addr, lldb.LLDB_INVALID_ADDRESS) + + def test_find_in_memory_invalid_address_range(self): + """Make sure invalid address range is failing""" + self.assertTrue(self.process, PROCESS_IS_VALID) + self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED) + + addr = self.process.FindInMemory( + SINGLE_INSTANCE_PATTERN, + lldb.SBAddressRange(), + 1, + ) + + self.assertEqual(addr, lldb.LLDB_INVALID_ADDRESS) + + def test_find_in_memory_invalid_buffer(self): + """Make sure the empty buffer is failing""" + self.assertTrue(self.process, PROCESS_IS_VALID) + self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED) + + addr_ranges = GetAddressRanges(self) + + addr = self.process.FindInMemory( + "", + addr_ranges[0], + 1, + ) + + self.assertEqual(addr, lldb.LLDB_INVALID_ADDRESS) diff --git a/lldb/test/API/python_api/find_in_memory/TestFindRangesInMemory.py b/lldb/test/API/python_api/find_in_memory/TestFindRangesInMemory.py new file mode 100644 index 0000000000000..ac4b4b8c481b6 --- /dev/null +++ b/lldb/test/API/python_api/find_in_memory/TestFindRangesInMemory.py @@ -0,0 +1,120 @@ +""" +Test Process::FindRangesInMemory. +""" + +import lldb +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil +from address_ranges_helper import GetAddressRanges +from address_ranges_helper import SINGLE_INSTANCE_PATTERN +from address_ranges_helper import DOUBLE_INSTANCE_PATTERN + + +class FindRangesInMemoryTestCase(TestBase): + NO_DEBUG_INFO_TESTCASE = True + + def setUp(self): + TestBase.setUp(self) + + self.build() + self.target, self.process, self.thread, self.bp = ( + lldbutil.run_to_source_breakpoint( + self, "break here", lldb.SBFileSpec("main.cpp") + ) + ) + self.assertTrue(self.bp.IsValid()) + + def test_find_ranges_in_memory_two_matches(self): + """Make sure two matches exist in the heap memory and the right address ranges are provided""" + self.assertTrue(self.process, PROCESS_IS_VALID) + self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED) + + addr_ranges = GetAddressRanges(self) + + matches = self.process.FindRangesInMemory( + DOUBLE_INSTANCE_PATTERN, + addr_ranges, + 1, + 10, + ) + + self.assertEqual(matches.GetSize(), 2) + + def test_find_ranges_in_memory_one_match(self): + """Make sure exactly one match exists in the heap memory and the right address ranges are provided""" + self.assertTrue(self.process, PROCESS_IS_VALID) + self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED) + + addr_ranges = GetAddressRanges(self) + + matches = self.process.FindRangesInMemory( + SINGLE_INSTANCE_PATTERN, + addr_ranges, + 1, + 10, + ) + + self.assertEqual(matches.GetSize(), 1) + + def test_find_ranges_in_memory_one_match_max(self): + """Make sure at least one matche exists in the heap memory and the right address ranges are provided""" + self.assertTrue(self.process, PROCESS_IS_VALID) + self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED) + + addr_ranges = GetAddressRanges(self) + + matches = self.process.FindRangesInMemory( + DOUBLE_INSTANCE_PATTERN, + addr_ranges, + 1, + 1, + ) + + self.assertEqual(matches.GetSize(), 1) + + def test_find_ranges_in_memory_invalid_alignment(self): + """Make sure the alignment 0 is failing""" + self.assertTrue(self.process, PROCESS_IS_VALID) + self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED) + + addr_ranges = GetAddressRanges(self) + + matches = self.process.FindRangesInMemory( + DOUBLE_INSTANCE_PATTERN, + addr_ranges, + 0, + 10, + ) + + self.assertEqual(matches.GetSize(), 0) + + def test_find_ranges_in_memory_empty_ranges(self): + """Make sure the empty ranges is failing""" + self.assertTrue(self.process, PROCESS_IS_VALID) + self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED) + + addr_ranges = lldb.SBAddressRangeList() + matches = self.process.FindRangesInMemory( + DOUBLE_INSTANCE_PATTERN, + addr_ranges, + 1, + 10, + ) + + self.assertEqual(matches.GetSize(), 0) + + def test_find_ranges_in_memory_invalid_buffer(self): + """Make sure the empty buffer is failing""" + self.assertTrue(self.process, PROCESS_IS_VALID) + self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED) + + addr_ranges = GetAddressRanges(self) + + matches = self.process.FindRangesInMemory( + "", + addr_ranges, + 1, + 10, + ) + + self.assertEqual(matches.GetSize(), 0) diff --git a/lldb/test/API/python_api/find_in_memory/address_ranges_helper.py b/lldb/test/API/python_api/find_in_memory/address_ranges_helper.py new file mode 100644 index 0000000000000..87341361c4c62 --- /dev/null +++ b/lldb/test/API/python_api/find_in_memory/address_ranges_helper.py @@ -0,0 +1,30 @@ +import lldb + +SINGLE_INSTANCE_PATTERN = "there_is_only_one_of_me" +DOUBLE_INSTANCE_PATTERN = "there_is_exactly_two_of_me" + +def GetAddressRanges(test_base): + mem_regions = test_base.process.GetMemoryRegions() + test_base.assertTrue(len(mem_regions) > 0, "Make sure there are memory regions") + addr_ranges = lldb.SBAddressRangeList() + for i in range(mem_regions.GetSize()): + region_info = lldb.SBMemoryRegionInfo() + if not mem_regions.GetMemoryRegionAtIndex(i, region_info): + continue + if not (region_info.IsReadable() and region_info.IsWritable()): + continue + if region_info.IsExecutable(): + continue + if not region_info.GetName() or region_info.GetName() != "[heap]": + continue + + addr = test_base.target.ResolveLoadAddress(region_info.GetRegionBase()) + addr_range = lldb.SBAddressRange( + addr, + region_info.GetRegionEnd() - region_info.GetRegionBase(), + ) + addr_ranges.Append(addr_range) + test_base.assertTrue( + len(addr_ranges) > 0, "Make sure there are valid address ranges" + ) + return addr_ranges diff --git a/lldb/test/API/python_api/find_in_memory/main.cpp b/lldb/test/API/python_api/find_in_memory/main.cpp new file mode 100644 index 0000000000000..1efaad9624ead --- /dev/null +++ b/lldb/test/API/python_api/find_in_memory/main.cpp @@ -0,0 +1,21 @@ +#include <cstring> + +int main() { + constexpr char SINGLE_INSTANCE_STRING[] = "there_is_only_one_of_me"; + constexpr size_t single_instance_size = sizeof(SINGLE_INSTANCE_STRING) + 1; + char *single_instance = new char[single_instance_size]; + strcpy(single_instance, SINGLE_INSTANCE_STRING); + + constexpr char DOUBLE_INSTANCE_STRING[] = "there_is_exactly_two_of_me"; + constexpr size_t double_instance_size = sizeof(DOUBLE_INSTANCE_STRING) + 1; + char *double_instance = new char[double_instance_size]; + char *double_instance_copy = new char[double_instance_size]; + strcpy(double_instance, DOUBLE_INSTANCE_STRING); + strcpy(double_instance_copy, DOUBLE_INSTANCE_STRING); + + delete[] single_instance; // break here + delete[] double_instance; + delete[] double_instance_copy; + + return 0; +} _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits