| """ |
| Test lldb process launch flags. |
| """ |
| |
| from __future__ import print_function |
| |
| import copy |
| import os |
| import time |
| |
| import lldb |
| from lldbsuite.test.decorators import * |
| from lldbsuite.test.lldbtest import * |
| from lldbsuite.test import lldbutil |
| |
| import six |
| |
| |
| class ProcessLaunchTestCase(TestBase): |
| |
| mydir = TestBase.compute_mydir(__file__) |
| NO_DEBUG_INFO_TESTCASE = True |
| |
| def setUp(self): |
| # Call super's setUp(). |
| TestBase.setUp(self) |
| self.runCmd("settings set auto-confirm true") |
| |
| def tearDown(self): |
| self.runCmd("settings clear auto-confirm") |
| TestBase.tearDown(self) |
| |
| @not_remote_testsuite_ready |
| def test_io(self): |
| """Test that process launch I/O redirection flags work properly.""" |
| self.build() |
| exe = self.getBuildArtifact("a.out") |
| self.expect("file " + exe, |
| patterns=["Current executable set to .*a.out"]) |
| |
| in_file = os.path.join(self.getSourceDir(), "input-file.txt") |
| out_file = lldbutil.append_to_process_working_directory(self, "output-test.out") |
| err_file = lldbutil.append_to_process_working_directory(self, "output-test.err") |
| |
| # Make sure the output files do not exist before launching the process |
| try: |
| os.remove(out_file) |
| except OSError: |
| pass |
| |
| try: |
| os.remove(err_file) |
| except OSError: |
| pass |
| |
| launch_command = "process launch -i '{0}' -o '{1}' -e '{2}' -w '{3}'".format( |
| in_file, out_file, err_file, self.get_process_working_directory()) |
| |
| if lldb.remote_platform: |
| self.runCmd('platform put-file "{local}" "{remote}"'.format( |
| local=in_file, remote=in_file)) |
| |
| self.expect(launch_command, |
| patterns=["Process .* launched: .*a.out"]) |
| |
| success = True |
| err_msg = "" |
| |
| out = lldbutil.read_file_on_target(self, out_file) |
| if out != "This should go to stdout.\n": |
| success = False |
| err_msg = err_msg + " ERROR: stdout file does not contain correct output.\n" |
| |
| |
| err = lldbutil.read_file_on_target(self, err_file) |
| if err != "This should go to stderr.\n": |
| success = False |
| err_msg = err_msg + " ERROR: stderr file does not contain correct output.\n" |
| |
| if not success: |
| self.fail(err_msg) |
| |
| # rdar://problem/9056462 |
| # The process launch flag '-w' for setting the current working directory |
| # not working? |
| @not_remote_testsuite_ready |
| @expectedFailureAll(oslist=["linux"], bugnumber="llvm.org/pr20265") |
| def test_set_working_dir_nonexisting(self): |
| """Test that '-w dir' fails to set the working dir when running the inferior with a dir which doesn't exist.""" |
| d = {'CXX_SOURCES': 'print_cwd.cpp'} |
| self.build(dictionary=d) |
| self.setTearDownCleanup(d) |
| exe = self.getBuildArtifact("a.out") |
| self.runCmd("file " + exe) |
| |
| mywd = 'my_working_dir' |
| out_file_name = "my_working_dir_test.out" |
| err_file_name = "my_working_dir_test.err" |
| |
| my_working_dir_path = self.getBuildArtifact(mywd) |
| out_file_path = os.path.join(my_working_dir_path, out_file_name) |
| err_file_path = os.path.join(my_working_dir_path, err_file_name) |
| |
| # Check that we get an error when we have a nonexisting path |
| invalid_dir_path = mywd + 'z' |
| launch_command = "process launch -w %s -o %s -e %s" % ( |
| invalid_dir_path, out_file_path, err_file_path) |
| |
| self.expect( |
| launch_command, error=True, patterns=[ |
| "error:.* No such file or directory: %s" % |
| invalid_dir_path]) |
| |
| @not_remote_testsuite_ready |
| def test_set_working_dir_existing(self): |
| """Test that '-w dir' sets the working dir when running the inferior.""" |
| d = {'CXX_SOURCES': 'print_cwd.cpp'} |
| self.build(dictionary=d) |
| self.setTearDownCleanup(d) |
| exe = self.getBuildArtifact("a.out") |
| self.runCmd("file " + exe) |
| |
| mywd = 'my_working_dir' |
| out_file_name = "my_working_dir_test.out" |
| err_file_name = "my_working_dir_test.err" |
| |
| my_working_dir_path = self.getBuildArtifact(mywd) |
| lldbutil.mkdir_p(my_working_dir_path) |
| out_file_path = os.path.join(my_working_dir_path, out_file_name) |
| err_file_path = os.path.join(my_working_dir_path, err_file_name) |
| |
| # Make sure the output files do not exist before launching the process |
| try: |
| os.remove(out_file_path) |
| os.remove(err_file_path) |
| except OSError: |
| pass |
| |
| launch_command = "process launch -w %s -o %s -e %s" % ( |
| my_working_dir_path, out_file_path, err_file_path) |
| |
| self.expect(launch_command, |
| patterns=["Process .* launched: .*a.out"]) |
| |
| success = True |
| err_msg = "" |
| |
| # Check to see if the 'stdout' file was created |
| try: |
| out_f = open(out_file_path) |
| except IOError: |
| success = False |
| err_msg = err_msg + "ERROR: stdout file was not created.\n" |
| else: |
| # Check to see if the 'stdout' file contains the right output |
| line = out_f.readline() |
| if self.TraceOn(): |
| print("line:", line) |
| if not re.search(mywd, line): |
| success = False |
| err_msg = err_msg + "The current working directory was not set correctly.\n" |
| out_f.close() |
| |
| # Try to delete the 'stdout' and 'stderr' files |
| try: |
| os.remove(out_file_path) |
| os.remove(err_file_path) |
| pass |
| except OSError: |
| pass |
| |
| if not success: |
| self.fail(err_msg) |
| |
| def test_environment_with_special_char(self): |
| """Test that environment variables containing '*' and '}' are handled correctly by the inferior.""" |
| source = 'print_env.cpp' |
| d = {'CXX_SOURCES': source} |
| self.build(dictionary=d) |
| self.setTearDownCleanup(d) |
| exe = self.getBuildArtifact("a.out") |
| |
| evil_var = 'INIT*MIDDLE}TAIL' |
| |
| target = self.dbg.CreateTarget(exe) |
| main_source_spec = lldb.SBFileSpec(source) |
| breakpoint = target.BreakpointCreateBySourceRegex( |
| '// Set breakpoint here.', main_source_spec) |
| |
| process = target.LaunchSimple(None, |
| ['EVIL=' + evil_var], |
| self.get_process_working_directory()) |
| self.assertEqual( |
| process.GetState(), |
| lldb.eStateStopped, |
| PROCESS_STOPPED) |
| |
| threads = lldbutil.get_threads_stopped_at_breakpoint( |
| process, breakpoint) |
| self.assertEqual(len(threads), 1) |
| frame = threads[0].GetFrameAtIndex(0) |
| sbvalue = frame.EvaluateExpression("evil") |
| value = sbvalue.GetSummary().strip('"') |
| |
| self.assertEqual(value, evil_var) |
| process.Continue() |
| self.assertEqual(process.GetState(), lldb.eStateExited, PROCESS_EXITED) |
| pass |