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
