https://github.com/DavidSpickett created 
https://github.com/llvm/llvm-project/pull/177559

"memory region" can be given an address once and then when repeated,
it will try to find a region just beyond the last one it printed.
This continues until the end of the address space.

Then it gives you an error showing the usage, which is odd because
you just saw a bunch of "memory region" with no options work.

So I've improved the error a bit to imply its to do with the repetition.
Then described the repeating behaviour in the help text.

>From 04eb9b855e41962e33887f11b85e20bd24e160cb Mon Sep 17 00:00:00 2001
From: David Spickett <[email protected]>
Date: Wed, 21 Jan 2026 14:09:57 +0000
Subject: [PATCH 1/3] [lldb] Fix error when running "memory region --all"
 repeatedly

Due to some faulty logic, if you ran "memory region --all" twice,
the second time lldb would try to repeat the command. There's nothing
to repeat, so it failed with an error.

I've fixed the logic so that we treat each --all use as its own
command starting from scratch.

For reasons unknown, I could not reproduce this issue using the
API test TestMemoryRegion.py. So I have added a shell test that
I confirmed does fail without this fix.
---
 lldb/source/Commands/CommandObjectMemory.cpp  | 21 ++++++++++---------
 .../Shell/Commands/command-memory-region.test | 10 +++++++++
 2 files changed, 21 insertions(+), 10 deletions(-)
 create mode 100644 lldb/test/Shell/Commands/command-memory-region.test

diff --git a/lldb/source/Commands/CommandObjectMemory.cpp 
b/lldb/source/Commands/CommandObjectMemory.cpp
index 5786e757ef7ea..cbfd7180f99f6 100644
--- a/lldb/source/Commands/CommandObjectMemory.cpp
+++ b/lldb/source/Commands/CommandObjectMemory.cpp
@@ -1752,16 +1752,17 @@ class CommandObjectMemoryRegion : public 
CommandObjectParsed {
         return;
       }
     } else if (argc > 1 ||
-               // When we're repeating the command, the previous end address is
-               // used for load_addr. If that was 0xF...F then we must have
-               // reached the end of memory.
-               (argc == 0 && !m_memory_region_options.m_all &&
-                load_addr == LLDB_INVALID_ADDRESS) ||
-               // If the target has non-address bits (tags, limited virtual
-               // address size, etc.), the end of mappable memory will be lower
-               // than that. So if we find any non-address bit set, we must be
-               // at the end of the mappable range.
-               (abi && (abi->FixAnyAddress(load_addr) != load_addr))) {
+               (!m_memory_region_options.m_all &&
+                (
+                    // When we're repeating the command, the previous end
+                    // address is used for load_addr. If that was 0xF...F then
+                    // we must have reached the end of memory.
+                    (argc == 0 && load_addr == LLDB_INVALID_ADDRESS) ||
+                    // If the target has non-address bits (tags, limited 
virtual
+                    // address size, etc.), the end of mappable memory will be
+                    // lower than that. So if we find any non-address bit set,
+                    // we must be at the end of the mappable range.
+                    (abi && (abi->FixAnyAddress(load_addr) != load_addr))))) {
       result.AppendErrorWithFormat(
           "'%s' takes one argument or \"--all\" option:\nUsage: %s\n",
           m_cmd_name.c_str(), m_cmd_syntax.c_str());
diff --git a/lldb/test/Shell/Commands/command-memory-region.test 
b/lldb/test/Shell/Commands/command-memory-region.test
new file mode 100644
index 0000000000000..35fb7b08cb666
--- /dev/null
+++ b/lldb/test/Shell/Commands/command-memory-region.test
@@ -0,0 +1,10 @@
+## --all should be able to be used many times in a row. As it is not
+## repeatable and starts fresh each time.
+
+# RUN: %clang_host -g -O0 %S/Inputs/main.c -o %t.out
+# RUN: %lldb %t.out -b -o 'b main' -o 'run' -o 'memory region --all' \
+# RUN:    -o 'memory region --all' | FileCheck %s
+# CHECK-LABEL: memory region --all
+# CHECK-NEXT: [0x{{[0-9a-f]+}}-0x{{[0-9a-f]+}})
+# CHECK-LABEL: memory region --all
+# CHECK-NEXT: [0x{{[0-9a-f]+}}-0x{{[0-9a-f]+}})

>From 43677c2d516fc1397f5b0ac4fbf834614622cbf1 Mon Sep 17 00:00:00 2001
From: David Spickett <[email protected]>
Date: Thu, 22 Jan 2026 11:44:08 +0000
Subject: [PATCH 2/3] cleanup validation logic

---
 lldb/source/Commands/CommandObjectMemory.cpp | 33 ++++++++++++--------
 1 file changed, 20 insertions(+), 13 deletions(-)

diff --git a/lldb/source/Commands/CommandObjectMemory.cpp 
b/lldb/source/Commands/CommandObjectMemory.cpp
index cbfd7180f99f6..eabe2fb4c4483 100644
--- a/lldb/source/Commands/CommandObjectMemory.cpp
+++ b/lldb/source/Commands/CommandObjectMemory.cpp
@@ -1735,7 +1735,24 @@ class CommandObjectMemoryRegion : public 
CommandObjectParsed {
     const size_t argc = command.GetArgumentCount();
     const lldb::ABISP &abi = process_sp->GetABI();
 
-    if (argc == 1) {
+    if (argc == 0) {
+      if (!m_memory_region_options.m_all) {
+        if ( // When we're repeating the command, the previous end
+             // address is used for load_addr. If that was 0xF...F then
+             // we must have reached the end of memory.
+            (load_addr == LLDB_INVALID_ADDRESS) ||
+            // If the target has non-address bits (tags, limited virtual
+            // address size, etc.), the end of mappable memory will be
+            // lower than that. So if we find any non-address bit set,
+            // we must be at the end of the mappable range.
+            (abi && (abi->FixAnyAddress(load_addr) != load_addr))) {
+          result.AppendErrorWithFormat(
+              "'%s' takes one argument or \"--all\" option:\nUsage: %s\n",
+              m_cmd_name.c_str(), m_cmd_syntax.c_str());
+          return;
+        }
+      }
+    } else if (argc == 1) {
       if (m_memory_region_options.m_all) {
         result.AppendError(
             "The \"--all\" option cannot be used when an address "
@@ -1751,18 +1768,8 @@ class CommandObjectMemoryRegion : public 
CommandObjectParsed {
                                      command[0].c_str(), error.AsCString());
         return;
       }
-    } else if (argc > 1 ||
-               (!m_memory_region_options.m_all &&
-                (
-                    // When we're repeating the command, the previous end
-                    // address is used for load_addr. If that was 0xF...F then
-                    // we must have reached the end of memory.
-                    (argc == 0 && load_addr == LLDB_INVALID_ADDRESS) ||
-                    // If the target has non-address bits (tags, limited 
virtual
-                    // address size, etc.), the end of mappable memory will be
-                    // lower than that. So if we find any non-address bit set,
-                    // we must be at the end of the mappable range.
-                    (abi && (abi->FixAnyAddress(load_addr) != load_addr))))) {
+    } else {
+      // argc > 1
       result.AppendErrorWithFormat(
           "'%s' takes one argument or \"--all\" option:\nUsage: %s\n",
           m_cmd_name.c_str(), m_cmd_syntax.c_str());

>From 7594e0ebe43c12be30e6ae6d4dbb738d33db5002 Mon Sep 17 00:00:00 2001
From: David Spickett <[email protected]>
Date: Fri, 23 Jan 2026 09:45:40 +0000
Subject: [PATCH 3/3] [lldb] Improve error and docs for repeating "memory
 region"

"memory region" can be given an address once and then when repeated,
it will try to find a region just beyond the last one it printed.
This continues until the end of the address space.

Then it gives you an error showing the usage, which is odd because
you just saw a bunch of "memory region" with no options work.

So I've improved the error a bit to imply its to do with the repetition.
Then described the repeating behaviour in the help text.
---
 lldb/source/Commands/CommandObjectMemory.cpp  | 23 ++++++++++++-------
 .../memory-region/TestMemoryRegion.py         |  2 +-
 .../completions/TestDAP_completions.py        |  7 +++++-
 3 files changed, 22 insertions(+), 10 deletions(-)

diff --git a/lldb/source/Commands/CommandObjectMemory.cpp 
b/lldb/source/Commands/CommandObjectMemory.cpp
index eabe2fb4c4483..ef9452b63d11e 100644
--- a/lldb/source/Commands/CommandObjectMemory.cpp
+++ b/lldb/source/Commands/CommandObjectMemory.cpp
@@ -1651,12 +1651,18 @@ class CommandObjectMemoryRegion : public 
CommandObjectParsed {
   };
 
   CommandObjectMemoryRegion(CommandInterpreter &interpreter)
-      : CommandObjectParsed(interpreter, "memory region",
-                            "Get information on the memory region containing "
-                            "an address in the current target process.",
-                            "memory region <address-expression> (or --all)",
-                            eCommandRequiresProcess | eCommandTryTargetAPILock 
|
-                                eCommandProcessMustBeLaunched) {
+      : CommandObjectParsed(
+            interpreter, "memory region",
+            "Get information on the memory region containing "
+            "an address in the current target process.\n"
+            "If this command is given an <address-expression> once "
+            "and then repeated without options, it will try to print "
+            "the memory region that follows the previously printed "
+            "region. The command can be repeated until the end of "
+            "the address range is reached.",
+            "memory region <address-expression> (or --all)",
+            eCommandRequiresProcess | eCommandTryTargetAPILock |
+                eCommandProcessMustBeLaunched) {
     // Address in option set 1.
     m_arguments.push_back(CommandArgumentEntry{CommandArgumentData(
         eArgTypeAddressOrExpression, eArgRepeatPlain, LLDB_OPT_SET_1)});
@@ -1747,8 +1753,9 @@ class CommandObjectMemoryRegion : public 
CommandObjectParsed {
             // we must be at the end of the mappable range.
             (abi && (abi->FixAnyAddress(load_addr) != load_addr))) {
           result.AppendErrorWithFormat(
-              "'%s' takes one argument or \"--all\" option:\nUsage: %s\n",
-              m_cmd_name.c_str(), m_cmd_syntax.c_str());
+              "No next region address set, one address expression argument or "
+              "\"--all\" option required:\nUsage: %s\n",
+              m_cmd_syntax.c_str());
           return;
         }
       }
diff --git a/lldb/test/API/functionalities/memory-region/TestMemoryRegion.py 
b/lldb/test/API/functionalities/memory-region/TestMemoryRegion.py
index 50182e72e498c..6b0e82c26b49d 100644
--- a/lldb/test/API/functionalities/memory-region/TestMemoryRegion.py
+++ b/lldb/test/API/functionalities/memory-region/TestMemoryRegion.py
@@ -54,7 +54,7 @@ def test_command(self):
         self.assertFalse(result.Succeeded())
         self.assertEqual(
             result.GetError(),
-            "error: 'memory region' takes one argument or \"--all\" option:\n"
+            'error: No next region address set, one address expression 
argument or "--all" option required:\n'
             "Usage: memory region <address-expression> (or --all)\n",
         )
 
diff --git a/lldb/test/API/tools/lldb-dap/completions/TestDAP_completions.py 
b/lldb/test/API/tools/lldb-dap/completions/TestDAP_completions.py
index 1792ff9953efe..2e6fc40588d3e 100644
--- a/lldb/test/API/tools/lldb-dap/completions/TestDAP_completions.py
+++ b/lldb/test/API/tools/lldb-dap/completions/TestDAP_completions.py
@@ -86,7 +86,12 @@ def test_command_completions(self):
                 {
                     "text": "region",
                     "label": "region",
-                    "detail": "Get information on the memory region containing 
an address in the current target process.",
+                    "detail": "Get information on the memory region containing 
an address "
+                    "in the current target process.\nIf this command is given 
an "
+                    "<address-expression> once and then repeated without 
options, "
+                    "it will try to print the memory region that follows the "
+                    "previously printed region. The command can be repeated "
+                    "until the end of the address range is reached.",
                 },
             ],
         )

_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to