[clang] Fix implicit integer conversion for opaque enums declared in class templates...
[llvm-project.git] / lldb / test / API / commands / process / launch / TestProcessLaunch.py
blob2d23c0a48960e1a1d1f2e04121cd9c4307cbc928
1 """
2 Test lldb process launch flags.
3 """
5 import os
7 import lldb
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
17 def setUp(self):
18 # Call super's setUp().
19 TestBase.setUp(self)
20 self.runCmd("settings set auto-confirm true")
22 def tearDown(self):
23 self.runCmd("settings clear auto-confirm")
24 TestBase.tearDown(self)
26 @skipIfRemote
27 def test_io(self):
28 """Test that process launch I/O redirection flags work properly."""
29 self.build()
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
38 try:
39 os.remove(out_file)
40 except OSError:
41 pass
43 try:
44 os.remove(err_file)
45 except OSError:
46 pass
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:
53 self.runCmd(
54 'platform put-file "{local}" "{remote}"'.format(
55 local=in_file, remote=in_file
59 self.expect(launch_command, patterns=["Process .* launched: .*a.out"])
61 success = True
62 err_msg = ""
64 out = lldbutil.read_file_on_target(self, out_file)
65 if out != "This should go to stdout.\n":
66 success = False
67 err_msg = (
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":
73 success = False
74 err_msg = (
75 err_msg + " ERROR: stderr file does not contain correct output.\n"
78 if not success:
79 self.fail(err_msg)
81 # rdar://problem/9056462
82 # The process launch flag '-w' for setting the current working directory
83 # not working?
84 @skipIfRemote
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" % (
106 invalid_dir_path,
107 out_file_path,
108 err_file_path,
111 self.expect(
112 launch_command,
113 error=True,
114 patterns=["error:.* No such file or directory: %s" % invalid_dir_path],
117 @skipIfRemote
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
136 try:
137 os.remove(out_file_path)
138 os.remove(err_file_path)
139 except OSError:
140 pass
142 launch_command = "process launch -w %s -o %s -e %s" % (
143 my_working_dir_path,
144 out_file_path,
145 err_file_path,
148 self.expect(launch_command, patterns=["Process .* launched: .*a.out"])
150 success = True
151 err_msg = ""
153 # Check to see if the 'stdout' file was created
154 try:
155 out_f = open(out_file_path)
156 except IOError:
157 success = False
158 err_msg = err_msg + "ERROR: stdout file was not created.\n"
159 else:
160 # Check to see if the 'stdout' file contains the right output
161 line = out_f.readline()
162 if self.TraceOn():
163 print("line:", line)
164 if not re.search(mywd, line):
165 success = False
166 err_msg = (
167 err_msg + "The current working directory was not set correctly.\n"
169 out_f.close()
171 # Try to delete the 'stdout' and 'stderr' files
172 try:
173 os.remove(out_file_path)
174 os.remove(err_file_path)
175 except OSError:
176 pass
178 if not success:
179 self.fail(err_msg)
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)
208 process.Continue()
209 self.assertState(process.GetState(), lldb.eStateExited, PROCESS_EXITED)
211 @skipIfRemote
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, "..")
228 ).resolve()
230 # If -w is not passed to process launch, then the setting will be used.
231 self.runCmd(
232 f"settings set target.launch-working-dir {another_working_dir_path}"
234 launch_command = f"process launch -o {out_file_path}"
236 self.expect(
237 launch_command,
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}"
248 self.expect(
249 launch_command,
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}"
260 self.expect(
261 launch_command,
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)