2 Test lldb process launch flags.
8 from lldbsuite
.test
.decorators
import *
9 from lldbsuite
.test
.lldbtest
import *
10 from lldbsuite
.test
import lldbutil
11 from pathlib
import Path
14 class ProcessLaunchTestCase(TestBase
):
15 NO_DEBUG_INFO_TESTCASE
= True
18 # Call super's setUp().
20 self
.runCmd("settings set auto-confirm true")
23 self
.runCmd("settings clear auto-confirm")
24 TestBase
.tearDown(self
)
28 """Test that process launch I/O redirection flags work properly."""
30 exe
= self
.getBuildArtifact("a.out")
31 self
.expect("file " + exe
, patterns
=["Current executable set to .*a.out"])
33 in_file
= os
.path
.join(self
.getSourceDir(), "input-file.txt")
34 out_file
= lldbutil
.append_to_process_working_directory(self
, "output-test.out")
35 err_file
= lldbutil
.append_to_process_working_directory(self
, "output-test.err")
37 # Make sure the output files do not exist before launching the process
48 launch_command
= "process launch -i '{0}' -o '{1}' -e '{2}' -w '{3}'".format(
49 in_file
, out_file
, err_file
, self
.get_process_working_directory()
52 if lldb
.remote_platform
:
54 'platform put-file "{local}" "{remote}"'.format(
55 local
=in_file
, remote
=in_file
59 self
.expect(launch_command
, patterns
=["Process .* launched: .*a.out"])
64 out
= lldbutil
.read_file_on_target(self
, out_file
)
65 if out
!= "This should go to stdout.\n":
68 err_msg
+ " ERROR: stdout file does not contain correct output.\n"
71 err
= lldbutil
.read_file_on_target(self
, err_file
)
72 if err
!= "This should go to stderr.\n":
75 err_msg
+ " ERROR: stderr file does not contain correct output.\n"
81 # rdar://problem/9056462
82 # The process launch flag '-w' for setting the current working directory
85 @expectedFailureAll(oslist
=["freebsd", "linux"], bugnumber
="llvm.org/pr20265")
86 @expectedFailureNetBSD
87 def test_set_working_dir_nonexisting(self
):
88 """Test that '-w dir' fails to set the working dir when running the inferior with a dir which doesn't exist."""
89 d
= {"CXX_SOURCES": "print_cwd.cpp"}
90 self
.build(dictionary
=d
)
91 self
.setTearDownCleanup(d
)
92 exe
= self
.getBuildArtifact("a.out")
93 self
.runCmd("file " + exe
)
95 mywd
= "my_working_dir"
96 out_file_name
= "my_working_dir_test.out"
97 err_file_name
= "my_working_dir_test.err"
99 my_working_dir_path
= self
.getBuildArtifact(mywd
)
100 out_file_path
= os
.path
.join(my_working_dir_path
, out_file_name
)
101 err_file_path
= os
.path
.join(my_working_dir_path
, err_file_name
)
103 # Check that we get an error when we have a nonexisting path
104 invalid_dir_path
= mywd
+ "z"
105 launch_command
= "process launch -w %s -o %s -e %s" % (
114 patterns
=["error:.* No such file or directory: %s" % invalid_dir_path
],
118 def test_set_working_dir_existing(self
):
119 """Test that '-w dir' sets the working dir when running the inferior."""
120 d
= {"CXX_SOURCES": "print_cwd.cpp"}
121 self
.build(dictionary
=d
)
122 self
.setTearDownCleanup(d
)
123 exe
= self
.getBuildArtifact("a.out")
124 self
.runCmd("file " + exe
)
126 mywd
= "my_working_dir"
127 out_file_name
= "my_working_dir_test.out"
128 err_file_name
= "my_working_dir_test.err"
130 my_working_dir_path
= self
.getBuildArtifact(mywd
)
131 lldbutil
.mkdir_p(my_working_dir_path
)
132 out_file_path
= os
.path
.join(my_working_dir_path
, out_file_name
)
133 err_file_path
= os
.path
.join(my_working_dir_path
, err_file_name
)
135 # Make sure the output files do not exist before launching the process
137 os
.remove(out_file_path
)
138 os
.remove(err_file_path
)
142 launch_command
= "process launch -w %s -o %s -e %s" % (
148 self
.expect(launch_command
, patterns
=["Process .* launched: .*a.out"])
153 # Check to see if the 'stdout' file was created
155 out_f
= open(out_file_path
)
158 err_msg
= err_msg
+ "ERROR: stdout file was not created.\n"
160 # Check to see if the 'stdout' file contains the right output
161 line
= out_f
.readline()
164 if not re
.search(mywd
, line
):
167 err_msg
+ "The current working directory was not set correctly.\n"
171 # Try to delete the 'stdout' and 'stderr' files
173 os
.remove(out_file_path
)
174 os
.remove(err_file_path
)
181 def test_environment_with_special_char(self
):
182 """Test that environment variables containing '*' and '}' are handled correctly by the inferior."""
183 source
= "print_env.cpp"
184 d
= {"CXX_SOURCES": source
}
185 self
.build(dictionary
=d
)
186 self
.setTearDownCleanup(d
)
188 evil_var
= "INIT*MIDDLE}TAIL"
190 target
= self
.createTestTarget()
191 main_source_spec
= lldb
.SBFileSpec(source
)
192 breakpoint
= target
.BreakpointCreateBySourceRegex(
193 "// Set breakpoint here.", main_source_spec
196 process
= target
.LaunchSimple(
197 None, ["EVIL=" + evil_var
], self
.get_process_working_directory()
199 self
.assertEqual(process
.GetState(), lldb
.eStateStopped
, PROCESS_STOPPED
)
201 threads
= lldbutil
.get_threads_stopped_at_breakpoint(process
, breakpoint
)
202 self
.assertEqual(len(threads
), 1)
203 frame
= threads
[0].GetFrameAtIndex(0)
204 sbvalue
= frame
.EvaluateExpression("evil")
205 value
= sbvalue
.GetSummary().strip('"')
207 self
.assertEqual(value
, evil_var
)
209 self
.assertState(process
.GetState(), lldb
.eStateExited
, PROCESS_EXITED
)
212 def test_target_launch_working_dir_prop(self
):
213 """Test that the setting `target.launch-working-dir` is correctly used when launching a process."""
214 d
= {"CXX_SOURCES": "print_cwd.cpp"}
215 self
.build(dictionary
=d
)
216 self
.setTearDownCleanup(d
)
217 exe
= self
.getBuildArtifact("a.out")
218 self
.runCmd("file " + exe
)
220 mywd
= "my_working_dir"
221 out_file_name
= "my_working_dir_test.out"
223 my_working_dir_path
= self
.getBuildArtifact(mywd
)
224 lldbutil
.mkdir_p(my_working_dir_path
)
225 out_file_path
= os
.path
.join(my_working_dir_path
, out_file_name
)
226 another_working_dir_path
= Path(
227 os
.path
.join(my_working_dir_path
, "..")
230 # If -w is not passed to process launch, then the setting will be used.
232 f
"settings set target.launch-working-dir {another_working_dir_path}"
234 launch_command
= f
"process launch -o {out_file_path}"
238 patterns
=["Process .* launched: .*a.out"],
241 out
= lldbutil
.read_file_on_target(self
, out_file_path
)
243 self
.assertIn(f
"stdout: {another_working_dir_path}", out
)
245 # If -w is passed to process launch, that value will be used instead of the setting.
246 launch_command
= f
"process launch -w {my_working_dir_path} -o {out_file_path}"
250 patterns
=["Process .* launched: .*a.out"],
253 out
= lldbutil
.read_file_on_target(self
, out_file_path
)
254 self
.assertIn(f
"stdout: {my_working_dir_path}", out
)
256 # If set to empty, then LLDB's cwd will be used to launch the process.
257 self
.runCmd(f
"settings set target.launch-working-dir ''")
258 launch_command
= f
"process launch -o {out_file_path}"
262 patterns
=["Process .* launched: .*a.out"],
265 out
= lldbutil
.read_file_on_target(self
, out_file_path
)
266 self
.assertNotIn(f
"stdout: {another_working_dir_path}", out
)