1""" 2Test lldb process launch flags. 3""" 4 5from __future__ import print_function 6 7import os 8 9import lldb 10from lldbsuite.test.decorators import * 11from lldbsuite.test.lldbtest import * 12from lldbsuite.test import lldbutil 13 14import six 15 16 17class ProcessLaunchTestCase(TestBase): 18 19 mydir = TestBase.compute_mydir(__file__) 20 NO_DEBUG_INFO_TESTCASE = True 21 22 def setUp(self): 23 # Call super's setUp(). 24 TestBase.setUp(self) 25 self.runCmd("settings set auto-confirm true") 26 27 def tearDown(self): 28 self.runCmd("settings clear auto-confirm") 29 TestBase.tearDown(self) 30 31 @skipIfRemote 32 @skipIfReproducer 33 def test_io(self): 34 """Test that process launch I/O redirection flags work properly.""" 35 self.build() 36 exe = self.getBuildArtifact("a.out") 37 self.expect("file " + exe, 38 patterns=["Current executable set to .*a.out"]) 39 40 in_file = os.path.join(self.getSourceDir(), "input-file.txt") 41 out_file = lldbutil.append_to_process_working_directory(self, "output-test.out") 42 err_file = lldbutil.append_to_process_working_directory(self, "output-test.err") 43 44 # Make sure the output files do not exist before launching the process 45 try: 46 os.remove(out_file) 47 except OSError: 48 pass 49 50 try: 51 os.remove(err_file) 52 except OSError: 53 pass 54 55 launch_command = "process launch -i '{0}' -o '{1}' -e '{2}' -w '{3}'".format( 56 in_file, out_file, err_file, self.get_process_working_directory()) 57 58 if lldb.remote_platform: 59 self.runCmd('platform put-file "{local}" "{remote}"'.format( 60 local=in_file, remote=in_file)) 61 62 self.expect(launch_command, 63 patterns=["Process .* launched: .*a.out"]) 64 65 success = True 66 err_msg = "" 67 68 out = lldbutil.read_file_on_target(self, out_file) 69 if out != "This should go to stdout.\n": 70 success = False 71 err_msg = err_msg + " ERROR: stdout file does not contain correct output.\n" 72 73 74 err = lldbutil.read_file_on_target(self, err_file) 75 if err != "This should go to stderr.\n": 76 success = False 77 err_msg = err_msg + " ERROR: stderr file does not contain correct output.\n" 78 79 if not success: 80 self.fail(err_msg) 81 82 # rdar://problem/9056462 83 # The process launch flag '-w' for setting the current working directory 84 # not working? 85 @skipIfRemote 86 @expectedFailureAll(oslist=["freebsd", "linux"], bugnumber="llvm.org/pr20265") 87 @expectedFailureNetBSD 88 @skipIfReproducer 89 def test_set_working_dir_nonexisting(self): 90 """Test that '-w dir' fails to set the working dir when running the inferior with a dir which doesn't exist.""" 91 d = {'CXX_SOURCES': 'print_cwd.cpp'} 92 self.build(dictionary=d) 93 self.setTearDownCleanup(d) 94 exe = self.getBuildArtifact("a.out") 95 self.runCmd("file " + exe) 96 97 mywd = 'my_working_dir' 98 out_file_name = "my_working_dir_test.out" 99 err_file_name = "my_working_dir_test.err" 100 101 my_working_dir_path = self.getBuildArtifact(mywd) 102 out_file_path = os.path.join(my_working_dir_path, out_file_name) 103 err_file_path = os.path.join(my_working_dir_path, err_file_name) 104 105 # Check that we get an error when we have a nonexisting path 106 invalid_dir_path = mywd + 'z' 107 launch_command = "process launch -w %s -o %s -e %s" % ( 108 invalid_dir_path, out_file_path, err_file_path) 109 110 self.expect( 111 launch_command, error=True, patterns=[ 112 "error:.* No such file or directory: %s" % 113 invalid_dir_path]) 114 115 @skipIfRemote 116 @skipIfReproducer 117 def test_set_working_dir_existing(self): 118 """Test that '-w dir' sets the working dir when running the inferior.""" 119 d = {'CXX_SOURCES': 'print_cwd.cpp'} 120 self.build(dictionary=d) 121 self.setTearDownCleanup(d) 122 exe = self.getBuildArtifact("a.out") 123 self.runCmd("file " + exe) 124 125 mywd = 'my_working_dir' 126 out_file_name = "my_working_dir_test.out" 127 err_file_name = "my_working_dir_test.err" 128 129 my_working_dir_path = self.getBuildArtifact(mywd) 130 lldbutil.mkdir_p(my_working_dir_path) 131 out_file_path = os.path.join(my_working_dir_path, out_file_name) 132 err_file_path = os.path.join(my_working_dir_path, err_file_name) 133 134 # Make sure the output files do not exist before launching the process 135 try: 136 os.remove(out_file_path) 137 os.remove(err_file_path) 138 except OSError: 139 pass 140 141 launch_command = "process launch -w %s -o %s -e %s" % ( 142 my_working_dir_path, out_file_path, err_file_path) 143 144 self.expect(launch_command, 145 patterns=["Process .* launched: .*a.out"]) 146 147 success = True 148 err_msg = "" 149 150 # Check to see if the 'stdout' file was created 151 try: 152 out_f = open(out_file_path) 153 except IOError: 154 success = False 155 err_msg = err_msg + "ERROR: stdout file was not created.\n" 156 else: 157 # Check to see if the 'stdout' file contains the right output 158 line = out_f.readline() 159 if self.TraceOn(): 160 print("line:", line) 161 if not re.search(mywd, line): 162 success = False 163 err_msg = err_msg + "The current working directory was not set correctly.\n" 164 out_f.close() 165 166 # Try to delete the 'stdout' and 'stderr' files 167 try: 168 os.remove(out_file_path) 169 os.remove(err_file_path) 170 except OSError: 171 pass 172 173 if not success: 174 self.fail(err_msg) 175 176 @skipIfReproducer 177 def test_environment_with_special_char(self): 178 """Test that environment variables containing '*' and '}' are handled correctly by the inferior.""" 179 source = 'print_env.cpp' 180 d = {'CXX_SOURCES': source} 181 self.build(dictionary=d) 182 self.setTearDownCleanup(d) 183 exe = self.getBuildArtifact("a.out") 184 185 evil_var = 'INIT*MIDDLE}TAIL' 186 187 target = self.dbg.CreateTarget(exe) 188 main_source_spec = lldb.SBFileSpec(source) 189 breakpoint = target.BreakpointCreateBySourceRegex( 190 '// Set breakpoint here.', main_source_spec) 191 192 process = target.LaunchSimple(None, 193 ['EVIL=' + evil_var], 194 self.get_process_working_directory()) 195 self.assertEqual( 196 process.GetState(), 197 lldb.eStateStopped, 198 PROCESS_STOPPED) 199 200 threads = lldbutil.get_threads_stopped_at_breakpoint( 201 process, breakpoint) 202 self.assertEqual(len(threads), 1) 203 frame = threads[0].GetFrameAtIndex(0) 204 sbvalue = frame.EvaluateExpression("evil") 205 value = sbvalue.GetSummary().strip('"') 206 207 self.assertEqual(value, evil_var) 208 process.Continue() 209 self.assertEqual(process.GetState(), lldb.eStateExited, PROCESS_EXITED) 210