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