blob: 65807c703cb870fa19f4be22756ab98d8afc15aa [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
Johnny Chenaa902922010-09-17 22:45:27 +0000116COMMAND_FAILED_AS_EXPECTED = "Command has failed as expected"
117
Johnny Chen00778092010-08-09 22:01:17 +0000118CURRENT_EXECUTABLE_SET = "Current executable set successfully"
119
Johnny Chen7d1d7532010-09-02 21:23:12 +0000120PROCESS_IS_VALID = "Process is valid"
121
122PROCESS_KILLED = "Process is killed successfully"
123
Johnny Chen5ee88192010-08-27 23:47:36 +0000124RUN_SUCCEEDED = "Process is launched successfully"
Johnny Chen00778092010-08-09 22:01:17 +0000125
Johnny Chen17941842010-08-09 23:44:24 +0000126RUN_COMPLETED = "Process exited successfully"
Johnny Chen00778092010-08-09 22:01:17 +0000127
Johnny Chen17941842010-08-09 23:44:24 +0000128BREAKPOINT_CREATED = "Breakpoint created successfully"
129
Johnny Chene76896c2010-08-17 21:33:31 +0000130BREAKPOINT_PENDING_CREATED = "Pending breakpoint created successfully"
131
Johnny Chen17941842010-08-09 23:44:24 +0000132BREAKPOINT_HIT_ONCE = "Breakpoint resolved with hit cout = 1"
Johnny Chen00778092010-08-09 22:01:17 +0000133
134STOPPED_DUE_TO_BREAKPOINT = "Process state is stopped due to breakpoint"
135
136STOPPED_DUE_TO_STEP_IN = "Process state is stopped due to step in"
137
Johnny Chen3c884a02010-08-24 22:07:56 +0000138DATA_TYPES_DISPLAYED_CORRECTLY = "Data type(s) displayed correctly"
139
Johnny Chen5fca8ca2010-08-26 20:04:17 +0000140VALID_BREAKPOINT = "Got a valid breakpoint"
141
Johnny Chen5ee88192010-08-27 23:47:36 +0000142VALID_FILESPEC = "Got a valid filespec"
143
Johnny Chen5fca8ca2010-08-26 20:04:17 +0000144VALID_PROCESS = "Got a valid process"
145
146VALID_TARGET = "Got a valid target"
147
Johnny Chen981463d2010-08-25 19:00:04 +0000148VARIABLES_DISPLAYED_CORRECTLY = "Variable(s) displayed correctly"
Johnny Chen00778092010-08-09 22:01:17 +0000149
Johnny Chen5fca8ca2010-08-26 20:04:17 +0000150
Johnny Chen17941842010-08-09 23:44:24 +0000151#
152# And a generic "Command '%s' returns successfully" message generator.
153#
154def CMD_MSG(command):
155 return "Command '%s' returns successfully" % (command)
156
Johnny Chen5fca8ca2010-08-26 20:04:17 +0000157#
Johnny Chen82d404c82010-08-27 18:08:58 +0000158# Returns the enum from the input string.
Johnny Chen5fca8ca2010-08-26 20:04:17 +0000159#
Johnny Chen82d404c82010-08-27 18:08:58 +0000160def StopReasonEnum(string):
161 if string == "Invalid":
Johnny Chen5fca8ca2010-08-26 20:04:17 +0000162 return 0
Johnny Chen82d404c82010-08-27 18:08:58 +0000163 elif string == "None":
Johnny Chen5fca8ca2010-08-26 20:04:17 +0000164 return 1
Johnny Chen82d404c82010-08-27 18:08:58 +0000165 elif string == "Trace":
Johnny Chen5fca8ca2010-08-26 20:04:17 +0000166 return 2
Johnny Chen82d404c82010-08-27 18:08:58 +0000167 elif string == "Breakpoint":
Johnny Chen5fca8ca2010-08-26 20:04:17 +0000168 return 3
Johnny Chen82d404c82010-08-27 18:08:58 +0000169 elif string == "Watchpoint":
Johnny Chen5fca8ca2010-08-26 20:04:17 +0000170 return 4
Johnny Chen82d404c82010-08-27 18:08:58 +0000171 elif string == "Signal":
Johnny Chen5fca8ca2010-08-26 20:04:17 +0000172 return 5
Johnny Chen82d404c82010-08-27 18:08:58 +0000173 elif string == "Exception":
Johnny Chen5fca8ca2010-08-26 20:04:17 +0000174 return 6
Johnny Chen82d404c82010-08-27 18:08:58 +0000175 elif string == "PlanComplete":
Johnny Chen5fca8ca2010-08-26 20:04:17 +0000176 return 7
177 else:
178 raise Exception("Unknown stopReason string")
Johnny Chen17941842010-08-09 23:44:24 +0000179
Johnny Chen27c41232010-08-26 21:49:29 +0000180#
Johnny Chen82d404c82010-08-27 18:08:58 +0000181# Returns the stopReason string given an enum.
182#
183def StopReasonString(enum):
184 if enum == 0:
185 return "Invalid"
186 elif enum == 1:
187 return "None"
188 elif enum == 2:
189 return "Trace"
190 elif enum == 3:
191 return "Breakpoint"
192 elif enum == 4:
193 return "Watchpoint"
194 elif enum == 5:
195 return "Signal"
196 elif enum == 6:
197 return "Exception"
198 elif enum == 7:
199 return "PlanComplete"
200 else:
201 raise Exception("Unknown stopReason enum")
202
203#
Johnny Chen27c41232010-08-26 21:49:29 +0000204# Returns an env variable array from the os.environ map object.
205#
206def EnvArray():
207 return map(lambda k,v: k+"="+v, os.environ.keys(), os.environ.values())
208
Johnny Chen8d55a342010-08-31 17:42:54 +0000209# From 2.7's subprocess.check_output() convenience function.
210def system(*popenargs, **kwargs):
211 r"""Run command with arguments and return its output as a byte string.
212
213 If the exit code was non-zero it raises a CalledProcessError. The
214 CalledProcessError object will have the return code in the returncode
215 attribute and output in the output attribute.
216
217 The arguments are the same as for the Popen constructor. Example:
218
219 >>> check_output(["ls", "-l", "/dev/null"])
220 'crw-rw-rw- 1 root root 1, 3 Oct 18 2007 /dev/null\n'
221
222 The stdout argument is not allowed as it is used internally.
223 To capture standard error in the result, use stderr=STDOUT.
224
225 >>> check_output(["/bin/sh", "-c",
226 ... "ls -l non_existent_file ; exit 0"],
227 ... stderr=STDOUT)
228 'ls: non_existent_file: No such file or directory\n'
229 """
230 if 'stdout' in kwargs:
231 raise ValueError('stdout argument not allowed, it will be overridden.')
232 process = Popen(stdout=PIPE, *popenargs, **kwargs)
Johnny Chen1aad5c62010-09-14 22:01:40 +0000233 output, error = process.communicate()
Johnny Chen8d55a342010-08-31 17:42:54 +0000234 retcode = process.poll()
235
236 if traceAlways:
237 if isinstance(popenargs, types.StringTypes):
238 args = [popenargs]
239 else:
240 args = list(popenargs)
241 print >> sys.stderr
242 print >> sys.stderr, "os command:", args
Johnny Chene0490512010-09-14 22:39:02 +0000243 print >> sys.stderr, "stdout:", output
244 print >> sys.stderr, "stderr:", error
245 print >> sys.stderr, "retcode:", retcode
Johnny Chen1aad5c62010-09-14 22:01:40 +0000246 print >> sys.stderr
Johnny Chen8d55a342010-08-31 17:42:54 +0000247
248 if retcode:
249 cmd = kwargs.get("args")
250 if cmd is None:
251 cmd = popenargs[0]
Johnny Chen2fcc0e52010-09-16 18:26:06 +0000252 raise CalledProcessError(retcode, cmd)
Johnny Chen8d55a342010-08-31 17:42:54 +0000253 return output
254
Johnny Chen827edff2010-08-27 00:15:48 +0000255
Johnny Chen73258832010-08-05 23:42:46 +0000256class TestBase(unittest2.TestCase):
Johnny Chenbf6ffa32010-07-03 03:41:59 +0000257 """This LLDB abstract base class is meant to be subclassed."""
258
259 # The concrete subclass should override this attribute.
Johnny Chenf02ec122010-07-03 20:41:42 +0000260 mydir = None
Johnny Chenbf6ffa32010-07-03 03:41:59 +0000261
Johnny Chen6ca006c2010-08-16 21:28:10 +0000262 # State pertaining to the inferior process, if any.
Johnny Chen57b47382010-09-02 22:25:47 +0000263 # This reflects inferior process started through the command interface with
264 # either the lldb "run" or "process launch" command.
265 # See also self.runCmd().
Johnny Chen6ca006c2010-08-16 21:28:10 +0000266 runStarted = False
267
Johnny Chenf2b70232010-08-25 18:49:48 +0000268 # Maximum allowed attempts when launching the inferior process.
269 # Can be overridden by the LLDB_MAX_LAUNCH_COUNT environment variable.
270 maxLaunchCount = 3;
271
272 # Time to wait before the next launching attempt in second(s).
273 # Can be overridden by the LLDB_TIME_WAIT environment variable.
274 timeWait = 1.0;
275
Johnny Chen1a9f4dd2010-09-16 01:53:04 +0000276 # Keep track of the old current working directory.
277 oldcwd = None
Johnny Chena2124952010-08-05 21:23:45 +0000278
Johnny Chen1a9f4dd2010-09-16 01:53:04 +0000279 @classmethod
280 def setUpClass(cls):
Johnny Chenf02ec122010-07-03 20:41:42 +0000281 # Fail fast if 'mydir' attribute is not overridden.
Johnny Chen1a9f4dd2010-09-16 01:53:04 +0000282 if not cls.mydir or len(cls.mydir) == 0:
Johnny Chenf02ec122010-07-03 20:41:42 +0000283 raise Exception("Subclasses must override the 'mydir' attribute.")
Johnny Chenbf6ffa32010-07-03 03:41:59 +0000284 # Save old working directory.
Johnny Chen1a9f4dd2010-09-16 01:53:04 +0000285 cls.oldcwd = os.getcwd()
Johnny Chenbf6ffa32010-07-03 03:41:59 +0000286
287 # Change current working directory if ${LLDB_TEST} is defined.
288 # See also dotest.py which sets up ${LLDB_TEST}.
289 if ("LLDB_TEST" in os.environ):
Johnny Chen1a9f4dd2010-09-16 01:53:04 +0000290 if traceAlways:
291 print "Change dir to:", os.path.join(os.environ["LLDB_TEST"], cls.mydir)
292 os.chdir(os.path.join(os.environ["LLDB_TEST"], cls.mydir))
293
294 @classmethod
295 def tearDownClass(cls):
296 """Do class-wide cleanup."""
297
298 # First, let's do the platform-specific cleanup.
299 module = __import__(sys.platform)
300 if not module.cleanup():
301 raise Exception("Don't know how to do cleanup")
302
303 # Subclass might have specific cleanup function defined.
304 if getattr(cls, "classCleanup", None):
305 if traceAlways:
306 print "Call class-specific cleanup function for class:", cls
307 cls.classCleanup()
308
309 # Restore old working directory.
310 if traceAlways:
311 print "Restore dir to:", cls.oldcwd
312 os.chdir(cls.oldcwd)
313
314 def setUp(self):
315 #import traceback
316 #traceback.print_stack()
Johnny Chenbf6ffa32010-07-03 03:41:59 +0000317
Johnny Chenf2b70232010-08-25 18:49:48 +0000318 if "LLDB_MAX_LAUNCH_COUNT" in os.environ:
319 self.maxLaunchCount = int(os.environ["LLDB_MAX_LAUNCH_COUNT"])
320
321 if "LLDB_TIME_WAIT" in os.environ:
322 self.timeWait = float(os.environ["LLDB_TIME_WAIT"])
323
Johnny Chenbf6ffa32010-07-03 03:41:59 +0000324 # Create the debugger instance if necessary.
325 try:
326 self.dbg = lldb.DBG
Johnny Chenbf6ffa32010-07-03 03:41:59 +0000327 except AttributeError:
328 self.dbg = lldb.SBDebugger.Create()
Johnny Chenf02ec122010-07-03 20:41:42 +0000329
Johnny Chenbf6ffa32010-07-03 03:41:59 +0000330 if not self.dbg.IsValid():
331 raise Exception('Invalid debugger instance')
332
333 # We want our debugger to be synchronous.
334 self.dbg.SetAsync(False)
335
Johnny Chen7d1d7532010-09-02 21:23:12 +0000336 # There is no process associated with the debugger as yet.
Johnny Chen57b47382010-09-02 22:25:47 +0000337 # See also self.tearDown() where it checks whether self.process has a
338 # valid reference and calls self.process.Kill() to kill the process.
Johnny Chen7d1d7532010-09-02 21:23:12 +0000339 self.process = None
340
Johnny Chenbf6ffa32010-07-03 03:41:59 +0000341 # Retrieve the associated command interpreter instance.
342 self.ci = self.dbg.GetCommandInterpreter()
343 if not self.ci:
344 raise Exception('Could not get the command interpreter')
345
346 # And the result object.
347 self.res = lldb.SBCommandReturnObject()
348
Johnny Chenbf6ffa32010-07-03 03:41:59 +0000349 def tearDown(self):
Johnny Chen7d1d7532010-09-02 21:23:12 +0000350 #import traceback
351 #traceback.print_stack()
352
353 # Terminate the current process being debugged, if any.
Johnny Chen6ca006c2010-08-16 21:28:10 +0000354 if self.runStarted:
Johnny Chen7d1d7532010-09-02 21:23:12 +0000355 self.runCmd("process kill", PROCESS_KILLED, check=False)
356 elif self.process and self.process.IsValid():
357 rc = self.process.Kill()
358 self.assertTrue(rc.Success(), PROCESS_KILLED)
Johnny Chen6ca006c2010-08-16 21:28:10 +0000359
Johnny Chenbf6ffa32010-07-03 03:41:59 +0000360 del self.dbg
361
Johnny Chen63dfb272010-09-01 00:15:19 +0000362 def runCmd(self, cmd, msg=None, check=True, trace=False, setCookie=True):
Johnny Chen27f212d2010-08-19 23:26:59 +0000363 """
364 Ask the command interpreter to handle the command and then check its
365 return status.
366 """
367 # Fail fast if 'cmd' is not meaningful.
368 if not cmd or len(cmd) == 0:
369 raise Exception("Bad 'cmd' parameter encountered")
Johnny Chen5bbb88f2010-08-20 17:57:32 +0000370
Johnny Chen8d55a342010-08-31 17:42:54 +0000371 trace = (True if traceAlways else trace)
Johnny Chend0190a62010-08-23 17:10:44 +0000372
Johnny Chen63dfb272010-09-01 00:15:19 +0000373 running = (cmd.startswith("run") or cmd.startswith("process launch"))
Johnny Chen5bbb88f2010-08-20 17:57:32 +0000374
Johnny Chen63dfb272010-09-01 00:15:19 +0000375 for i in range(self.maxLaunchCount if running else 1):
Johnny Chenf2b70232010-08-25 18:49:48 +0000376 self.ci.HandleCommand(cmd, self.res)
Johnny Chen5bbb88f2010-08-20 17:57:32 +0000377
Johnny Chenf2b70232010-08-25 18:49:48 +0000378 if trace:
379 print >> sys.stderr, "runCmd:", cmd
380 if self.res.Succeeded():
381 print >> sys.stderr, "output:", self.res.GetOutput()
382 else:
383 print >> sys.stderr, self.res.GetError()
Johnny Chen5bbb88f2010-08-20 17:57:32 +0000384
Johnny Chen725945d2010-09-03 22:35:47 +0000385 if running:
386 # For process launch, wait some time before possible next try.
387 time.sleep(self.timeWait)
388
Johnny Chenff3d01d2010-08-20 21:03:09 +0000389 if self.res.Succeeded():
Johnny Chenf2b70232010-08-25 18:49:48 +0000390 break
Johnny Chenf7f0cab2010-09-15 17:33:57 +0000391 elif running:
Johnny Chen9fa03212010-09-15 18:00:19 +0000392 print >> sys.stderr, "Command '" + cmd + "' failed!"
Johnny Chen5bbb88f2010-08-20 17:57:32 +0000393
Johnny Chen7d1d7532010-09-02 21:23:12 +0000394 # Modify runStarted only if "run" or "process launch" was encountered.
395 if running:
396 self.runStarted = running and setCookie
Johnny Chen63dfb272010-09-01 00:15:19 +0000397
Johnny Chen27f212d2010-08-19 23:26:59 +0000398 if check:
399 self.assertTrue(self.res.Succeeded(),
400 msg if msg else CMD_MSG(cmd))
401
Johnny Chenb3307862010-09-17 22:28:51 +0000402 def expect(self, cmd, msg=None, startstr=None, substrs=None, trace=False, error=False):
Johnny Chen27f212d2010-08-19 23:26:59 +0000403 """
404 Similar to runCmd; with additional expect style output matching ability.
405
406 Ask the command interpreter to handle the command and then check its
407 return status. The 'msg' parameter specifies an informational assert
408 message. We expect the output from running the command to start with
409 'startstr' and matches the substrings contained in 'substrs'.
Johnny Chenb3307862010-09-17 22:28:51 +0000410
411 If the keyword argument error is set to True, it signifies that the API
412 client is expecting the command to fail. In this case, the error stream
Johnny Chenaa902922010-09-17 22:45:27 +0000413 from running the command is retrieved and compared against the golden
Johnny Chenb3307862010-09-17 22:28:51 +0000414 input, instead.
Johnny Chen27f212d2010-08-19 23:26:59 +0000415 """
Johnny Chen8d55a342010-08-31 17:42:54 +0000416 trace = (True if traceAlways else trace)
Johnny Chend0190a62010-08-23 17:10:44 +0000417
Johnny Chenb3307862010-09-17 22:28:51 +0000418 # First run the command. If we are expecting error, set check=False.
419 self.runCmd(cmd, trace = (True if trace else False), check = not error)
Johnny Chen27f212d2010-08-19 23:26:59 +0000420
Johnny Chen74f26b82010-08-20 19:17:39 +0000421 # Then compare the output against expected strings.
Johnny Chenb3307862010-09-17 22:28:51 +0000422 output = self.res.GetError() if error else self.res.GetOutput()
423
424 # If error is True, the API client expects the command to fail!
425 if error:
426 self.assertFalse(self.res.Succeeded(),
427 "Command '" + cmd + "' is expected to fail!")
428
Johnny Chen27f212d2010-08-19 23:26:59 +0000429 matched = output.startswith(startstr) if startstr else True
Johnny Chenb145bba2010-08-20 18:25:15 +0000430
Johnny Chenc7c9fcf2010-08-24 23:48:10 +0000431 if startstr and trace:
432 print >> sys.stderr, "Expecting start string:", startstr
433 print >> sys.stderr, "Matched" if matched else "Not matched"
434 print >> sys.stderr
Johnny Chenb145bba2010-08-20 18:25:15 +0000435
Johnny Chen981463d2010-08-25 19:00:04 +0000436 if substrs and matched:
Johnny Chen27f212d2010-08-19 23:26:59 +0000437 for str in substrs:
438 matched = output.find(str) > 0
Johnny Chenc7c9fcf2010-08-24 23:48:10 +0000439 if trace:
440 print >> sys.stderr, "Expecting sub string:", str
441 print >> sys.stderr, "Matched" if matched else "Not matched"
Johnny Chen27f212d2010-08-19 23:26:59 +0000442 if not matched:
443 break
Johnny Chenc7c9fcf2010-08-24 23:48:10 +0000444 if trace:
445 print >> sys.stderr
Johnny Chen27f212d2010-08-19 23:26:59 +0000446
Johnny Chen74f26b82010-08-20 19:17:39 +0000447 self.assertTrue(matched, msg if msg else CMD_MSG(cmd))
Johnny Chen27f212d2010-08-19 23:26:59 +0000448
Johnny Chenf3c59232010-08-25 22:52:45 +0000449 def invoke(self, obj, name, trace=False):
Johnny Chen61703c92010-08-25 22:56:10 +0000450 """Use reflection to call a method dynamically with no argument."""
Johnny Chen8d55a342010-08-31 17:42:54 +0000451 trace = (True if traceAlways else trace)
Johnny Chenf3c59232010-08-25 22:52:45 +0000452
453 method = getattr(obj, name)
454 import inspect
455 self.assertTrue(inspect.ismethod(method),
456 name + "is a method name of object: " + str(obj))
457 result = method()
Johnny Chen8d55a342010-08-31 17:42:54 +0000458 if trace:
Johnny Chenf3c59232010-08-25 22:52:45 +0000459 print str(method) + ":", result
460 return result
Johnny Chen827edff2010-08-27 00:15:48 +0000461
Johnny Chen13639082010-09-01 22:08:51 +0000462 def breakAfterLaunch(self, process, func, trace=False):
463 """
464 Perform some dancees after LaunchProcess() to break at func name.
465
466 Return True if we can successfully break at the func name in due time.
467 """
468 trace = (True if traceAlways else trace)
469
470 count = 0
471 while True:
472 # The stop reason of the thread should be breakpoint.
473 thread = process.GetThreadAtIndex(0)
474 SR = thread.GetStopReason()
475 if trace:
476 print >> sys.stderr, "StopReason =", StopReasonString(SR)
477
478 if SR == StopReasonEnum("Breakpoint"):
479 frame = thread.GetFrameAtIndex(0)
480 name = frame.GetFunction().GetName()
Johnny Chenea772bb2010-09-07 18:55:50 +0000481 if trace:
482 print >> sys.stderr, "function =", name
Johnny Chen13639082010-09-01 22:08:51 +0000483 if (name == func):
484 # We got what we want; now break out of the loop.
485 return True
486
487 # The inferior is in a transient state; continue the process.
488 time.sleep(1.0)
489 if trace:
490 print >> sys.stderr, "Continuing the process:", process
491 process.Continue()
492
493 count = count + 1
Johnny Chenae745562010-09-15 00:00:54 +0000494 if count == 15:
Johnny Chen13639082010-09-01 22:08:51 +0000495 if trace:
Johnny Chenae745562010-09-15 00:00:54 +0000496 print >> sys.stderr, "Reached 15 iterations, giving up..."
Johnny Chen13639082010-09-01 22:08:51 +0000497 # Enough iterations already, break out of the loop.
498 return False
499
500 # End of while loop.
501
502
Johnny Chen1394a4b2010-09-13 20:54:30 +0000503 def buildDefault(self, compiler=None):
Johnny Chen1b1b9ac2010-09-03 23:49:16 +0000504 """Platform specific way to build the default binaries."""
505 module = __import__(sys.platform)
Johnny Chen1394a4b2010-09-13 20:54:30 +0000506 if not module.buildDefault(compiler):
Johnny Chen1b1b9ac2010-09-03 23:49:16 +0000507 raise Exception("Don't know how to build default binary")
508
Johnny Chen1394a4b2010-09-13 20:54:30 +0000509 def buildDsym(self, compiler=None):
Johnny Chen2f1ad5e2010-08-30 22:26:48 +0000510 """Platform specific way to build binaries with dsym info."""
Johnny Chen8d55a342010-08-31 17:42:54 +0000511 module = __import__(sys.platform)
Johnny Chen1394a4b2010-09-13 20:54:30 +0000512 if not module.buildDsym(compiler):
Johnny Chen2f1ad5e2010-08-30 22:26:48 +0000513 raise Exception("Don't know how to build binary with dsym")
514
Johnny Chen1394a4b2010-09-13 20:54:30 +0000515 def buildDwarf(self, compiler=None):
Johnny Chen2f1ad5e2010-08-30 22:26:48 +0000516 """Platform specific way to build binaries with dwarf maps."""
Johnny Chen8d55a342010-08-31 17:42:54 +0000517 module = __import__(sys.platform)
Johnny Chen1394a4b2010-09-13 20:54:30 +0000518 if not module.buildDwarf(compiler):
Johnny Chen2f1ad5e2010-08-30 22:26:48 +0000519 raise Exception("Don't know how to build binary with dwarf")
520
Johnny Chen827edff2010-08-27 00:15:48 +0000521 def DebugSBValue(self, frame, val):
Johnny Chen8d55a342010-08-31 17:42:54 +0000522 """Debug print a SBValue object, if traceAlways is True."""
523 if not traceAlways:
Johnny Chen827edff2010-08-27 00:15:48 +0000524 return
525
526 err = sys.stderr
527 err.write(val.GetName() + ":\n")
528 err.write('\t' + "TypeName -> " + val.GetTypeName() + '\n')
529 err.write('\t' + "ByteSize -> " + str(val.GetByteSize()) + '\n')
530 err.write('\t' + "NumChildren -> " + str(val.GetNumChildren()) + '\n')
531 err.write('\t' + "Value -> " + str(val.GetValue(frame)) + '\n')
532 err.write('\t' + "Summary -> " + str(val.GetSummary(frame)) + '\n')
533 err.write('\t' + "IsPtrType -> " + str(val.TypeIsPtrType()) + '\n')
534 err.write('\t' + "Location -> " + val.GetLocation(frame) + '\n')
535