blob: 76e29c52c8cca67d2d05367b4da3296ba51226b1 [file] [log] [blame]
Johnny Chenbf6ffa32010-07-03 03:41:59 +00001"""
2LLDB module which provides the abstract base class of lldb test case.
3
4The concrete subclass can override lldbtest.TesBase in order to inherit the
5common behavior for unitest.TestCase.setUp/tearDown implemented in this file.
6
7The subclass should override the attribute mydir in order for the python runtime
8to locate the individual test cases when running as part of a large test suite
9or when running each test case as a separate python invocation.
10
11./dotest.py provides a test driver which sets up the environment to run the
12entire test suite. Users who want to run a test case on its own can specify the
13LLDB_TEST and PYTHONPATH environment variables, for example:
14
15$ export LLDB_TEST=$PWD
Johnny Chen8d55a342010-08-31 17:42:54 +000016$ export PYTHONPATH=/Volumes/data/lldb/svn/trunk/build/Debug/LLDB.framework/Resources/Python:$LLDB_TEST:$LLDB_TEST/plugins
Johnny Chenbf6ffa32010-07-03 03:41:59 +000017$ echo $LLDB_TEST
18/Volumes/data/lldb/svn/trunk/test
19$ echo $PYTHONPATH
Johnny Chen8d55a342010-08-31 17:42:54 +000020/Volumes/data/lldb/svn/trunk/build/Debug/LLDB.framework/Resources/Python:/Volumes/data/lldb/svn/trunk/test:/Volumes/data/lldb/svn/trunk/test/plugins
Johnny Chenbf6ffa32010-07-03 03:41:59 +000021$ python function_types/TestFunctionTypes.py
22.
23----------------------------------------------------------------------
24Ran 1 test in 0.363s
25
26OK
Johnny Chend0190a62010-08-23 17:10:44 +000027$ LLDB_COMMAND_TRACE=YES python array_types/TestArrayTypes.py
Johnny Chen57b47382010-09-02 22:25:47 +000028
29...
Johnny Chend0190a62010-08-23 17:10:44 +000030
31runCmd: breakpoint set -f main.c -l 42
32output: Breakpoint created: 1: file ='main.c', line = 42, locations = 1
33
34runCmd: run
35output: Launching '/Volumes/data/lldb/svn/trunk/test/array_types/a.out' (x86_64)
36
Johnny Chen57b47382010-09-02 22:25:47 +000037...
Johnny Chend0190a62010-08-23 17:10:44 +000038
Johnny Chen57b47382010-09-02 22:25:47 +000039runCmd: frame variable strings
Johnny Chend0190a62010-08-23 17:10:44 +000040output: (char *[4]) strings = {
41 (char *) strings[0] = 0x0000000100000f0c "Hello",
42 (char *) strings[1] = 0x0000000100000f12 "Hola",
43 (char *) strings[2] = 0x0000000100000f17 "Bonjour",
44 (char *) strings[3] = 0x0000000100000f1f "Guten Tag"
45}
46
Johnny Chen57b47382010-09-02 22:25:47 +000047runCmd: frame variable char_16
Johnny Chend0190a62010-08-23 17:10:44 +000048output: (char [16]) char_16 = {
49 (char) char_16[0] = 'H',
50 (char) char_16[1] = 'e',
51 (char) char_16[2] = 'l',
52 (char) char_16[3] = 'l',
53 (char) char_16[4] = 'o',
54 (char) char_16[5] = ' ',
55 (char) char_16[6] = 'W',
56 (char) char_16[7] = 'o',
57 (char) char_16[8] = 'r',
58 (char) char_16[9] = 'l',
59 (char) char_16[10] = 'd',
60 (char) char_16[11] = '\n',
61 (char) char_16[12] = '\0',
62 (char) char_16[13] = '\0',
63 (char) char_16[14] = '\0',
64 (char) char_16[15] = '\0'
65}
66
Johnny Chen57b47382010-09-02 22:25:47 +000067runCmd: frame variable ushort_matrix
Johnny Chend0190a62010-08-23 17:10:44 +000068output: (unsigned short [2][3]) ushort_matrix = {
69 (unsigned short [3]) ushort_matrix[0] = {
70 (unsigned short) ushort_matrix[0][0] = 0x0001,
71 (unsigned short) ushort_matrix[0][1] = 0x0002,
72 (unsigned short) ushort_matrix[0][2] = 0x0003
73 },
74 (unsigned short [3]) ushort_matrix[1] = {
75 (unsigned short) ushort_matrix[1][0] = 0x000b,
76 (unsigned short) ushort_matrix[1][1] = 0x0016,
77 (unsigned short) ushort_matrix[1][2] = 0x0021
78 }
79}
80
Johnny Chen57b47382010-09-02 22:25:47 +000081runCmd: frame variable long_6
Johnny Chend0190a62010-08-23 17:10:44 +000082output: (long [6]) long_6 = {
83 (long) long_6[0] = 1,
84 (long) long_6[1] = 2,
85 (long) long_6[2] = 3,
86 (long) long_6[3] = 4,
87 (long) long_6[4] = 5,
88 (long) long_6[5] = 6
89}
90
91.
92----------------------------------------------------------------------
93Ran 1 test in 0.349s
94
95OK
Johnny Chenbf6ffa32010-07-03 03:41:59 +000096$
97"""
98
Johnny Chen8952a2d2010-08-30 21:35:00 +000099import os, sys
100from subprocess import *
Johnny Chenf2b70232010-08-25 18:49:48 +0000101import time
Johnny Chena33a93c2010-08-30 23:08:52 +0000102import types
Johnny Chen73258832010-08-05 23:42:46 +0000103import unittest2
Johnny Chenbf6ffa32010-07-03 03:41:59 +0000104import lldb
105
Johnny Chen8d55a342010-08-31 17:42:54 +0000106if "LLDB_COMMAND_TRACE" in os.environ and os.environ["LLDB_COMMAND_TRACE"]=="YES":
107 traceAlways = True
108else:
109 traceAlways = False
110
111
Johnny Chen00778092010-08-09 22:01:17 +0000112#
113# Some commonly used assert messages.
114#
115
116CURRENT_EXECUTABLE_SET = "Current executable set successfully"
117
Johnny Chen7d1d7532010-09-02 21:23:12 +0000118PROCESS_IS_VALID = "Process is valid"
119
120PROCESS_KILLED = "Process is killed successfully"
121
Johnny Chen5ee88192010-08-27 23:47:36 +0000122RUN_SUCCEEDED = "Process is launched successfully"
Johnny Chen00778092010-08-09 22:01:17 +0000123
Johnny Chen17941842010-08-09 23:44:24 +0000124RUN_COMPLETED = "Process exited successfully"
Johnny Chen00778092010-08-09 22:01:17 +0000125
Johnny Chen17941842010-08-09 23:44:24 +0000126BREAKPOINT_CREATED = "Breakpoint created successfully"
127
Johnny Chene76896c2010-08-17 21:33:31 +0000128BREAKPOINT_PENDING_CREATED = "Pending breakpoint created successfully"
129
Johnny Chen17941842010-08-09 23:44:24 +0000130BREAKPOINT_HIT_ONCE = "Breakpoint resolved with hit cout = 1"
Johnny Chen00778092010-08-09 22:01:17 +0000131
132STOPPED_DUE_TO_BREAKPOINT = "Process state is stopped due to breakpoint"
133
134STOPPED_DUE_TO_STEP_IN = "Process state is stopped due to step in"
135
Johnny Chen3c884a02010-08-24 22:07:56 +0000136DATA_TYPES_DISPLAYED_CORRECTLY = "Data type(s) displayed correctly"
137
Johnny Chen5fca8ca2010-08-26 20:04:17 +0000138VALID_BREAKPOINT = "Got a valid breakpoint"
139
Johnny Chen5ee88192010-08-27 23:47:36 +0000140VALID_FILESPEC = "Got a valid filespec"
141
Johnny Chen5fca8ca2010-08-26 20:04:17 +0000142VALID_PROCESS = "Got a valid process"
143
144VALID_TARGET = "Got a valid target"
145
Johnny Chen981463d2010-08-25 19:00:04 +0000146VARIABLES_DISPLAYED_CORRECTLY = "Variable(s) displayed correctly"
Johnny Chen00778092010-08-09 22:01:17 +0000147
Johnny Chen5fca8ca2010-08-26 20:04:17 +0000148
Johnny Chen17941842010-08-09 23:44:24 +0000149#
150# And a generic "Command '%s' returns successfully" message generator.
151#
152def CMD_MSG(command):
153 return "Command '%s' returns successfully" % (command)
154
Johnny Chen5fca8ca2010-08-26 20:04:17 +0000155#
Johnny Chen82d404c82010-08-27 18:08:58 +0000156# Returns the enum from the input string.
Johnny Chen5fca8ca2010-08-26 20:04:17 +0000157#
Johnny Chen82d404c82010-08-27 18:08:58 +0000158def StopReasonEnum(string):
159 if string == "Invalid":
Johnny Chen5fca8ca2010-08-26 20:04:17 +0000160 return 0
Johnny Chen82d404c82010-08-27 18:08:58 +0000161 elif string == "None":
Johnny Chen5fca8ca2010-08-26 20:04:17 +0000162 return 1
Johnny Chen82d404c82010-08-27 18:08:58 +0000163 elif string == "Trace":
Johnny Chen5fca8ca2010-08-26 20:04:17 +0000164 return 2
Johnny Chen82d404c82010-08-27 18:08:58 +0000165 elif string == "Breakpoint":
Johnny Chen5fca8ca2010-08-26 20:04:17 +0000166 return 3
Johnny Chen82d404c82010-08-27 18:08:58 +0000167 elif string == "Watchpoint":
Johnny Chen5fca8ca2010-08-26 20:04:17 +0000168 return 4
Johnny Chen82d404c82010-08-27 18:08:58 +0000169 elif string == "Signal":
Johnny Chen5fca8ca2010-08-26 20:04:17 +0000170 return 5
Johnny Chen82d404c82010-08-27 18:08:58 +0000171 elif string == "Exception":
Johnny Chen5fca8ca2010-08-26 20:04:17 +0000172 return 6
Johnny Chen82d404c82010-08-27 18:08:58 +0000173 elif string == "PlanComplete":
Johnny Chen5fca8ca2010-08-26 20:04:17 +0000174 return 7
175 else:
176 raise Exception("Unknown stopReason string")
Johnny Chen17941842010-08-09 23:44:24 +0000177
Johnny Chen27c41232010-08-26 21:49:29 +0000178#
Johnny Chen82d404c82010-08-27 18:08:58 +0000179# Returns the stopReason string given an enum.
180#
181def StopReasonString(enum):
182 if enum == 0:
183 return "Invalid"
184 elif enum == 1:
185 return "None"
186 elif enum == 2:
187 return "Trace"
188 elif enum == 3:
189 return "Breakpoint"
190 elif enum == 4:
191 return "Watchpoint"
192 elif enum == 5:
193 return "Signal"
194 elif enum == 6:
195 return "Exception"
196 elif enum == 7:
197 return "PlanComplete"
198 else:
199 raise Exception("Unknown stopReason enum")
200
201#
Johnny Chen27c41232010-08-26 21:49:29 +0000202# Returns an env variable array from the os.environ map object.
203#
204def EnvArray():
205 return map(lambda k,v: k+"="+v, os.environ.keys(), os.environ.values())
206
Johnny Chen8d55a342010-08-31 17:42:54 +0000207# From 2.7's subprocess.check_output() convenience function.
208def system(*popenargs, **kwargs):
209 r"""Run command with arguments and return its output as a byte string.
210
211 If the exit code was non-zero it raises a CalledProcessError. The
212 CalledProcessError object will have the return code in the returncode
213 attribute and output in the output attribute.
214
215 The arguments are the same as for the Popen constructor. Example:
216
217 >>> check_output(["ls", "-l", "/dev/null"])
218 'crw-rw-rw- 1 root root 1, 3 Oct 18 2007 /dev/null\n'
219
220 The stdout argument is not allowed as it is used internally.
221 To capture standard error in the result, use stderr=STDOUT.
222
223 >>> check_output(["/bin/sh", "-c",
224 ... "ls -l non_existent_file ; exit 0"],
225 ... stderr=STDOUT)
226 'ls: non_existent_file: No such file or directory\n'
227 """
228 if 'stdout' in kwargs:
229 raise ValueError('stdout argument not allowed, it will be overridden.')
230 process = Popen(stdout=PIPE, *popenargs, **kwargs)
Johnny Chen1aad5c62010-09-14 22:01:40 +0000231 output, error = process.communicate()
Johnny Chen8d55a342010-08-31 17:42:54 +0000232 retcode = process.poll()
233
234 if traceAlways:
235 if isinstance(popenargs, types.StringTypes):
236 args = [popenargs]
237 else:
238 args = list(popenargs)
239 print >> sys.stderr
240 print >> sys.stderr, "os command:", args
Johnny Chene0490512010-09-14 22:39:02 +0000241 print >> sys.stderr, "stdout:", output
242 print >> sys.stderr, "stderr:", error
243 print >> sys.stderr, "retcode:", retcode
Johnny Chen1aad5c62010-09-14 22:01:40 +0000244 print >> sys.stderr
Johnny Chen8d55a342010-08-31 17:42:54 +0000245
246 if retcode:
247 cmd = kwargs.get("args")
248 if cmd is None:
249 cmd = popenargs[0]
Johnny Chen2fcc0e52010-09-16 18:26:06 +0000250 raise CalledProcessError(retcode, cmd)
Johnny Chen8d55a342010-08-31 17:42:54 +0000251 return output
252
Johnny Chen827edff2010-08-27 00:15:48 +0000253
Johnny Chen73258832010-08-05 23:42:46 +0000254class TestBase(unittest2.TestCase):
Johnny Chenbf6ffa32010-07-03 03:41:59 +0000255 """This LLDB abstract base class is meant to be subclassed."""
256
257 # The concrete subclass should override this attribute.
Johnny Chenf02ec122010-07-03 20:41:42 +0000258 mydir = None
Johnny Chenbf6ffa32010-07-03 03:41:59 +0000259
Johnny Chen6ca006c2010-08-16 21:28:10 +0000260 # State pertaining to the inferior process, if any.
Johnny Chen57b47382010-09-02 22:25:47 +0000261 # This reflects inferior process started through the command interface with
262 # either the lldb "run" or "process launch" command.
263 # See also self.runCmd().
Johnny Chen6ca006c2010-08-16 21:28:10 +0000264 runStarted = False
265
Johnny Chenf2b70232010-08-25 18:49:48 +0000266 # Maximum allowed attempts when launching the inferior process.
267 # Can be overridden by the LLDB_MAX_LAUNCH_COUNT environment variable.
268 maxLaunchCount = 3;
269
270 # Time to wait before the next launching attempt in second(s).
271 # Can be overridden by the LLDB_TIME_WAIT environment variable.
272 timeWait = 1.0;
273
Johnny Chen1a9f4dd2010-09-16 01:53:04 +0000274 # Keep track of the old current working directory.
275 oldcwd = None
Johnny Chena2124952010-08-05 21:23:45 +0000276
Johnny Chen1a9f4dd2010-09-16 01:53:04 +0000277 @classmethod
278 def setUpClass(cls):
Johnny Chenf02ec122010-07-03 20:41:42 +0000279 # Fail fast if 'mydir' attribute is not overridden.
Johnny Chen1a9f4dd2010-09-16 01:53:04 +0000280 if not cls.mydir or len(cls.mydir) == 0:
Johnny Chenf02ec122010-07-03 20:41:42 +0000281 raise Exception("Subclasses must override the 'mydir' attribute.")
Johnny Chenbf6ffa32010-07-03 03:41:59 +0000282 # Save old working directory.
Johnny Chen1a9f4dd2010-09-16 01:53:04 +0000283 cls.oldcwd = os.getcwd()
Johnny Chenbf6ffa32010-07-03 03:41:59 +0000284
285 # Change current working directory if ${LLDB_TEST} is defined.
286 # See also dotest.py which sets up ${LLDB_TEST}.
287 if ("LLDB_TEST" in os.environ):
Johnny Chen1a9f4dd2010-09-16 01:53:04 +0000288 if traceAlways:
289 print "Change dir to:", os.path.join(os.environ["LLDB_TEST"], cls.mydir)
290 os.chdir(os.path.join(os.environ["LLDB_TEST"], cls.mydir))
291
292 @classmethod
293 def tearDownClass(cls):
294 """Do class-wide cleanup."""
295
296 # First, let's do the platform-specific cleanup.
297 module = __import__(sys.platform)
298 if not module.cleanup():
299 raise Exception("Don't know how to do cleanup")
300
301 # Subclass might have specific cleanup function defined.
302 if getattr(cls, "classCleanup", None):
303 if traceAlways:
304 print "Call class-specific cleanup function for class:", cls
305 cls.classCleanup()
306
307 # Restore old working directory.
308 if traceAlways:
309 print "Restore dir to:", cls.oldcwd
310 os.chdir(cls.oldcwd)
311
312 def setUp(self):
313 #import traceback
314 #traceback.print_stack()
Johnny Chenbf6ffa32010-07-03 03:41:59 +0000315
Johnny Chenf2b70232010-08-25 18:49:48 +0000316 if "LLDB_MAX_LAUNCH_COUNT" in os.environ:
317 self.maxLaunchCount = int(os.environ["LLDB_MAX_LAUNCH_COUNT"])
318
319 if "LLDB_TIME_WAIT" in os.environ:
320 self.timeWait = float(os.environ["LLDB_TIME_WAIT"])
321
Johnny Chenbf6ffa32010-07-03 03:41:59 +0000322 # Create the debugger instance if necessary.
323 try:
324 self.dbg = lldb.DBG
Johnny Chenbf6ffa32010-07-03 03:41:59 +0000325 except AttributeError:
326 self.dbg = lldb.SBDebugger.Create()
Johnny Chenf02ec122010-07-03 20:41:42 +0000327
Johnny Chenbf6ffa32010-07-03 03:41:59 +0000328 if not self.dbg.IsValid():
329 raise Exception('Invalid debugger instance')
330
331 # We want our debugger to be synchronous.
332 self.dbg.SetAsync(False)
333
Johnny Chen7d1d7532010-09-02 21:23:12 +0000334 # There is no process associated with the debugger as yet.
Johnny Chen57b47382010-09-02 22:25:47 +0000335 # See also self.tearDown() where it checks whether self.process has a
336 # valid reference and calls self.process.Kill() to kill the process.
Johnny Chen7d1d7532010-09-02 21:23:12 +0000337 self.process = None
338
Johnny Chenbf6ffa32010-07-03 03:41:59 +0000339 # Retrieve the associated command interpreter instance.
340 self.ci = self.dbg.GetCommandInterpreter()
341 if not self.ci:
342 raise Exception('Could not get the command interpreter')
343
344 # And the result object.
345 self.res = lldb.SBCommandReturnObject()
346
Johnny Chenbf6ffa32010-07-03 03:41:59 +0000347 def tearDown(self):
Johnny Chen7d1d7532010-09-02 21:23:12 +0000348 #import traceback
349 #traceback.print_stack()
350
351 # Terminate the current process being debugged, if any.
Johnny Chen6ca006c2010-08-16 21:28:10 +0000352 if self.runStarted:
Johnny Chen7d1d7532010-09-02 21:23:12 +0000353 self.runCmd("process kill", PROCESS_KILLED, check=False)
354 elif self.process and self.process.IsValid():
355 rc = self.process.Kill()
356 self.assertTrue(rc.Success(), PROCESS_KILLED)
Johnny Chen6ca006c2010-08-16 21:28:10 +0000357
Johnny Chenbf6ffa32010-07-03 03:41:59 +0000358 del self.dbg
359
Johnny Chen63dfb272010-09-01 00:15:19 +0000360 def runCmd(self, cmd, msg=None, check=True, trace=False, setCookie=True):
Johnny Chen27f212d2010-08-19 23:26:59 +0000361 """
362 Ask the command interpreter to handle the command and then check its
363 return status.
364 """
365 # Fail fast if 'cmd' is not meaningful.
366 if not cmd or len(cmd) == 0:
367 raise Exception("Bad 'cmd' parameter encountered")
Johnny Chen5bbb88f2010-08-20 17:57:32 +0000368
Johnny Chen8d55a342010-08-31 17:42:54 +0000369 trace = (True if traceAlways else trace)
Johnny Chend0190a62010-08-23 17:10:44 +0000370
Johnny Chen63dfb272010-09-01 00:15:19 +0000371 running = (cmd.startswith("run") or cmd.startswith("process launch"))
Johnny Chen5bbb88f2010-08-20 17:57:32 +0000372
Johnny Chen63dfb272010-09-01 00:15:19 +0000373 for i in range(self.maxLaunchCount if running else 1):
Johnny Chenf2b70232010-08-25 18:49:48 +0000374 self.ci.HandleCommand(cmd, self.res)
Johnny Chen5bbb88f2010-08-20 17:57:32 +0000375
Johnny Chenf2b70232010-08-25 18:49:48 +0000376 if trace:
377 print >> sys.stderr, "runCmd:", cmd
378 if self.res.Succeeded():
379 print >> sys.stderr, "output:", self.res.GetOutput()
380 else:
381 print >> sys.stderr, self.res.GetError()
Johnny Chen5bbb88f2010-08-20 17:57:32 +0000382
Johnny Chen725945d2010-09-03 22:35:47 +0000383 if running:
384 # For process launch, wait some time before possible next try.
385 time.sleep(self.timeWait)
386
Johnny Chenff3d01d2010-08-20 21:03:09 +0000387 if self.res.Succeeded():
Johnny Chenf2b70232010-08-25 18:49:48 +0000388 break
Johnny Chenf7f0cab2010-09-15 17:33:57 +0000389 elif running:
Johnny Chen9fa03212010-09-15 18:00:19 +0000390 print >> sys.stderr, "Command '" + cmd + "' failed!"
Johnny Chen5bbb88f2010-08-20 17:57:32 +0000391
Johnny Chen7d1d7532010-09-02 21:23:12 +0000392 # Modify runStarted only if "run" or "process launch" was encountered.
393 if running:
394 self.runStarted = running and setCookie
Johnny Chen63dfb272010-09-01 00:15:19 +0000395
Johnny Chen27f212d2010-08-19 23:26:59 +0000396 if check:
397 self.assertTrue(self.res.Succeeded(),
398 msg if msg else CMD_MSG(cmd))
399
Johnny Chend0190a62010-08-23 17:10:44 +0000400 def expect(self, cmd, msg=None, startstr=None, substrs=None, trace=False):
Johnny Chen27f212d2010-08-19 23:26:59 +0000401 """
402 Similar to runCmd; with additional expect style output matching ability.
403
404 Ask the command interpreter to handle the command and then check its
405 return status. The 'msg' parameter specifies an informational assert
406 message. We expect the output from running the command to start with
407 'startstr' and matches the substrings contained in 'substrs'.
408 """
Johnny Chen8d55a342010-08-31 17:42:54 +0000409 trace = (True if traceAlways else trace)
Johnny Chend0190a62010-08-23 17:10:44 +0000410
Johnny Chen74f26b82010-08-20 19:17:39 +0000411 # First run the command.
Johnny Chend0190a62010-08-23 17:10:44 +0000412 self.runCmd(cmd, trace = (True if trace else False))
Johnny Chen27f212d2010-08-19 23:26:59 +0000413
Johnny Chen74f26b82010-08-20 19:17:39 +0000414 # Then compare the output against expected strings.
Johnny Chen27f212d2010-08-19 23:26:59 +0000415 output = self.res.GetOutput()
416 matched = output.startswith(startstr) if startstr else True
Johnny Chenb145bba2010-08-20 18:25:15 +0000417
Johnny Chenc7c9fcf2010-08-24 23:48:10 +0000418 if startstr and trace:
419 print >> sys.stderr, "Expecting start string:", startstr
420 print >> sys.stderr, "Matched" if matched else "Not matched"
421 print >> sys.stderr
Johnny Chenb145bba2010-08-20 18:25:15 +0000422
Johnny Chen981463d2010-08-25 19:00:04 +0000423 if substrs and matched:
Johnny Chen27f212d2010-08-19 23:26:59 +0000424 for str in substrs:
425 matched = output.find(str) > 0
Johnny Chenc7c9fcf2010-08-24 23:48:10 +0000426 if trace:
427 print >> sys.stderr, "Expecting sub string:", str
428 print >> sys.stderr, "Matched" if matched else "Not matched"
Johnny Chen27f212d2010-08-19 23:26:59 +0000429 if not matched:
430 break
Johnny Chenc7c9fcf2010-08-24 23:48:10 +0000431 if trace:
432 print >> sys.stderr
Johnny Chen27f212d2010-08-19 23:26:59 +0000433
Johnny Chen74f26b82010-08-20 19:17:39 +0000434 self.assertTrue(matched, msg if msg else CMD_MSG(cmd))
Johnny Chen27f212d2010-08-19 23:26:59 +0000435
Johnny Chenf3c59232010-08-25 22:52:45 +0000436 def invoke(self, obj, name, trace=False):
Johnny Chen61703c92010-08-25 22:56:10 +0000437 """Use reflection to call a method dynamically with no argument."""
Johnny Chen8d55a342010-08-31 17:42:54 +0000438 trace = (True if traceAlways else trace)
Johnny Chenf3c59232010-08-25 22:52:45 +0000439
440 method = getattr(obj, name)
441 import inspect
442 self.assertTrue(inspect.ismethod(method),
443 name + "is a method name of object: " + str(obj))
444 result = method()
Johnny Chen8d55a342010-08-31 17:42:54 +0000445 if trace:
Johnny Chenf3c59232010-08-25 22:52:45 +0000446 print str(method) + ":", result
447 return result
Johnny Chen827edff2010-08-27 00:15:48 +0000448
Johnny Chen13639082010-09-01 22:08:51 +0000449 def breakAfterLaunch(self, process, func, trace=False):
450 """
451 Perform some dancees after LaunchProcess() to break at func name.
452
453 Return True if we can successfully break at the func name in due time.
454 """
455 trace = (True if traceAlways else trace)
456
457 count = 0
458 while True:
459 # The stop reason of the thread should be breakpoint.
460 thread = process.GetThreadAtIndex(0)
461 SR = thread.GetStopReason()
462 if trace:
463 print >> sys.stderr, "StopReason =", StopReasonString(SR)
464
465 if SR == StopReasonEnum("Breakpoint"):
466 frame = thread.GetFrameAtIndex(0)
467 name = frame.GetFunction().GetName()
Johnny Chenea772bb2010-09-07 18:55:50 +0000468 if trace:
469 print >> sys.stderr, "function =", name
Johnny Chen13639082010-09-01 22:08:51 +0000470 if (name == func):
471 # We got what we want; now break out of the loop.
472 return True
473
474 # The inferior is in a transient state; continue the process.
475 time.sleep(1.0)
476 if trace:
477 print >> sys.stderr, "Continuing the process:", process
478 process.Continue()
479
480 count = count + 1
Johnny Chenae745562010-09-15 00:00:54 +0000481 if count == 15:
Johnny Chen13639082010-09-01 22:08:51 +0000482 if trace:
Johnny Chenae745562010-09-15 00:00:54 +0000483 print >> sys.stderr, "Reached 15 iterations, giving up..."
Johnny Chen13639082010-09-01 22:08:51 +0000484 # Enough iterations already, break out of the loop.
485 return False
486
487 # End of while loop.
488
489
Johnny Chen1394a4b2010-09-13 20:54:30 +0000490 def buildDefault(self, compiler=None):
Johnny Chen1b1b9ac2010-09-03 23:49:16 +0000491 """Platform specific way to build the default binaries."""
492 module = __import__(sys.platform)
Johnny Chen1394a4b2010-09-13 20:54:30 +0000493 if not module.buildDefault(compiler):
Johnny Chen1b1b9ac2010-09-03 23:49:16 +0000494 raise Exception("Don't know how to build default binary")
495
Johnny Chen1394a4b2010-09-13 20:54:30 +0000496 def buildDsym(self, compiler=None):
Johnny Chen2f1ad5e2010-08-30 22:26:48 +0000497 """Platform specific way to build binaries with dsym info."""
Johnny Chen8d55a342010-08-31 17:42:54 +0000498 module = __import__(sys.platform)
Johnny Chen1394a4b2010-09-13 20:54:30 +0000499 if not module.buildDsym(compiler):
Johnny Chen2f1ad5e2010-08-30 22:26:48 +0000500 raise Exception("Don't know how to build binary with dsym")
501
Johnny Chen1394a4b2010-09-13 20:54:30 +0000502 def buildDwarf(self, compiler=None):
Johnny Chen2f1ad5e2010-08-30 22:26:48 +0000503 """Platform specific way to build binaries with dwarf maps."""
Johnny Chen8d55a342010-08-31 17:42:54 +0000504 module = __import__(sys.platform)
Johnny Chen1394a4b2010-09-13 20:54:30 +0000505 if not module.buildDwarf(compiler):
Johnny Chen2f1ad5e2010-08-30 22:26:48 +0000506 raise Exception("Don't know how to build binary with dwarf")
507
Johnny Chen827edff2010-08-27 00:15:48 +0000508 def DebugSBValue(self, frame, val):
Johnny Chen8d55a342010-08-31 17:42:54 +0000509 """Debug print a SBValue object, if traceAlways is True."""
510 if not traceAlways:
Johnny Chen827edff2010-08-27 00:15:48 +0000511 return
512
513 err = sys.stderr
514 err.write(val.GetName() + ":\n")
515 err.write('\t' + "TypeName -> " + val.GetTypeName() + '\n')
516 err.write('\t' + "ByteSize -> " + str(val.GetByteSize()) + '\n')
517 err.write('\t' + "NumChildren -> " + str(val.GetNumChildren()) + '\n')
518 err.write('\t' + "Value -> " + str(val.GetValue(frame)) + '\n')
519 err.write('\t' + "Summary -> " + str(val.GetSummary(frame)) + '\n')
520 err.write('\t' + "IsPtrType -> " + str(val.TypeIsPtrType()) + '\n')
521 err.write('\t' + "Location -> " + val.GetLocation(frame) + '\n')
522