diff --git a/lldb/source/Commands/CommandObjectMemory.cpp b/lldb/source/Commands/CommandObjectMemory.cpp --- a/lldb/source/Commands/CommandObjectMemory.cpp +++ b/lldb/source/Commands/CommandObjectMemory.cpp @@ -1240,6 +1240,7 @@ // 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 @@ 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 --- a/lldb/source/Interpreter/CommandObject.cpp +++ b/lldb/source/Interpreter/CommandObject.cpp @@ -454,6 +454,9 @@ 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 --- /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 --- /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 ] [-s ]
[ [...]]", + "memory write -i [-s ] [-o ]
"]) diff --git a/lldb/test/API/commands/memory/write/file.txt b/lldb/test/API/commands/memory/write/file.txt new file mode 100644 --- /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 --- /dev/null +++ b/lldb/test/API/commands/memory/write/main.c @@ -0,0 +1,7 @@ +#include + +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; +}