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