1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
"""
Use lldb Python SBtarget.WatchAddress() API to create a watchpoint for write of '*g_char_ptr'.
"""
import os, time
import re
import unittest2
import lldb, lldbutil
from lldbtest import *
class TargetWatchAddressAPITestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
# Our simple source filename.
self.source = 'main.cpp'
# Find the line number to break inside main().
self.line = line_number(self.source, '// Set break point at this line.')
# This is for verifying that watch location works.
self.violating_func = "do_bad_thing_with_location";
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
@dsym_test
def test_watch_address_with_dsym(self):
"""Exercise SBTarget.WatchAddress() API to set a watchpoint."""
self.buildDsym()
self.do_set_watchaddress()
@python_api_test
@dwarf_test
@expectedFailureLinux # failed 11/100 dosep runs
def test_watch_address_with_dwarf(self):
"""Exercise SBTarget.WatchAddress() API to set a watchpoint."""
self.buildDwarf()
self.do_set_watchaddress()
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
@dsym_test
def test_watch_address_with_invalid_watch_size_with_dsym(self):
"""Exercise SBTarget.WatchAddress() API but pass an invalid watch_size."""
self.buildDsym()
self.do_set_watchaddress_with_invalid_watch_size()
@python_api_test
@dwarf_test
@expectedFailureGcc #xfail to get buildbot green, test failed with gcc4.8.2
def test_watch_address_with_invalid_watch_size_with_dwarf(self):
"""Exercise SBTarget.WatchAddress() API but pass an invalid watch_size."""
self.buildDwarf()
self.do_set_watchaddress_with_invalid_watch_size()
def do_set_watchaddress(self):
"""Use SBTarget.WatchAddress() to set a watchpoint and verify that the program stops later due to the watchpoint."""
exe = os.path.join(os.getcwd(), "a.out")
# Create a target by the debugger.
target = self.dbg.CreateTarget(exe)
self.assertTrue(target, VALID_TARGET)
# Now create a breakpoint on main.c.
breakpoint = target.BreakpointCreateByLocation(self.source, self.line)
self.assertTrue(breakpoint and
breakpoint.GetNumLocations() == 1,
VALID_BREAKPOINT)
# Now launch the process, and do not stop at the entry point.
process = target.LaunchSimple (None, None, self.get_process_working_directory())
# We should be stopped due to the breakpoint. Get frame #0.
process = target.GetProcess()
self.assertTrue(process.GetState() == lldb.eStateStopped,
PROCESS_STOPPED)
thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
frame0 = thread.GetFrameAtIndex(0)
value = frame0.FindValue('g_char_ptr',
lldb.eValueTypeVariableGlobal)
pointee = value.CreateValueFromAddress("pointee",
value.GetValueAsUnsigned(0),
value.GetType().GetPointeeType())
# Watch for write to *g_char_ptr.
error = lldb.SBError();
watchpoint = target.WatchAddress(value.GetValueAsUnsigned(), 1, False, True, error)
self.assertTrue(value and watchpoint,
"Successfully found the pointer and set a watchpoint")
self.DebugSBValue(value)
self.DebugSBValue(pointee)
# Hide stdout if not running with '-t' option.
if not self.TraceOn():
self.HideStdout()
print watchpoint
# Continue. Expect the program to stop due to the variable being written to.
process.Continue()
if (self.TraceOn()):
lldbutil.print_stacktraces(process)
thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonWatchpoint)
self.assertTrue(thread, "The thread stopped due to watchpoint")
self.DebugSBValue(value)
self.DebugSBValue(pointee)
self.expect(lldbutil.print_stacktrace(thread, string_buffer=True), exe=False,
substrs = [self.violating_func])
# This finishes our test.
def do_set_watchaddress_with_invalid_watch_size(self):
"""Use SBTarget.WatchAddress() to set a watchpoint with invalid watch_size and verify we get a meaningful error message."""
exe = os.path.join(os.getcwd(), "a.out")
# Create a target by the debugger.
target = self.dbg.CreateTarget(exe)
self.assertTrue(target, VALID_TARGET)
# Now create a breakpoint on main.c.
breakpoint = target.BreakpointCreateByLocation(self.source, self.line)
self.assertTrue(breakpoint and
breakpoint.GetNumLocations() == 1,
VALID_BREAKPOINT)
# Now launch the process, and do not stop at the entry point.
process = target.LaunchSimple (None, None, self.get_process_working_directory())
# We should be stopped due to the breakpoint. Get frame #0.
process = target.GetProcess()
self.assertTrue(process.GetState() == lldb.eStateStopped,
PROCESS_STOPPED)
thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
frame0 = thread.GetFrameAtIndex(0)
value = frame0.FindValue('g_char_ptr',
lldb.eValueTypeVariableGlobal)
pointee = value.CreateValueFromAddress("pointee",
value.GetValueAsUnsigned(0),
value.GetType().GetPointeeType())
# Watch for write to *g_char_ptr.
error = lldb.SBError();
watchpoint = target.WatchAddress(value.GetValueAsUnsigned(), 365, False, True, error)
self.assertFalse(watchpoint)
self.expect(error.GetCString(), exe=False,
substrs = ['watch size of %d is not supported' % 365])
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
atexit.register(lambda: lldb.SBDebugger.Terminate())
unittest2.main()
|