예제 #1
0
    def test(self):
        self.build()
        # Launch and stop before the dlopen call.
        lldbutil.run_to_source_breakpoint(self, "// break here",
                                          lldb.SBFileSpec("main.c"))

        # Delete the breakpoint we no longer need.
        self.target().DeleteAllBreakpoints()

        # Check that the executable is the test binary.
        self.assertEqual(self.target().GetExecutable().GetFilename(), "a.out")

        # Continue so that dlopen is called.
        breakpoint = self.target().BreakpointCreateBySourceRegex(
            "// break after dlopen", lldb.SBFileSpec("main.c"))
        self.assertNotEqual(breakpoint.GetNumResolvedLocations(), 0)
        stopped_threads = lldbutil.continue_to_breakpoint(
            self.process(), breakpoint)
        self.assertEqual(len(stopped_threads), 1)

        # Check that the executable is still the test binary and not "other".
        self.assertEqual(self.target().GetExecutable().GetFilename(), "a.out")

        # Kill the process and run the program again.
        err = self.process().Kill()
        self.assertSuccess(err)

        # Test that we hit the breakpoint after dlopen.
        lldbutil.run_to_breakpoint_do_run(self, self.target(), breakpoint)
예제 #2
0
    def test_thread_local(self):
        # Set a breakpoint on the first instruction of the main function,
        # before the TLS initialization has run.
        self.build()
        exe = self.getBuildArtifact("a.out")

        (target, process, _, _) = \
            lldbutil.run_to_source_breakpoint(self, "Set breakpoint here",
                                              lldb.SBFileSpec("main.cpp"))
        self.expect_expr("tl_local_int + 1",
                         result_type="int",
                         result_value="323")
        self.expect_expr("*tl_local_ptr + 2",
                         result_type="int",
                         result_value="324")
        self.expect_expr("tl_global_int",
                         result_type="int",
                         result_value="123")
        self.expect_expr("*tl_global_ptr",
                         result_type="int",
                         result_value="45")

        # Create the filespec by which to locate our a.out module.
        #
        #  - Use the absolute path to get the module for the current variant.
        #  - Use the relative path for reproducers. The modules are never
        #    orphaned because the SB objects are leaked intentionally. This
        #    causes LLDB to reuse the same module for every variant, because the
        #    UUID is the same for all the inferiors. FindModule below only
        #    compares paths and is oblivious to the fact that the UUIDs are the
        #    same.
        if configuration.is_reproducer():
            filespec = lldb.SBFileSpec('a.out', False)
        else:
            filespec = lldb.SBFileSpec(exe, False)

        # Now see if we emit the correct error when the TLS is not yet
        # initialized. Let's set a breakpoint on the first instruction
        # of main.
        main_module = target.FindModule(filespec)
        self.assertTrue(main_module, VALID_MODULE)
        main_address = main_module.FindSymbol("main").GetStartAddress()
        main_bkpt = target.BreakpointCreateBySBAddress(main_address)

        process.Kill()
        lldbutil.run_to_breakpoint_do_run(self, target, main_bkpt)

        self.expect("expr tl_local_int",
                    error=True,
                    substrs=[
                        "couldn't get the value of variable tl_local_int",
                        "No TLS data currently exists for this thread"
                    ])
        self.expect("expr *tl_local_ptr",
                    error=True,
                    substrs=[
                        "couldn't get the value of variable tl_local_ptr",
                        "No TLS data currently exists for this thread"
                    ])
예제 #3
0
    def test_thread_local(self):
        # Set a breakpoint on the first instruction of the main function,
        # before the TLS initialization has run.
        self.build()
        exe = self.getBuildArtifact("a.out")

        (target, process, _, _) = \
            lldbutil.run_to_source_breakpoint(self, "Set breakpoint here",
                                              lldb.SBFileSpec("main.cpp"))
        self.expect_expr("tl_local_int + 1",
                         result_type="int",
                         result_value="323")
        self.expect_expr("*tl_local_ptr + 2",
                         result_type="int",
                         result_value="324")
        self.expect_expr("tl_global_int",
                         result_type="int",
                         result_value="123")
        self.expect_expr("*tl_global_ptr",
                         result_type="int",
                         result_value="45")

        # Create the filespec by which to locate our a.out module. Use the
        # absolute path to get the module for the current variant.
        filespec = lldb.SBFileSpec(exe, False)

        # Now see if we emit the correct error when the TLS is not yet
        # initialized. Let's set a breakpoint on the first instruction
        # of main.
        main_module = target.FindModule(filespec)
        self.assertTrue(main_module, VALID_MODULE)
        main_address = main_module.FindSymbol("main").GetStartAddress()
        main_bkpt = target.BreakpointCreateBySBAddress(main_address)

        process.Kill()
        lldbutil.run_to_breakpoint_do_run(self, target, main_bkpt)

        self.expect("expr tl_local_int",
                    error=True,
                    substrs=[
                        "couldn't get the value of variable tl_local_int",
                        "No TLS data currently exists for this thread"
                    ])
        self.expect("expr *tl_local_ptr",
                    error=True,
                    substrs=[
                        "couldn't get the value of variable tl_local_ptr",
                        "No TLS data currently exists for this thread"
                    ])
예제 #4
0
    def after_expr_test(self):
        interp = self.dbg.GetCommandInterpreter()
        result = lldb.SBCommandReturnObject()
        interp.HandleCommand("target stop-hook add -o 'expr g_var++'", result)
        self.assertTrue(result.Succeeded, "Set the target stop hook")

        (target, process, thread,
         first_bkpt) = lldbutil.run_to_source_breakpoint(
             self, "Set a breakpoint here", self.main_source_file)

        var = target.FindFirstGlobalVariable("g_var")
        self.assertTrue(var.IsValid())
        self.assertEqual(var.GetValueAsUnsigned(), 1, "Updated g_var")

        bkpt = target.BreakpointCreateBySourceRegex("Continue to here",
                                                    self.main_source_file)
        self.assertNotEqual(bkpt.GetNumLocations(), 0,
                            "Set the second breakpoint")
        commands = lldb.SBStringList()
        commands.AppendString("expr increment_gvar()")
        bkpt.SetCommandLineCommands(commands)

        threads = lldbutil.continue_to_breakpoint(process, bkpt)
        self.assertEqual(len(threads), 1, "Hit my breakpoint")

        self.assertTrue(var.IsValid())
        self.assertEqual(var.GetValueAsUnsigned(), 3, "Updated g_var")

        # Make sure running an expression does NOT run the stop hook.
        # Our expression will increment it by one, but the stop shouldn't
        # have gotten it to 5.
        threads[0].frames[0].EvaluateExpression("increment_gvar()")
        self.assertTrue(var.IsValid())
        self.assertEqual(var.GetValueAsUnsigned(), 4, "Updated g_var")

        # Make sure a rerun doesn't upset the state we've set up:
        process.Kill()
        lldbutil.run_to_breakpoint_do_run(self, target, first_bkpt)
        var = target.FindFirstGlobalVariable("g_var")
        self.assertTrue(var.IsValid())
        self.assertEqual(var.GetValueAsUnsigned(), 1, "Updated g_var")
예제 #5
0
    def test_expr(self):
        with open(self.getBuildArtifact("module.modulemap"), "w") as f:
            f.write("""
                    module Foo { header "f.h" }
                    """)
        with open(self.getBuildArtifact("f.h"), "w") as f:
            f.write("""
                    struct Q { int i; };
                    void f() {}
                    """)

        mod_cache = self.getBuildArtifact("private-module-cache")
        if os.path.isdir(mod_cache):
            shutil.rmtree(mod_cache)
        d = {'OBJC_SOURCES': 'first.m'}
        self.build(dictionary=d)
        self.assertTrue(os.path.isdir(mod_cache), "module cache exists")

        logfile = self.getBuildArtifact("modules.log")
        self.runCmd("log enable -f %s lldb module" % logfile)
        target, process, _, bkpt = lldbutil.run_to_name_breakpoint(
            self, "main")
        self.assertIn("int i", str(target.FindTypes('Q').GetTypeAtIndex(0)))
        self.expect("image list -g", patterns=[r'first\.o', r'Foo.*\.pcm'])

        # Update the module.
        with open(self.getBuildArtifact("f.h"), "w") as f:
            f.write("""
                    struct S { int i; };
                    struct S getS() { struct S r = {1}; return r; }
                    void f() {}
                    """)

        # Rebuild.
        d = {'OBJC_SOURCES': 'second.m'}
        self.build(dictionary=d)

        # Reattach.
        process.Kill()
        target, process, _, _ = lldbutil.run_to_breakpoint_do_run(
            self, target, bkpt)
        self.assertIn("int i", str(target.FindTypes('S').GetTypeAtIndex(0)))
        self.expect("image list -g", patterns=[r'second\.o', r'Foo.*\.pcm'])

        # Check log file.
        found = False
        with open(logfile, 'r') as f:
            for line in f:
                if "module changed" in line and "Foo" in line:
                    found = True
        self.assertTrue(found)
    def test_rebuild_app_modules_untouched(self):
        with open(self.getBuildArtifact("module.modulemap"), "w") as f:
            f.write("""
                    module Foo { header "f.h" }
                    """)
        with open(self.getBuildArtifact("f.h"), "w") as f:
            f.write("""
                    @import Foundation;
                    @interface Foo : NSObject {
                       int i;
                    }
                    +(instancetype)init;
                    @end
                    """)

        mod_cache = self.getBuildArtifact("private-module-cache")
        import os
        if os.path.isdir(mod_cache):
            shutil.rmtree(mod_cache)
        self.build()
        self.assertTrue(os.path.isdir(mod_cache), "module cache exists")

        target, process, _, bkpt = lldbutil.run_to_source_breakpoint(
            self, "break here", lldb.SBFileSpec("main.m"))
        bar = target.FindTypes('Bar').GetTypeAtIndex(0)
        foo = bar.GetDirectBaseClassAtIndex(0).GetType()
        self.assertEqual(foo.GetNumberOfFields(), 1)
        self.assertEqual(foo.GetFieldAtIndex(0).GetName(), "i")

        # Rebuild.
        process.Kill()
        os.remove(self.getBuildArtifact('main.o'))
        os.remove(self.getBuildArtifact('a.out'))
        self.build()

        # Reattach.
        target, process, _, _ = lldbutil.run_to_breakpoint_do_run(
            self, target, bkpt)
        bar = target.FindTypes('Bar').GetTypeAtIndex(0)
        foo = bar.GetDirectBaseClassAtIndex(0).GetType()
        self.assertEqual(foo.GetNumberOfFields(), 1)
        self.assertEqual(foo.GetFieldAtIndex(0).GetName(), "i")
예제 #7
0
    def do_test(self):
        """This reads in a python file and sets a breakpoint using it."""

        target = self.make_target_and_import()
        extra_args = self.make_extra_args()

        file_list = lldb.SBFileSpecList()
        module_list = lldb.SBFileSpecList()

        # Make breakpoints with this resolver using different filters, first ones that will take:
        right = []
        # one with no file or module spec - this one should fire:
        right.append(target.BreakpointCreateFromScript("resolver.Resolver", extra_args, module_list, file_list))

        # one with the right source file and no module - should also fire:
        file_list.Append(lldb.SBFileSpec("main.c"))
        right.append(target.BreakpointCreateFromScript("resolver.Resolver", extra_args, module_list, file_list))
        # Make sure the help text shows up in the "break list" output:
        self.expect("break list", substrs=["I am a python breakpoint resolver"], msg="Help is listed in break list")

        # one with the right source file and right module - should also fire:
        module_list.Append(lldb.SBFileSpec("a.out"))
        right.append(target.BreakpointCreateFromScript("resolver.Resolver", extra_args, module_list, file_list))

        # And one with no source file but the right module:
        file_list.Clear()
        right.append(target.BreakpointCreateFromScript("resolver.Resolver", extra_args, module_list, file_list))

        # Make sure these all got locations:
        for i in range (0, len(right)):
            self.assertTrue(right[i].GetNumLocations() >= 1, "Breakpoint %d has no locations."%(i))

        # Now some ones that won't take:

        module_list.Clear()
        file_list.Clear()
        wrong = []

        # one with the wrong module - should not fire:
        module_list.Append(lldb.SBFileSpec("noSuchModule"))
        wrong.append(target.BreakpointCreateFromScript("resolver.Resolver", extra_args, module_list, file_list))

        # one with the wrong file - also should not fire:
        file_list.Clear()
        module_list.Clear()
        file_list.Append(lldb.SBFileSpec("noFileOfThisName.xxx"))
        wrong.append(target.BreakpointCreateFromScript("resolver.Resolver", extra_args, module_list, file_list))
        
        # Now make sure the CU level iteration obeys the file filters:
        file_list.Clear()
        module_list.Clear()
        file_list.Append(lldb.SBFileSpec("no_such_file.xxx"))
        wrong.append(target.BreakpointCreateFromScript("resolver.ResolverCUDepth", extra_args, module_list, file_list))

        # And the Module filters:
        file_list.Clear()
        module_list.Clear()
        module_list.Append(lldb.SBFileSpec("NoSuchModule.dylib"))
        wrong.append(target.BreakpointCreateFromScript("resolver.ResolverCUDepth", extra_args, module_list, file_list))

        # Now make sure the Function level iteration obeys the file filters:
        file_list.Clear()
        module_list.Clear()
        file_list.Append(lldb.SBFileSpec("no_such_file.xxx"))
        wrong.append(target.BreakpointCreateFromScript("resolver.ResolverFuncDepth", extra_args, module_list, file_list))

        # And the Module filters:
        file_list.Clear()
        module_list.Clear()
        module_list.Append(lldb.SBFileSpec("NoSuchModule.dylib"))
        wrong.append(target.BreakpointCreateFromScript("resolver.ResolverFuncDepth", extra_args, module_list, file_list))

        # Make sure these didn't get locations:
        for i in range(0, len(wrong)):
            self.assertEqual(wrong[i].GetNumLocations(), 0, "Breakpoint %d has locations."%(i))

        # Now run to main and ensure we hit the breakpoints we should have:

        lldbutil.run_to_breakpoint_do_run(self, target, right[0])
        
        # Test the hit counts:
        for i in range(0, len(right)):
            self.assertEqual(right[i].GetHitCount(), 1, "Breakpoint %d has the wrong hit count"%(i))

        for i in range(0, len(wrong)):
            self.assertEqual(wrong[i].GetHitCount(), 0, "Breakpoint %d has the wrong hit count"%(i))
예제 #8
0
    def test_process_handle(self):
        """Test that calling process handle before we have a target, and before we
           have a process will affect the process.  Also that the signal settings
           are preserved on rerun."""
        self.build()

        # Make sure we don't accept signal values by signo with no process - we don't know what the
        # mapping will be so we can't do the right thing with bare numbers:
        lldbutil.set_actions_for_signal(self,
                                        "9",
                                        "true",
                                        None,
                                        None,
                                        expect_success=False)

        # First, I need a reference value so I can see whether changes actually took:
        (target, process, _,
         bkpt) = lldbutil.run_to_source_breakpoint(self, '// break here',
                                                   lldb.SBFileSpec("main.cpp"))
        (default_pass, default_stop,
         default_notify) = lldbutil.get_actions_for_signal(self, "SIGSEGV")

        # Let's change the value here, then exit and make sure the changed value sticks:
        new_value = "false"
        if default_pass == "true":
            new_value = "false"

        # First make sure we get an error for bogus values when running:
        lldbutil.set_actions_for_signal(self,
                                        "NOTSIGSEGV",
                                        new_value,
                                        None,
                                        None,
                                        expect_success=False)

        # Then set the one we intend to change.
        lldbutil.set_actions_for_signal(self, "SIGSEGV", new_value, None, None)

        process.Continue()

        self.assertEqual(process.GetState(), lldb.eStateExited)
        self.assertEqual(process.GetExitStatus(), 0)

        # Check that we preserved the setting:
        (curr_pass, curr_stop,
         curr_notify) = lldbutil.get_actions_for_signal(self,
                                                        "SIGSEGV",
                                                        from_target=True)
        self.assertEqual(curr_pass, new_value, "Pass was set correctly")
        self.assertEqual(curr_stop, "not set", "Stop was not set by us")
        self.assertEqual(curr_notify, "not set", "Notify was not set by us")

        # Run again and make sure that we prime the new process with these settings:
        process = lldbutil.run_to_breakpoint_do_run(self, target, bkpt)

        # We check the process settings now, to see what got copied into the process:
        (curr_pass, curr_stop,
         curr_notify) = lldbutil.get_actions_for_signal(self, "SIGSEGV")
        self.assertEqual(curr_pass, new_value, "Pass was set correctly")
        self.assertEqual(curr_stop, default_stop, "Stop was its default value")
        self.assertEqual(curr_notify, default_notify,
                         "Notify was its default value")

        # Now kill this target, set the handling and make sure the values get copied from the dummy into the new target.
        success = self.dbg.DeleteTarget(target)
        self.assertTrue(success, "Deleted the target")
        self.assertEqual(self.dbg.GetNumTargets(), 0,
                         "We did delete all the targets.")

        # The signal settings should be back at their default - we were only setting this on the target:
        lldbutil.get_actions_for_signal(self,
                                        "SIGSEGV",
                                        from_target=True,
                                        expected_absent=True)
        # Set a valid one:
        lldbutil.set_actions_for_signal(self, "SIGSEGV", new_value, None, None)
        # Set a bogus one - we don't have a way to check pre-run so this is allowed
        # but we should get an error message when launching:
        lldbutil.set_actions_for_signal(self, "SIGNOTSIG", new_value, None,
                                        None)

        out_filename = self.getBuildArtifact('output')
        success = True
        try:
            f = open(out_filename, 'w')
        except:
            success = False

        if not success:
            self.fail("Couldn't open error output file for writing.")

        self.dbg.SetErrorFileHandle(f, False)
        # Now make a new process and make sure the right values got copied into the new target
        (target, process, _,
         bkpt) = lldbutil.run_to_source_breakpoint(self, '// break here',
                                                   lldb.SBFileSpec("main.cpp"))
        f.write("TESTPATTERN\n")
        f.flush()
        f.close()

        try:
            f = open(out_filename, 'r')
        except:
            success = False

        if not success:
            self.fail("Couldn't open error output file for reading")
        errors = f.read()
        f.close()

        self.assertIn("SIGNOTSIG", errors, "We warned about the unset signal")
        # Also make sure we didn't accidentally add this bogus setting to the process.
        lldbutil.set_actions_for_signal(self,
                                        "SIGNOTSIG",
                                        "true",
                                        "true",
                                        "true",
                                        expect_success=False)

        # Check that they went into the target:
        (curr_pass, curr_stop,
         curr_notify) = lldbutil.get_actions_for_signal(self,
                                                        "SIGSEGV",
                                                        from_target=True)
        self.assertEqual(curr_pass, new_value, "Pass was set correctly")
        self.assertEqual(curr_stop, "not set", "Stop was not set by us")
        self.assertEqual(curr_notify, "not set", "Notify was not set by us")

        # And the process:
        # Check that they went into the target:
        (curr_pass, curr_stop,
         curr_notify) = lldbutil.get_actions_for_signal(self, "SIGSEGV")
        self.assertEqual(curr_pass, new_value, "Pass was set correctly")
        self.assertEqual(curr_stop, default_stop, "Stop was its default value")
        self.assertEqual(curr_notify, default_notify,
                         "Notify was its default value")

        # Now clear the handling, and make sure that we get the right signal values again:
        self.runCmd("process handle -c SIGSEGV")
        # Check that there is no longer configuration for SIGSEGV in the target:
        lldbutil.get_actions_for_signal(self,
                                        "SIGSEGV",
                                        from_target=True,
                                        expected_absent=True)
        # Make a new process, to make sure we did indeed reset the values:
        (target, process, _,
         bkpt) = lldbutil.run_to_source_breakpoint(self, '// break here',
                                                   lldb.SBFileSpec("main.cpp"))
        (curr_pass, curr_stop,
         curr_notify) = lldbutil.get_actions_for_signal(self, "SIGSEGV")
        self.assertEqual(curr_pass, new_value, "Pass was set correctly")
        self.assertEqual(curr_stop, default_stop, "Stop was its default value")
        self.assertEqual(curr_notify, default_notify,
                         "Notify was its default value")

        # Finally remove this from the dummy target as well, and make sure it was cleared from there:
        self.runCmd("process handle -c -d SIGSEGV")
        error = process.Kill()
        self.assertSuccess(error, "Killed the process")
        success = self.dbg.DeleteTarget(target)
        self.assertTrue(success, "Destroyed the target.")

        (target, process, _,
         bkpt) = lldbutil.run_to_source_breakpoint(self, '// break here',
                                                   lldb.SBFileSpec("main.cpp"))
        (curr_pass, curr_stop,
         curr_notify) = lldbutil.get_actions_for_signal(self, "SIGSEGV")
        self.assertEqual(curr_pass, default_pass, "Pass was set correctly")
        self.assertEqual(curr_stop, default_stop, "Stop was its default value")
        self.assertEqual(curr_notify, default_notify,
                         "Notify was its default value")