[Lldb-commits] [lldb] 94038c5 - [lldb] Fix 'memory write' to not allow specifying values when writing file contents

Venkata Ramanaiah Nalamothu via lldb-commits lldb-commits at lists.llvm.org
Fri Nov 26 02:20:43 PST 2021


Author: Venkata Ramanaiah Nalamothu
Date: 2021-11-26T15:50:36+05:30
New Revision: 94038c570fbc991c03fe68793c576314c231d4ee

URL: https://github.com/llvm/llvm-project/commit/94038c570fbc991c03fe68793c576314c231d4ee
DIFF: https://github.com/llvm/llvm-project/commit/94038c570fbc991c03fe68793c576314c231d4ee.diff

LOG: [lldb] Fix 'memory write' to not allow specifying values when writing file contents

Currently the 'memory write' command allows specifying the values when
writing the file contents to memory but the values are actually ignored. This
patch fixes that by erroring out when values are specified in such cases.

Reviewed By: DavidSpickett

Differential Revision: https://reviews.llvm.org/D114544

Added: 
    lldb/test/API/commands/memory/write/Makefile
    lldb/test/API/commands/memory/write/TestMemoryWrite.py
    lldb/test/API/commands/memory/write/file.txt
    lldb/test/API/commands/memory/write/main.c

Modified: 
    lldb/source/Commands/CommandObjectMemory.cpp
    lldb/source/Interpreter/CommandObject.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/source/Commands/CommandObjectMemory.cpp b/lldb/source/Commands/CommandObjectMemory.cpp
index f27d4bd7e4b26..ff508a939f0be 100644
--- a/lldb/source/Commands/CommandObjectMemory.cpp
+++ b/lldb/source/Commands/CommandObjectMemory.cpp
@@ -1240,6 +1240,7 @@ class CommandObjectMemoryWrite : public CommandObjectParsed {
     // Define the first (and only) variant of this arg.
     value_arg.arg_type = eArgTypeValue;
     value_arg.arg_repetition = eArgRepeatPlus;
+    value_arg.arg_opt_set_association = LLDB_OPT_SET_1;
 
     // There is only one variant this argument could be; put it into the
     // argument entry.
@@ -1278,6 +1279,12 @@ class CommandObjectMemoryWrite : public CommandObjectParsed {
             m_cmd_name.c_str());
         return false;
       }
+      if (argc > 1) {
+        result.AppendErrorWithFormat(
+            "%s takes only a destination address when writing file contents.\n",
+            m_cmd_name.c_str());
+        return false;
+      }
     } else if (argc < 2) {
       result.AppendErrorWithFormat(
           "%s takes a destination address and at least one value.\n",

diff  --git a/lldb/source/Interpreter/CommandObject.cpp b/lldb/source/Interpreter/CommandObject.cpp
index 64b23d04abea3..dcae27ff54790 100644
--- a/lldb/source/Interpreter/CommandObject.cpp
+++ b/lldb/source/Interpreter/CommandObject.cpp
@@ -454,6 +454,9 @@ void CommandObject::GetFormattedCommandArguments(Stream &str,
         opt_set_mask == LLDB_OPT_SET_ALL
             ? m_arguments[i]
             : OptSetFiltered(opt_set_mask, m_arguments[i]);
+    // This argument is not associated with the current option set, so skip it.
+    if (arg_entry.empty())
+      continue;
     int num_alternatives = arg_entry.size();
 
     if ((num_alternatives == 2) && IsPairType(arg_entry[0].arg_repetition)) {

diff  --git a/lldb/test/API/commands/memory/write/Makefile b/lldb/test/API/commands/memory/write/Makefile
new file mode 100644
index 0000000000000..695335e068c0c
--- /dev/null
+++ b/lldb/test/API/commands/memory/write/Makefile
@@ -0,0 +1,4 @@
+C_SOURCES := main.c
+CFLAGS_EXTRAS := -std=c99
+
+include Makefile.rules

diff  --git a/lldb/test/API/commands/memory/write/TestMemoryWrite.py b/lldb/test/API/commands/memory/write/TestMemoryWrite.py
new file mode 100644
index 0000000000000..852edf95079f7
--- /dev/null
+++ b/lldb/test/API/commands/memory/write/TestMemoryWrite.py
@@ -0,0 +1,83 @@
+"""
+Test the 'memory write' command.
+"""
+
+import lldb
+import lldbsuite.test.lldbutil as lldbutil
+
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+
+
+class MemoryWriteTestCase(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    def setUp(self):
+        # Call super's setUp().
+        TestBase.setUp(self)
+        # Find the line number to break inside main().
+        self.line = line_number('main.c', '// Set break point at this line.')
+
+    def build_run_stop(self):
+        self.build()
+        exe = self.getBuildArtifact("a.out")
+        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+        # Break in main() after the variables are assigned values.
+        lldbutil.run_break_set_by_file_and_line(self,
+                                                "main.c",
+                                                self.line,
+                                                num_expected_locations=1,
+                                                loc_exact=True)
+
+        self.runCmd("run", RUN_SUCCEEDED)
+
+        # The stop reason of the thread should be breakpoint.
+        self.expect("thread list",
+                    STOPPED_DUE_TO_BREAKPOINT,
+                    substrs=['stopped', 'stop reason = breakpoint'])
+
+        # The breakpoint should have a hit count of 1.
+        lldbutil.check_breakpoint(self, bpno = 1, expected_hit_count = 1)
+
+    @no_debug_info_test
+    def test_memory_write(self):
+        """Test the 'memory write' command for writing values and file contents."""
+        self.build_run_stop()
+
+        self.expect(
+            "memory read --format c --size 7 --count 1 `&my_string`",
+            substrs=['abcdefg'])
+
+        self.expect(
+            "memory write --format c --size 7 `&my_string` ABCDEFG")
+
+        self.expect(
+            "memory read --format c --size 7 --count 1 `&my_string`",
+            substrs=['ABCDEFG'])
+
+        self.expect(
+            "memory write --infile file.txt --size 7 `&my_string`",
+            substrs=['7 bytes were written'])
+
+        self.expect(
+            "memory read --format c --size 7 --count 1 `&my_string`",
+            substrs=['abcdefg'])
+
+        self.expect(
+            "memory write --infile file.txt --size 7 `&my_string` ABCDEFG", error=True,
+            substrs=['error: memory write takes only a destination address when writing file contents'])
+
+        self.expect(
+            "memory write --infile file.txt --size 7", error=True,
+            substrs=['error: memory write takes a destination address when writing file contents'])
+
+    @no_debug_info_test
+    def test_memory_write_command_usage_syntax(self):
+        """Test that 'memory write' command usage syntax shows it does not take values when writing file contents."""
+        self.expect(
+            "help memory write",
+            substrs=[
+                "memory write [-f <format>] [-s <byte-size>] <address> <value> [<value> [...]]",
+                "memory write -i <filename> [-s <byte-size>] [-o <offset>] <address>"])

diff  --git a/lldb/test/API/commands/memory/write/file.txt b/lldb/test/API/commands/memory/write/file.txt
new file mode 100644
index 0000000000000..b5b9ef6c6a00e
--- /dev/null
+++ b/lldb/test/API/commands/memory/write/file.txt
@@ -0,0 +1 @@
+abcdefg

diff  --git a/lldb/test/API/commands/memory/write/main.c b/lldb/test/API/commands/memory/write/main.c
new file mode 100644
index 0000000000000..1b037360e41a1
--- /dev/null
+++ b/lldb/test/API/commands/memory/write/main.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main() {
+  char my_string[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 0};
+  printf("my_string=%s\n", my_string); // Set break point at this line.
+  return 0;
+}


        


More information about the lldb-commits mailing list