Skip to content

Commit 99de991

Browse files
authored
Merge pull request #2891 from apple/🍒/ganymede/710651c61dcd
[lldb] Fix bug where memory read --outfile is not truncating the file
2 parents d217d8b + 93254f4 commit 99de991

File tree

2 files changed

+58
-13
lines changed

2 files changed

+58
-13
lines changed

lldb/source/Commands/CommandObjectMemory.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -767,10 +767,11 @@ class CommandObjectMemoryRead : public CommandObjectParsed {
767767
std::string path = outfile_spec.GetPath();
768768
if (outfile_spec) {
769769

770-
auto open_options = File::eOpenOptionWrite | File::eOpenOptionCanCreate;
770+
File::OpenOptions open_options =
771+
File::eOpenOptionWrite | File::eOpenOptionCanCreate;
771772
const bool append = m_outfile_options.GetAppend().GetCurrentValue();
772-
if (append)
773-
open_options |= File::eOpenOptionAppend;
773+
open_options |=
774+
append ? File::eOpenOptionAppend : File::eOpenOptionTruncate;
774775

775776
auto outfile = FileSystem::Instance().Open(outfile_spec, open_options);
776777

lldb/test/API/functionalities/memory/read/TestMemoryRead.py

Lines changed: 54 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
Test the 'memory read' command.
33
"""
44

5-
6-
75
import lldb
8-
from lldbsuite.test.lldbtest import *
96
import lldbsuite.test.lldbutil as lldbutil
107

8+
from lldbsuite.test.decorators import *
9+
from lldbsuite.test.lldbtest import *
10+
1111

1212
class MemoryReadTestCase(TestBase):
1313

@@ -19,27 +19,34 @@ def setUp(self):
1919
# Find the line number to break inside main().
2020
self.line = line_number('main.cpp', '// Set break point at this line.')
2121

22-
def test_memory_read(self):
23-
"""Test the 'memory read' command with plain and vector formats."""
22+
def build_run_stop(self):
2423
self.build()
2524
exe = self.getBuildArtifact("a.out")
2625
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
2726

2827
# Break in main() after the variables are assigned values.
29-
lldbutil.run_break_set_by_file_and_line(
30-
self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
28+
lldbutil.run_break_set_by_file_and_line(self,
29+
"main.cpp",
30+
self.line,
31+
num_expected_locations=1,
32+
loc_exact=True)
3133

3234
self.runCmd("run", RUN_SUCCEEDED)
3335

3436
# The stop reason of the thread should be breakpoint.
35-
self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
37+
self.expect("thread list",
38+
STOPPED_DUE_TO_BREAKPOINT,
3639
substrs=['stopped', 'stop reason = breakpoint'])
3740

3841
# The breakpoint should have a hit count of 1.
39-
self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE,
42+
self.expect("breakpoint list -f",
43+
BREAKPOINT_HIT_ONCE,
4044
substrs=[' resolved, hit count = 1'])
4145

42-
# Test the memory read commands.
46+
@no_debug_info_test
47+
def test_memory_read(self):
48+
"""Test the 'memory read' command with plain and vector formats."""
49+
self.build_run_stop()
4350

4451
# (lldb) memory read -f d -c 1 `&argc`
4552
# 0x7fff5fbff9a0: 1
@@ -131,3 +138,40 @@ def test_memory_read(self):
131138
for o in objects_read:
132139
self.assertEqual(len(o), expected_object_length)
133140
self.assertEquals(len(objects_read), 4)
141+
142+
@no_debug_info_test
143+
def test_memory_read_file(self):
144+
self.build_run_stop()
145+
res = lldb.SBCommandReturnObject()
146+
self.ci.HandleCommand("memory read -f d -c 1 `&argc`", res)
147+
self.assertTrue(res.Succeeded(), "memory read failed:" + res.GetError())
148+
149+
# Record golden output.
150+
golden_output = res.GetOutput()
151+
152+
memory_read_file = self.getBuildArtifact("memory-read-output")
153+
154+
def check_file_content(expected):
155+
with open(memory_read_file) as f:
156+
lines = f.readlines()
157+
lines = [s.strip() for s in lines]
158+
expected = [s.strip() for s in expected]
159+
self.assertEqual(lines, expected)
160+
161+
# Sanity check.
162+
self.runCmd("memory read -f d -c 1 -o '{}' `&argc`".format(memory_read_file))
163+
check_file_content([golden_output])
164+
165+
# Write some garbage to the file.
166+
with open(memory_read_file, 'w') as f:
167+
f.write("some garbage")
168+
169+
# Make sure the file is truncated when we run the command again.
170+
self.runCmd("memory read -f d -c 1 -o '{}' `&argc`".format(memory_read_file))
171+
check_file_content([golden_output])
172+
173+
# Make sure the file is appended when we run the command with --append-outfile.
174+
self.runCmd(
175+
"memory read -f d -c 1 -o '{}' --append-outfile `&argc`".format(
176+
memory_read_file))
177+
check_file_content([golden_output, golden_output])

0 commit comments

Comments
 (0)