1"""
2Test my first lldb watchpoint.
3"""
4
5
6
7import lldb
8from lldbsuite.test.decorators import *
9from lldbsuite.test.lldbtest import *
10from lldbsuite.test import lldbutil
11
12
13class HelloWatchpointTestCase(TestBase):
14    NO_DEBUG_INFO_TESTCASE = True
15
16    def setUp(self):
17        # Call super's setUp().
18        TestBase.setUp(self)
19        # Our simple source filename.
20        self.source = 'main.c'
21        # Find the line number to break inside main().
22        self.line = line_number(
23            self.source, '// Set break point at this line.')
24        # And the watchpoint variable declaration line number.
25        self.decl = line_number(self.source,
26                                '// Watchpoint variable declaration.')
27        self.exe_name = self.getBuildArtifact('a.out')
28        self.d = {'C_SOURCES': self.source, 'EXE': self.exe_name}
29
30    @add_test_categories(["basic_process"])
31    def test_hello_watchpoint_using_watchpoint_set(self):
32        """Test a simple sequence of watchpoint creation and watchpoint hit."""
33        self.build(dictionary=self.d)
34        self.setTearDownCleanup(dictionary=self.d)
35
36        exe = self.getBuildArtifact(self.exe_name)
37        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
38
39        # Add a breakpoint to set a watchpoint when stopped on the breakpoint.
40        lldbutil.run_break_set_by_file_and_line(
41            self, None, self.line, num_expected_locations=1)
42
43        # Run the program.
44        self.runCmd("run", RUN_SUCCEEDED)
45
46        # We should be stopped again due to the breakpoint.
47        # The stop reason of the thread should be breakpoint.
48        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
49                    substrs=['stopped',
50                             'stop reason = breakpoint'])
51
52        # Now let's set a write-type watchpoint for 'global'.
53        # There should be only one watchpoint hit (see main.c).
54        self.expect(
55            "watchpoint set variable -w write global",
56            WATCHPOINT_CREATED,
57            substrs=[
58                'Watchpoint created',
59                'size = 4',
60                'type = w',
61                '%s:%d' %
62                (self.source,
63                 self.decl)])
64
65        # Use the '-v' option to do verbose listing of the watchpoint.
66        # The hit count should be 0 initially.
67        self.expect("watchpoint list -v",
68                    substrs=['hit_count = 0'])
69
70        self.runCmd("process continue")
71
72        # We should be stopped again due to the watchpoint (write type), but
73        # only once.  The stop reason of the thread should be watchpoint.
74        self.expect("thread list", STOPPED_DUE_TO_WATCHPOINT,
75                    substrs=['stopped',
76                             'stop reason = watchpoint'])
77
78        self.runCmd("process continue")
79
80        # Don't expect the read of 'global' to trigger a stop exception.
81        process = self.dbg.GetSelectedTarget().GetProcess()
82        if process.GetState() == lldb.eStateStopped:
83            self.assertFalse(
84                lldbutil.get_stopped_thread(
85                    process, lldb.eStopReasonWatchpoint))
86
87        # Use the '-v' option to do verbose listing of the watchpoint.
88        # The hit count should now be 1.
89        self.expect("watchpoint list -v",
90                    substrs=['hit_count = 1'])
91