150e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen"""
250e0534f2edd82964a997cde7a79c540e38e76baJohnny ChenUse lldb Python SBtarget.WatchAddress() API to create a watchpoint for write of '*g_char_ptr'.
350e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen"""
450e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen
550e0534f2edd82964a997cde7a79c540e38e76baJohnny Chenimport os, time
650e0534f2edd82964a997cde7a79c540e38e76baJohnny Chenimport re
750e0534f2edd82964a997cde7a79c540e38e76baJohnny Chenimport unittest2
850e0534f2edd82964a997cde7a79c540e38e76baJohnny Chenimport lldb, lldbutil
950e0534f2edd82964a997cde7a79c540e38e76baJohnny Chenfrom lldbtest import *
1050e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen
1150e0534f2edd82964a997cde7a79c540e38e76baJohnny Chenclass TargetWatchAddressAPITestCase(TestBase):
1250e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen
1350e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen    mydir = os.path.join("python_api", "watchpoint", "watchlocation")
1450e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen
1550e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen    def setUp(self):
1650e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        # Call super's setUp().
1750e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        TestBase.setUp(self)
1850e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        # Our simple source filename.
1950e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        self.source = 'main.cpp'
2050e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        # Find the line number to break inside main().
2150e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        self.line = line_number(self.source, '// Set break point at this line.')
2250e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        # This is for verifying that watch location works.
2350e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        self.violating_func = "do_bad_thing_with_location";
2450e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen
2550e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
2650e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen    @python_api_test
2721b1984e161b0cadee331d32bfd721eccfdf4b1fJohnny Chen    @dsym_test
2850e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen    def test_watch_address_with_dsym(self):
2950e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        """Exercise SBTarget.WatchAddress() API to set a watchpoint."""
3050e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        self.buildDsym()
3150e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        self.do_set_watchaddress()
3250e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen
333bf526ac0f51dda6f63be3421cd7de68720dd656Ed Maste    @expectedFailureFreeBSD('llvm.org/pr16706') # Watchpoints fail on FreeBSD
344f2353a3c264d45500293f38e21b623bf59b6117Matt Kopec    @skipIfLinux # llvm.org/pr14323 - skip due to incomplete multi-threaded debug support
3550e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen    @python_api_test
3621b1984e161b0cadee331d32bfd721eccfdf4b1fJohnny Chen    @dwarf_test
3715bb3cf9a0ba3778623e010d9f1fe9d1d67386c4Johnny Chen    def test_watch_address_with_dwarf(self):
3850e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        """Exercise SBTarget.WatchAddress() API to set a watchpoint."""
3950e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        self.buildDwarf()
4050e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        self.do_set_watchaddress()
4150e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen
423f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
433f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen    @python_api_test
443f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen    @dsym_test
453f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen    def test_watch_address_with_invalid_watch_size_with_dsym(self):
463f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen        """Exercise SBTarget.WatchAddress() API but pass an invalid watch_size."""
473f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen        self.buildDsym()
483f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen        self.do_set_watchaddress_with_invalid_watch_size()
493f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen
503f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen    @python_api_test
513f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen    @dwarf_test
523f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen    def test_watch_address_with_invalid_watch_size_with_dwarf(self):
533f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen        """Exercise SBTarget.WatchAddress() API but pass an invalid watch_size."""
543f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen        self.buildDwarf()
553f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen        self.do_set_watchaddress_with_invalid_watch_size()
563f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen
5750e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen    def do_set_watchaddress(self):
5850e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        """Use SBTarget.WatchAddress() to set a watchpoint and verify that the program stops later due to the watchpoint."""
5950e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        exe = os.path.join(os.getcwd(), "a.out")
6050e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen
6150e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        # Create a target by the debugger.
6250e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        target = self.dbg.CreateTarget(exe)
6350e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        self.assertTrue(target, VALID_TARGET)
6450e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen
6550e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        # Now create a breakpoint on main.c.
6650e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        breakpoint = target.BreakpointCreateByLocation(self.source, self.line)
6750e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        self.assertTrue(breakpoint and
6850e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen                        breakpoint.GetNumLocations() == 1,
6950e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen                        VALID_BREAKPOINT)
7050e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen
7150e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        # Now launch the process, and do not stop at the entry point.
7250e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        process = target.LaunchSimple(None, None, os.getcwd())
7350e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen
7450e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        # We should be stopped due to the breakpoint.  Get frame #0.
7550e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        process = target.GetProcess()
7650e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        self.assertTrue(process.GetState() == lldb.eStateStopped,
7750e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen                        PROCESS_STOPPED)
7850e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
7950e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        frame0 = thread.GetFrameAtIndex(0)
8050e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen
8150e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        value = frame0.FindValue('g_char_ptr',
8250e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen                                 lldb.eValueTypeVariableGlobal)
8350e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        pointee = value.CreateValueFromAddress("pointee",
8450e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen                                               value.GetValueAsUnsigned(0),
8550e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen                                               value.GetType().GetPointeeType())
8650e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        # Watch for write to *g_char_ptr.
873f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen        error = lldb.SBError();
883f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen        watchpoint = target.WatchAddress(value.GetValueAsUnsigned(), 1, False, True, error)
8950e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        self.assertTrue(value and watchpoint,
9050e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen                        "Successfully found the pointer and set a watchpoint")
9150e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        self.DebugSBValue(value)
9250e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        self.DebugSBValue(pointee)
9350e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen
9450e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        # Hide stdout if not running with '-t' option.
9550e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        if not self.TraceOn():
9650e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen            self.HideStdout()
9750e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen
9850e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        print watchpoint
9950e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen
10050e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        # Continue.  Expect the program to stop due to the variable being written to.
10150e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        process.Continue()
10250e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen
10350e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        if (self.TraceOn()):
10450e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen            lldbutil.print_stacktraces(process)
10550e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen
10650e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonWatchpoint)
10750e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        self.assertTrue(thread, "The thread stopped due to watchpoint")
10850e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        self.DebugSBValue(value)
10950e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        self.DebugSBValue(pointee)
11050e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen
11150e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        self.expect(lldbutil.print_stacktrace(thread, string_buffer=True), exe=False,
11250e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen            substrs = [self.violating_func])
11350e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen
11450e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen        # This finishes our test.
11550e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen
1163f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen    def do_set_watchaddress_with_invalid_watch_size(self):
1173f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen        """Use SBTarget.WatchAddress() to set a watchpoint with invalid watch_size and verify we get a meaningful error message."""
1183f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen        exe = os.path.join(os.getcwd(), "a.out")
1193f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen
1203f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen        # Create a target by the debugger.
1213f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen        target = self.dbg.CreateTarget(exe)
1223f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen        self.assertTrue(target, VALID_TARGET)
1233f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen
1243f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen        # Now create a breakpoint on main.c.
1253f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen        breakpoint = target.BreakpointCreateByLocation(self.source, self.line)
1263f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen        self.assertTrue(breakpoint and
1273f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen                        breakpoint.GetNumLocations() == 1,
1283f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen                        VALID_BREAKPOINT)
1293f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen
1303f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen        # Now launch the process, and do not stop at the entry point.
1313f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen        process = target.LaunchSimple(None, None, os.getcwd())
1323f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen
1333f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen        # We should be stopped due to the breakpoint.  Get frame #0.
1343f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen        process = target.GetProcess()
1353f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen        self.assertTrue(process.GetState() == lldb.eStateStopped,
1363f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen                        PROCESS_STOPPED)
1373f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen        thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
1383f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen        frame0 = thread.GetFrameAtIndex(0)
1393f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen
1403f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen        value = frame0.FindValue('g_char_ptr',
1413f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen                                 lldb.eValueTypeVariableGlobal)
1423f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen        pointee = value.CreateValueFromAddress("pointee",
1433f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen                                               value.GetValueAsUnsigned(0),
1443f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen                                               value.GetType().GetPointeeType())
1453f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen        # Watch for write to *g_char_ptr.
1463f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen        error = lldb.SBError();
1473f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen        watchpoint = target.WatchAddress(value.GetValueAsUnsigned(), 365, False, True, error)
1483f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen        self.assertFalse(watchpoint)
1493f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen        self.expect(error.GetCString(), exe=False,
1503f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen            substrs = ['watch size of %d is not supported' % 365])
1513f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen
15250e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen
15350e0534f2edd82964a997cde7a79c540e38e76baJohnny Chenif __name__ == '__main__':
15450e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen    import atexit
15550e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen    lldb.SBDebugger.Initialize()
15650e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen    atexit.register(lambda: lldb.SBDebugger.Terminate())
15750e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen    unittest2.main()
158