blob: 1789b57dd75f199e2b2d2f826bc8d02a36a303f1 [file] [log] [blame]
Johnny Chena1affab2010-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 Chen9de4ede2010-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 Chena1affab2010-07-03 03:41:59 +000017$ echo $LLDB_TEST
18/Volumes/data/lldb/svn/trunk/test
19$ echo $PYTHONPATH
Johnny Chen9de4ede2010-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 Chena1affab2010-07-03 03:41:59 +000021$ python function_types/TestFunctionTypes.py
22.
23----------------------------------------------------------------------
24Ran 1 test in 0.363s
25
26OK
Johnny Chend0c24b22010-08-23 17:10:44 +000027$ LLDB_COMMAND_TRACE=YES python array_types/TestArrayTypes.py
Johnny Chen59ea45f2010-09-02 22:25:47 +000028
29...
Johnny Chend0c24b22010-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 Chen59ea45f2010-09-02 22:25:47 +000037...
Johnny Chend0c24b22010-08-23 17:10:44 +000038
Johnny Chen59ea45f2010-09-02 22:25:47 +000039runCmd: frame variable strings
Johnny Chend0c24b22010-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 Chen59ea45f2010-09-02 22:25:47 +000047runCmd: frame variable char_16
Johnny Chend0c24b22010-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 Chen59ea45f2010-09-02 22:25:47 +000067runCmd: frame variable ushort_matrix
Johnny Chend0c24b22010-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 Chen59ea45f2010-09-02 22:25:47 +000081runCmd: frame variable long_6
Johnny Chend0c24b22010-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 Chena1affab2010-07-03 03:41:59 +000096$
97"""
98
Johnny Chena1cc8832010-08-30 21:35:00 +000099import os, sys
100from subprocess import *
Johnny Chen65572482010-08-25 18:49:48 +0000101import time
Johnny Chen1acaf632010-08-30 23:08:52 +0000102import types
Johnny Chen75e28f92010-08-05 23:42:46 +0000103import unittest2
Johnny Chena1affab2010-07-03 03:41:59 +0000104import lldb
105
Johnny Chen9de4ede2010-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 Chen96f08d52010-08-09 22:01:17 +0000112#
113# Some commonly used assert messages.
114#
115
116CURRENT_EXECUTABLE_SET = "Current executable set successfully"
117
Johnny Chen72a14342010-09-02 21:23:12 +0000118PROCESS_IS_VALID = "Process is valid"
119
120PROCESS_KILLED = "Process is killed successfully"
121
Johnny Chen1bb9f9a2010-08-27 23:47:36 +0000122RUN_SUCCEEDED = "Process is launched successfully"
Johnny Chen96f08d52010-08-09 22:01:17 +0000123
Johnny Chend85dae52010-08-09 23:44:24 +0000124RUN_COMPLETED = "Process exited successfully"
Johnny Chen96f08d52010-08-09 22:01:17 +0000125
Johnny Chend85dae52010-08-09 23:44:24 +0000126BREAKPOINT_CREATED = "Breakpoint created successfully"
127
Johnny Chen9b92c6e2010-08-17 21:33:31 +0000128BREAKPOINT_PENDING_CREATED = "Pending breakpoint created successfully"
129
Johnny Chend85dae52010-08-09 23:44:24 +0000130BREAKPOINT_HIT_ONCE = "Breakpoint resolved with hit cout = 1"
Johnny Chen96f08d52010-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 Chen4917e102010-08-24 22:07:56 +0000136DATA_TYPES_DISPLAYED_CORRECTLY = "Data type(s) displayed correctly"
137
Johnny Chenb4d1fff2010-08-26 20:04:17 +0000138VALID_BREAKPOINT = "Got a valid breakpoint"
139
Johnny Chen1bb9f9a2010-08-27 23:47:36 +0000140VALID_FILESPEC = "Got a valid filespec"
141
Johnny Chenb4d1fff2010-08-26 20:04:17 +0000142VALID_PROCESS = "Got a valid process"
143
144VALID_TARGET = "Got a valid target"
145
Johnny Chen22b95b22010-08-25 19:00:04 +0000146VARIABLES_DISPLAYED_CORRECTLY = "Variable(s) displayed correctly"
Johnny Chen96f08d52010-08-09 22:01:17 +0000147
Johnny Chenb4d1fff2010-08-26 20:04:17 +0000148
Johnny Chend85dae52010-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 Chenb4d1fff2010-08-26 20:04:17 +0000155#
Johnny Chen6264bc62010-08-27 18:08:58 +0000156# Returns the enum from the input string.
Johnny Chenb4d1fff2010-08-26 20:04:17 +0000157#
Johnny Chen6264bc62010-08-27 18:08:58 +0000158def StopReasonEnum(string):
159 if string == "Invalid":
Johnny Chenb4d1fff2010-08-26 20:04:17 +0000160 return 0
Johnny Chen6264bc62010-08-27 18:08:58 +0000161 elif string == "None":
Johnny Chenb4d1fff2010-08-26 20:04:17 +0000162 return 1
Johnny Chen6264bc62010-08-27 18:08:58 +0000163 elif string == "Trace":
Johnny Chenb4d1fff2010-08-26 20:04:17 +0000164 return 2
Johnny Chen6264bc62010-08-27 18:08:58 +0000165 elif string == "Breakpoint":
Johnny Chenb4d1fff2010-08-26 20:04:17 +0000166 return 3
Johnny Chen6264bc62010-08-27 18:08:58 +0000167 elif string == "Watchpoint":
Johnny Chenb4d1fff2010-08-26 20:04:17 +0000168 return 4
Johnny Chen6264bc62010-08-27 18:08:58 +0000169 elif string == "Signal":
Johnny Chenb4d1fff2010-08-26 20:04:17 +0000170 return 5
Johnny Chen6264bc62010-08-27 18:08:58 +0000171 elif string == "Exception":
Johnny Chenb4d1fff2010-08-26 20:04:17 +0000172 return 6
Johnny Chen6264bc62010-08-27 18:08:58 +0000173 elif string == "PlanComplete":
Johnny Chenb4d1fff2010-08-26 20:04:17 +0000174 return 7
175 else:
176 raise Exception("Unknown stopReason string")
Johnny Chend85dae52010-08-09 23:44:24 +0000177
Johnny Chenf4ce2882010-08-26 21:49:29 +0000178#
Johnny Chen6264bc62010-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 Chenf4ce2882010-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 Chen9de4ede2010-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 Chenfde69bc2010-09-14 22:01:40 +0000231 output, error = process.communicate()
Johnny Chen9de4ede2010-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 Chen493cad42010-09-14 22:39:02 +0000241 print >> sys.stderr, "stdout:", output
242 print >> sys.stderr, "stderr:", error
243 print >> sys.stderr, "retcode:", retcode
Johnny Chenfde69bc2010-09-14 22:01:40 +0000244 print >> sys.stderr
Johnny Chen9de4ede2010-08-31 17:42:54 +0000245
246 if retcode:
247 cmd = kwargs.get("args")
248 if cmd is None:
249 cmd = popenargs[0]
250 raise CalledProcessError(retcode, cmd, output=output)
251 return output
252
Johnny Chen9c10c182010-08-27 00:15:48 +0000253
Johnny Chen75e28f92010-08-05 23:42:46 +0000254class TestBase(unittest2.TestCase):
Johnny Chena1affab2010-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 Chenf8c723b2010-07-03 20:41:42 +0000258 mydir = None
Johnny Chena1affab2010-07-03 03:41:59 +0000259
Johnny Chenffde4fc2010-08-16 21:28:10 +0000260 # State pertaining to the inferior process, if any.
Johnny Chen59ea45f2010-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 Chenffde4fc2010-08-16 21:28:10 +0000264 runStarted = False
265
Johnny Chen65572482010-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 Chend3521cc2010-09-16 01:53:04 +0000274 # Keep track of the old current working directory.
275 oldcwd = None
Johnny Chen88f83042010-08-05 21:23:45 +0000276
Johnny Chend3521cc2010-09-16 01:53:04 +0000277 @classmethod
278 def setUpClass(cls):
Johnny Chenf8c723b2010-07-03 20:41:42 +0000279 # Fail fast if 'mydir' attribute is not overridden.
Johnny Chend3521cc2010-09-16 01:53:04 +0000280 if not cls.mydir or len(cls.mydir) == 0:
Johnny Chenf8c723b2010-07-03 20:41:42 +0000281 raise Exception("Subclasses must override the 'mydir' attribute.")
Johnny Chena1affab2010-07-03 03:41:59 +0000282 # Save old working directory.
Johnny Chend3521cc2010-09-16 01:53:04 +0000283 cls.oldcwd = os.getcwd()
Johnny Chena1affab2010-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 Chend3521cc2010-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 Chena1affab2010-07-03 03:41:59 +0000315
Johnny Chen65572482010-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 Chena1affab2010-07-03 03:41:59 +0000322 # Create the debugger instance if necessary.
323 try:
324 self.dbg = lldb.DBG
Johnny Chena1affab2010-07-03 03:41:59 +0000325 except AttributeError:
326 self.dbg = lldb.SBDebugger.Create()
Johnny Chenf8c723b2010-07-03 20:41:42 +0000327
Johnny Chena1affab2010-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 Chen72a14342010-09-02 21:23:12 +0000334 # There is no process associated with the debugger as yet.
Johnny Chen59ea45f2010-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 Chen72a14342010-09-02 21:23:12 +0000337 self.process = None
338
Johnny Chena1affab2010-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 Chena1affab2010-07-03 03:41:59 +0000347 def tearDown(self):
Johnny Chen72a14342010-09-02 21:23:12 +0000348 #import traceback
349 #traceback.print_stack()
350
351 # Terminate the current process being debugged, if any.
Johnny Chenffde4fc2010-08-16 21:28:10 +0000352 if self.runStarted:
Johnny Chen72a14342010-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 Chenffde4fc2010-08-16 21:28:10 +0000357
Johnny Chena1affab2010-07-03 03:41:59 +0000358 del self.dbg
359
Johnny Chen21f33412010-09-01 00:15:19 +0000360 def runCmd(self, cmd, msg=None, check=True, trace=False, setCookie=True):
Johnny Chen8df95eb2010-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 Chen4f995f02010-08-20 17:57:32 +0000368
Johnny Chen9de4ede2010-08-31 17:42:54 +0000369 trace = (True if traceAlways else trace)
Johnny Chend0c24b22010-08-23 17:10:44 +0000370
Johnny Chen21f33412010-09-01 00:15:19 +0000371 running = (cmd.startswith("run") or cmd.startswith("process launch"))
Johnny Chen4f995f02010-08-20 17:57:32 +0000372
Johnny Chen21f33412010-09-01 00:15:19 +0000373 for i in range(self.maxLaunchCount if running else 1):
Johnny Chen65572482010-08-25 18:49:48 +0000374 self.ci.HandleCommand(cmd, self.res)
Johnny Chen4f995f02010-08-20 17:57:32 +0000375
Johnny Chen65572482010-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 Chen4f995f02010-08-20 17:57:32 +0000382
Johnny Chenc5b15db2010-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 Chen029acae2010-08-20 21:03:09 +0000387 if self.res.Succeeded():
Johnny Chen65572482010-08-25 18:49:48 +0000388 break
Johnny Chen0c30ad82010-09-15 17:33:57 +0000389 elif running:
Johnny Chen5f3b98c2010-09-15 18:00:19 +0000390 print >> sys.stderr, "Command '" + cmd + "' failed!"
Johnny Chen4f995f02010-08-20 17:57:32 +0000391
Johnny Chen72a14342010-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 Chen21f33412010-09-01 00:15:19 +0000395
Johnny Chen8df95eb2010-08-19 23:26:59 +0000396 if check:
397 self.assertTrue(self.res.Succeeded(),
398 msg if msg else CMD_MSG(cmd))
399
Johnny Chend0c24b22010-08-23 17:10:44 +0000400 def expect(self, cmd, msg=None, startstr=None, substrs=None, trace=False):
Johnny Chen8df95eb2010-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 Chen9de4ede2010-08-31 17:42:54 +0000409 trace = (True if traceAlways else trace)
Johnny Chend0c24b22010-08-23 17:10:44 +0000410
Johnny Chene8b02f32010-08-20 19:17:39 +0000411 # First run the command.
Johnny Chend0c24b22010-08-23 17:10:44 +0000412 self.runCmd(cmd, trace = (True if trace else False))
Johnny Chen8df95eb2010-08-19 23:26:59 +0000413
Johnny Chene8b02f32010-08-20 19:17:39 +0000414 # Then compare the output against expected strings.
Johnny Chen8df95eb2010-08-19 23:26:59 +0000415 output = self.res.GetOutput()
416 matched = output.startswith(startstr) if startstr else True
Johnny Chenead35c82010-08-20 18:25:15 +0000417
Johnny Chen3f3fb132010-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 Chenead35c82010-08-20 18:25:15 +0000422
Johnny Chen22b95b22010-08-25 19:00:04 +0000423 if substrs and matched:
Johnny Chen8df95eb2010-08-19 23:26:59 +0000424 for str in substrs:
425 matched = output.find(str) > 0
Johnny Chen3f3fb132010-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 Chen8df95eb2010-08-19 23:26:59 +0000429 if not matched:
430 break
Johnny Chen3f3fb132010-08-24 23:48:10 +0000431 if trace:
432 print >> sys.stderr
Johnny Chen8df95eb2010-08-19 23:26:59 +0000433
Johnny Chene8b02f32010-08-20 19:17:39 +0000434 self.assertTrue(matched, msg if msg else CMD_MSG(cmd))
Johnny Chen8df95eb2010-08-19 23:26:59 +0000435
Johnny Chena8b3cdd2010-08-25 22:52:45 +0000436 def invoke(self, obj, name, trace=False):
Johnny Chend8473bc2010-08-25 22:56:10 +0000437 """Use reflection to call a method dynamically with no argument."""
Johnny Chen9de4ede2010-08-31 17:42:54 +0000438 trace = (True if traceAlways else trace)
Johnny Chena8b3cdd2010-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 Chen9de4ede2010-08-31 17:42:54 +0000445 if trace:
Johnny Chena8b3cdd2010-08-25 22:52:45 +0000446 print str(method) + ":", result
447 return result
Johnny Chen9c10c182010-08-27 00:15:48 +0000448
Johnny Chenc202b492010-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 Chenc6fe11f2010-09-07 18:55:50 +0000468 if trace:
469 print >> sys.stderr, "function =", name
Johnny Chenc202b492010-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 Chenc1810672010-09-15 00:00:54 +0000481 if count == 15:
Johnny Chenc202b492010-09-01 22:08:51 +0000482 if trace:
Johnny Chenc1810672010-09-15 00:00:54 +0000483 print >> sys.stderr, "Reached 15 iterations, giving up..."
Johnny Chenc202b492010-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 Chen48904052010-09-13 20:54:30 +0000490 def buildDefault(self, compiler=None):
Johnny Chenff4e1d82010-09-03 23:49:16 +0000491 """Platform specific way to build the default binaries."""
492 module = __import__(sys.platform)
Johnny Chen48904052010-09-13 20:54:30 +0000493 if not module.buildDefault(compiler):
Johnny Chenff4e1d82010-09-03 23:49:16 +0000494 raise Exception("Don't know how to build default binary")
495
Johnny Chen48904052010-09-13 20:54:30 +0000496 def buildDsym(self, compiler=None):
Johnny Cheneef7a862010-08-30 22:26:48 +0000497 """Platform specific way to build binaries with dsym info."""
Johnny Chen9de4ede2010-08-31 17:42:54 +0000498 module = __import__(sys.platform)
Johnny Chen48904052010-09-13 20:54:30 +0000499 if not module.buildDsym(compiler):
Johnny Cheneef7a862010-08-30 22:26:48 +0000500 raise Exception("Don't know how to build binary with dsym")
501
Johnny Chen48904052010-09-13 20:54:30 +0000502 def buildDwarf(self, compiler=None):
Johnny Cheneef7a862010-08-30 22:26:48 +0000503 """Platform specific way to build binaries with dwarf maps."""
Johnny Chen9de4ede2010-08-31 17:42:54 +0000504 module = __import__(sys.platform)
Johnny Chen48904052010-09-13 20:54:30 +0000505 if not module.buildDwarf(compiler):
Johnny Cheneef7a862010-08-30 22:26:48 +0000506 raise Exception("Don't know how to build binary with dwarf")
507
Johnny Chen9c10c182010-08-27 00:15:48 +0000508 def DebugSBValue(self, frame, val):
Johnny Chen9de4ede2010-08-31 17:42:54 +0000509 """Debug print a SBValue object, if traceAlways is True."""
510 if not traceAlways:
Johnny Chen9c10c182010-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