| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #Note: Keep name-type-value-numchild-extra order | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import sys | 
					
						
							|  |  |  | import traceback | 
					
						
							|  |  |  | import gdb | 
					
						
							| 
									
										
										
										
											2009-12-04 13:22:39 +01:00
										 |  |  | import base64 | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  | import curses.ascii | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-08 18:16:16 +01:00
										 |  |  | # only needed for gdb 7.0/7.0.1 that do not implement parse_and_eval | 
					
						
							| 
									
										
										
										
											2009-12-09 09:53:43 +01:00
										 |  |  | import os | 
					
						
							|  |  |  | import tempfile | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  | verbosity = 0 | 
					
						
							|  |  |  | verbosity = 1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-27 13:52:29 +01:00
										 |  |  | def select(condition, if_expr, else_expr): | 
					
						
							|  |  |  |     if condition: | 
					
						
							|  |  |  |         return if_expr | 
					
						
							|  |  |  |     return else_expr | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-27 14:10:42 +01:00
										 |  |  | def qmin(n, m): | 
					
						
							|  |  |  |     if n < m: | 
					
						
							|  |  |  |         return n | 
					
						
							|  |  |  |     return m | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-18 16:25:59 +01:00
										 |  |  | def isGoodGdb(): | 
					
						
							| 
									
										
										
										
											2010-01-05 17:05:13 +01:00
										 |  |  |     #return gdb.VERSION.startswith("6.8.50.2009") \ | 
					
						
							|  |  |  |     #   and gdb.VERSION != "6.8.50.20090630-cvs" | 
					
						
							|  |  |  |     return 'parse_and_eval' in dir(gdb) | 
					
						
							| 
									
										
										
										
											2009-12-18 16:25:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-06 17:01:16 +01:00
										 |  |  | def cleanAddress(addr): | 
					
						
							| 
									
										
										
										
											2010-01-14 15:25:53 +01:00
										 |  |  |     # We cannot use str(addr) as it yields rubbish for char pointers | 
					
						
							|  |  |  |     # that might trigger Unicode encoding errors. | 
					
						
							| 
									
										
										
										
											2010-01-07 13:02:19 +01:00
										 |  |  |     return addr.cast(gdb.lookup_type("void").pointer()) | 
					
						
							| 
									
										
										
										
											2010-01-06 17:01:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-15 13:26:46 +01:00
										 |  |  | # Workaround for gdb < 7.1 | 
					
						
							|  |  |  | def numericTemplateArgument(type, position): | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         return int(type.template_argument(position)) | 
					
						
							|  |  |  |     except RuntimeError as error: | 
					
						
							|  |  |  |         # ": No type named 30." | 
					
						
							|  |  |  |         msg = str(error) | 
					
						
							|  |  |  |         return int(msg[14:-1]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-09 09:53:43 +01:00
										 |  |  | def parseAndEvaluate(exp): | 
					
						
							| 
									
										
										
										
											2009-12-18 16:25:59 +01:00
										 |  |  |     if isGoodGdb(): | 
					
						
							| 
									
										
										
										
											2009-12-09 09:53:43 +01:00
										 |  |  |         return gdb.parse_and_eval(exp) | 
					
						
							|  |  |  |     # Work around non-existing gdb.parse_and_eval as in released 7.0 | 
					
						
							|  |  |  |     gdb.execute("set logging redirect on") | 
					
						
							|  |  |  |     gdb.execute("set logging on") | 
					
						
							| 
									
										
										
										
											2010-01-08 11:03:00 +01:00
										 |  |  |     try: | 
					
						
							|  |  |  |         gdb.execute("print %s" % exp) | 
					
						
							|  |  |  |     except: | 
					
						
							|  |  |  |         gdb.execute("set logging off") | 
					
						
							|  |  |  |         return None | 
					
						
							| 
									
										
										
										
											2009-12-09 09:53:43 +01:00
										 |  |  |     gdb.execute("set logging off") | 
					
						
							|  |  |  |     return gdb.history(0) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-19 18:15:16 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | class Breakpoint: | 
					
						
							|  |  |  |     def __init__(self): | 
					
						
							|  |  |  |         self.number = None | 
					
						
							|  |  |  |         self.filename = None | 
					
						
							|  |  |  |         self.linenumber = None | 
					
						
							|  |  |  |         self.address = [] | 
					
						
							|  |  |  |         self.function = None | 
					
						
							|  |  |  |         self.fullname = None | 
					
						
							|  |  |  |         self.condition = None | 
					
						
							|  |  |  |         self.times = None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def listOfBreakpoints(d): | 
					
						
							|  |  |  |     file = tempfile.mkstemp(prefix="gdbpy_") | 
					
						
							|  |  |  |     filename = file[1] | 
					
						
							|  |  |  |     gdb.execute("set logging off") | 
					
						
							|  |  |  |     gdb.execute("set logging redirect off") | 
					
						
							|  |  |  |     gdb.execute("set logging file %s" % filename) | 
					
						
							|  |  |  |     gdb.execute("set logging redirect on") | 
					
						
							|  |  |  |     gdb.execute("set logging on") | 
					
						
							|  |  |  |     gdb.execute("info break") | 
					
						
							|  |  |  |     gdb.execute("set logging off") | 
					
						
							|  |  |  |     gdb.execute("set logging redirect off") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # [bkpt={number="1",type="breakpoint",disp="keep",enabled="y", | 
					
						
							|  |  |  |     #addr="0x0804da6d",func="testHidden()",file="../app.cpp", | 
					
						
							|  |  |  |     #fullname="...",line="1292",times="1",original-location="\"app.cpp\":1292"}, | 
					
						
							|  |  |  |     # Num     Type           Disp Enb Address    What\n" | 
					
						
							|  |  |  |     #1       breakpoint     keep y   0x0804da6d in testHidden() at app.cpp:1292 | 
					
						
							|  |  |  |     #\tbreakpoint already hit 1 time | 
					
						
							|  |  |  |     #2       breakpoint     keep y   0x080564d3 in espace::..doit(int) at ../app.cpp:1210\n" | 
					
						
							|  |  |  |     #3       breakpoint     keep y   <PENDING>  \"plugin.cpp\":38\n" | 
					
						
							|  |  |  |     #4       breakpoint     keep y   <MULTIPLE> \n" | 
					
						
							|  |  |  |     #4.1                         y     0x08056673 in Foo at ../app.cpp:126\n" | 
					
						
							|  |  |  |     #4.2                         y     0x0805678b in Foo at ../app.cpp:126\n" | 
					
						
							|  |  |  |     #5       hw watchpoint  keep y              &main\n" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     file = open(filename, "r") | 
					
						
							|  |  |  |     lines = [] | 
					
						
							|  |  |  |     for line in file: | 
					
						
							|  |  |  |         if len(line) == 0 or line.startswith(" "): | 
					
						
							|  |  |  |             continue | 
					
						
							|  |  |  |         lines.append(line) | 
					
						
							|  |  |  |     file.close() | 
					
						
							|  |  |  |     os.remove(filename) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     lines.reverse() | 
					
						
							|  |  |  |     bp = Breakpoint() | 
					
						
							|  |  |  |     for line in lines: | 
					
						
							|  |  |  |         if line[0] < '0' or line[0] > '9': | 
					
						
							|  |  |  |             continue | 
					
						
							|  |  |  |         if line.startswith("\tstop only if "): | 
					
						
							|  |  |  |             bp.condition = line[14:] | 
					
						
							|  |  |  |             continue | 
					
						
							|  |  |  |         if line.startswith("\tbreakpoint already hit "): | 
					
						
							|  |  |  |             bp.times = line[24:] | 
					
						
							|  |  |  |             continue | 
					
						
							|  |  |  |         number = line[0:5] | 
					
						
							|  |  |  |         pos0x = line.find(" 0x") | 
					
						
							|  |  |  |         posin = line.find(" in ") | 
					
						
							|  |  |  |         posat = line.find(" at ") | 
					
						
							|  |  |  |         poscol = line.find(":", posat) | 
					
						
							|  |  |  |         if pos0x < posin and pos0x != -1: | 
					
						
							|  |  |  |             bp.address.append(line[pos0x + 1 : posin]) | 
					
						
							|  |  |  |         if line.find("<PENDING>") >= 0: | 
					
						
							|  |  |  |             bp.address.append("<PENDING>") | 
					
						
							|  |  |  |         if posin < posat and posin != -1: | 
					
						
							|  |  |  |             bp.function = line[posin + 4 : posat] | 
					
						
							|  |  |  |         if posat < poscol and poscol != -1: | 
					
						
							|  |  |  |             bp.filename = line[posat + 4 : poscol] | 
					
						
							|  |  |  |         if poscol != -1: | 
					
						
							|  |  |  |             bp.linenumber = line[poscol + 1 : -1] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if '.' in number: # Part of multiple breakpoint. | 
					
						
							|  |  |  |             continue | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # A breakpoint of its own | 
					
						
							|  |  |  |         bp.number = int(number) | 
					
						
							|  |  |  |         d.putCommaIfNeeded() | 
					
						
							|  |  |  |         d.put('bkpt={number="%s"' % bp.number) | 
					
						
							|  |  |  |         d.put(',type="breakpoint"') | 
					
						
							|  |  |  |         d.put(',disp="keep"') | 
					
						
							|  |  |  |         d.put(',enabled="y"') | 
					
						
							|  |  |  |         for address in bp.address: | 
					
						
							|  |  |  |             d.put(',addr="%s"' % address) | 
					
						
							|  |  |  |         if not bp.function is None: | 
					
						
							|  |  |  |             d.put(',func="%s"' % bp.function) | 
					
						
							|  |  |  |         if not bp.filename is None: | 
					
						
							|  |  |  |             d.put(',file="%s"' % bp.filename) | 
					
						
							|  |  |  |         if not bp.fullname is None: | 
					
						
							|  |  |  |             d.put(',fullname="%s"' % bp.fullname) | 
					
						
							|  |  |  |         if not bp.linenumber is None: | 
					
						
							|  |  |  |             d.put(',line="%s"' % bp.linenumber) | 
					
						
							|  |  |  |         if not bp.condition is None: | 
					
						
							|  |  |  |             d.put(',cond="%s"' % bp.condition) | 
					
						
							|  |  |  |         if not bp.fullname is None: | 
					
						
							|  |  |  |             d.put(',fullname="%s"' % bt.fullname) | 
					
						
							|  |  |  |         if not bp.times is None: | 
					
						
							|  |  |  |             d.put(',times="1"' % bp.times) | 
					
						
							|  |  |  |         #d.put('original-location="-"') | 
					
						
							|  |  |  |         d.put('}') | 
					
						
							|  |  |  |         bp = Breakpoint() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-14 15:25:53 +01:00
										 |  |  | def listOfLocals(varList): | 
					
						
							| 
									
										
										
										
											2009-12-09 09:53:43 +01:00
										 |  |  |     try: | 
					
						
							|  |  |  |         frame = gdb.selected_frame() | 
					
						
							|  |  |  |         #warn("FRAME %s: " % frame) | 
					
						
							|  |  |  |     except RuntimeError: | 
					
						
							| 
									
										
										
										
											2010-01-14 15:25:53 +01:00
										 |  |  |         warn("FRAME NOT ACCESSIBLE") | 
					
						
							| 
									
										
										
										
											2009-12-18 16:25:59 +01:00
										 |  |  |         return [] | 
					
						
							| 
									
										
										
										
											2009-12-09 09:53:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-14 15:25:53 +01:00
										 |  |  |     # gdb-6.8-symbianelf fails here | 
					
						
							|  |  |  |     hasBlock = 'block' in dir(frame) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-09 09:53:43 +01:00
										 |  |  |     items = [] | 
					
						
							| 
									
										
										
										
											2010-01-14 15:25:53 +01:00
										 |  |  |     if hasBlock and isGoodGdb(): | 
					
						
							|  |  |  |         warn("IS GOOD: %s " % varList) | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             block = frame.block() | 
					
						
							|  |  |  |             #warn("BLOCK: %s " % block) | 
					
						
							|  |  |  |         except: | 
					
						
							|  |  |  |             warn("BLOCK NOT ACCESSIBLE") | 
					
						
							|  |  |  |             return items | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-09 09:53:43 +01:00
										 |  |  |         while True: | 
					
						
							|  |  |  |             if block is None: | 
					
						
							|  |  |  |                 warn("UNEXPECTED 'None' BLOCK") | 
					
						
							|  |  |  |                 break | 
					
						
							|  |  |  |             for symbol in block: | 
					
						
							|  |  |  |                 name = symbol.print_name | 
					
						
							| 
									
										
										
										
											2010-01-06 17:01:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-09 09:53:43 +01:00
										 |  |  |                 if name == "__in_chrg": | 
					
						
							|  |  |  |                     continue | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 # "NotImplementedError: Symbol type not yet supported in | 
					
						
							|  |  |  |                 # Python scripts." | 
					
						
							|  |  |  |                 #warn("SYMBOL %s: " % symbol.value) | 
					
						
							|  |  |  |                 #warn("SYMBOL %s  (%s): " % (symbol, name)) | 
					
						
							|  |  |  |                 item = Item(0, "local", name, name) | 
					
						
							|  |  |  |                 try: | 
					
						
							|  |  |  |                     item.value = frame.read_var(name)  # this is a gdb value | 
					
						
							|  |  |  |                 except RuntimeError: | 
					
						
							|  |  |  |                     # happens for  void foo() { std::string s; std::wstring w; } | 
					
						
							|  |  |  |                     #warn("  FRAME READ VAR ERROR: %s (%s): " % (symbol, name)) | 
					
						
							|  |  |  |                     continue | 
					
						
							|  |  |  |                 #warn("ITEM %s: " % item.value) | 
					
						
							|  |  |  |                 items.append(item) | 
					
						
							|  |  |  |             # The outermost block in a function has the function member | 
					
						
							|  |  |  |             # FIXME: check whether this is guaranteed. | 
					
						
							|  |  |  |             if not block.function is None: | 
					
						
							|  |  |  |                 break | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             block = block.superblock | 
					
						
							|  |  |  |     else: | 
					
						
							| 
									
										
										
										
											2009-12-18 16:25:59 +01:00
										 |  |  |         # Assuming gdb 7.0 release or 6.8-symbianelf. | 
					
						
							| 
									
										
										
										
											2009-12-09 09:53:43 +01:00
										 |  |  |         file = tempfile.mkstemp(prefix="gdbpy_") | 
					
						
							|  |  |  |         filename = file[1] | 
					
						
							| 
									
										
										
										
											2010-01-14 15:25:53 +01:00
										 |  |  |         #warn("VARLIST: %s " % varList) | 
					
						
							|  |  |  |         #warn("VARLIST: %s " % len(varList)) | 
					
						
							| 
									
										
										
										
											2009-12-18 16:25:59 +01:00
										 |  |  |         gdb.execute("set logging off") | 
					
						
							|  |  |  |         gdb.execute("set logging redirect off") | 
					
						
							| 
									
										
										
										
											2009-12-09 09:53:43 +01:00
										 |  |  |         gdb.execute("set logging file %s" % filename) | 
					
						
							|  |  |  |         gdb.execute("set logging redirect on") | 
					
						
							|  |  |  |         gdb.execute("set logging on") | 
					
						
							| 
									
										
										
										
											2010-01-14 15:25:53 +01:00
										 |  |  |         try: | 
					
						
							|  |  |  |             gdb.execute("info args") | 
					
						
							|  |  |  |             # We cannot use "info locals" as at least 6.8-symbianelf | 
					
						
							|  |  |  |             # aborts as soon as we hit unreadable memory. | 
					
						
							|  |  |  |             # gdb.execute("interpreter mi '-stack-list-locals 0'") | 
					
						
							|  |  |  |             # results in &"Recursive internal problem.\n", so we have | 
					
						
							|  |  |  |             # the frontend pass us the list of locals. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # There are two cases, either varList is empty, so we have | 
					
						
							|  |  |  |             # to fetch the list here, or it is not empty with the | 
					
						
							|  |  |  |             # first entry being a dummy. | 
					
						
							|  |  |  |             if len(varList) == 0: | 
					
						
							|  |  |  |                 gdb.execute("info locals") | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 varList = varList[1:] | 
					
						
							|  |  |  |         except: | 
					
						
							|  |  |  |             pass | 
					
						
							| 
									
										
										
										
											2009-12-09 09:53:43 +01:00
										 |  |  |         gdb.execute("set logging off") | 
					
						
							|  |  |  |         gdb.execute("set logging redirect off") | 
					
						
							| 
									
										
										
										
											2010-01-14 15:25:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-09 09:53:43 +01:00
										 |  |  |         file = open(filename, "r") | 
					
						
							|  |  |  |         for line in file: | 
					
						
							|  |  |  |             if len(line) == 0 or line.startswith(" "): | 
					
						
							|  |  |  |                 continue | 
					
						
							| 
									
										
										
										
											2010-01-14 15:25:53 +01:00
										 |  |  |             # The function parameters | 
					
						
							| 
									
										
										
										
											2009-12-09 09:53:43 +01:00
										 |  |  |             pos = line.find(" = ") | 
					
						
							|  |  |  |             if pos < 0: | 
					
						
							|  |  |  |                 continue | 
					
						
							| 
									
										
										
										
											2010-01-14 15:25:53 +01:00
										 |  |  |             varList.append(line[0:pos]) | 
					
						
							|  |  |  |         file.close() | 
					
						
							|  |  |  |         os.remove(filename) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         #warn("VARLIST: %s " % varList) | 
					
						
							|  |  |  |         for name in varList: | 
					
						
							|  |  |  |             #warn("NAME %s " % name) | 
					
						
							| 
									
										
										
										
											2009-12-09 09:53:43 +01:00
										 |  |  |             item = Item(0, "local", name, name) | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 item.value = frame.read_var(name)  # this is a gdb value | 
					
						
							|  |  |  |             except RuntimeError: | 
					
						
							| 
									
										
										
										
											2010-01-14 15:25:53 +01:00
										 |  |  |                 pass | 
					
						
							|  |  |  |                 #continue | 
					
						
							| 
									
										
										
										
											2009-12-09 09:53:43 +01:00
										 |  |  |             items.append(item) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return items | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-07 09:14:35 +01:00
										 |  |  | def value(expr): | 
					
						
							| 
									
										
										
										
											2009-12-09 09:53:43 +01:00
										 |  |  |     value = parseAndEvaluate(expr) | 
					
						
							| 
									
										
										
										
											2009-12-07 09:14:35 +01:00
										 |  |  |     try: | 
					
						
							|  |  |  |         return int(value) | 
					
						
							|  |  |  |     except: | 
					
						
							|  |  |  |         return str(value) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-09 09:53:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  | def isSimpleType(typeobj): | 
					
						
							| 
									
										
										
										
											2010-01-07 13:02:19 +01:00
										 |  |  |     if typeobj.code == gdb.TYPE_CODE_PTR: | 
					
						
							|  |  |  |         return False | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  |     type = str(typeobj) | 
					
						
							|  |  |  |     return type == "bool" \ | 
					
						
							|  |  |  |         or type == "char" \ | 
					
						
							|  |  |  |         or type == "double" \ | 
					
						
							|  |  |  |         or type == "float" \ | 
					
						
							|  |  |  |         or type == "int" \ | 
					
						
							|  |  |  |         or type == "long" or type.startswith("long ") \ | 
					
						
							|  |  |  |         or type == "short" or type.startswith("short ") \ | 
					
						
							| 
									
										
										
										
											2010-01-05 10:48:14 +01:00
										 |  |  |         or type == "signed" or type.startswith("signed ") \ | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  |         or type == "unsigned" or type.startswith("unsigned ") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-09 09:53:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  | def isStringType(d, typeobj): | 
					
						
							|  |  |  |     type = str(typeobj) | 
					
						
							|  |  |  |     return type == d.ns + "QString" \ | 
					
						
							|  |  |  |         or type == d.ns + "QByteArray" \ | 
					
						
							|  |  |  |         or type == "std::string" \ | 
					
						
							|  |  |  |         or type == "std::wstring" \ | 
					
						
							|  |  |  |         or type == "wstring" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def warn(message): | 
					
						
							| 
									
										
										
										
											2010-01-14 15:25:53 +01:00
										 |  |  |     if True or verbosity > 0: | 
					
						
							|  |  |  |         print "XXX: %s\n" % message.encode("latin1") | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  |     pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def check(exp): | 
					
						
							|  |  |  |     if not exp: | 
					
						
							|  |  |  |         raise RuntimeError("Check failed") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-04 14:14:14 +01:00
										 |  |  | def checkRef(ref): | 
					
						
							|  |  |  |     count = ref["_q_value"] | 
					
						
							|  |  |  |     check(count > 0) | 
					
						
							|  |  |  |     check(count < 1000000) # assume there aren't a million references to any object | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  | #def couldBePointer(p, align): | 
					
						
							|  |  |  | #    type = gdb.lookup_type("unsigned int") | 
					
						
							|  |  |  | #    ptr = gdb.Value(p).cast(type) | 
					
						
							|  |  |  | #    d = int(str(ptr)) | 
					
						
							|  |  |  | #    warn("CHECKING : %s %d " % (p, ((d & 3) == 0 and (d > 1000 or d == 0)))) | 
					
						
							|  |  |  | #    return (d & (align - 1)) and (d > 1000 or d == 0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def checkAccess(p, align = 1): | 
					
						
							|  |  |  |     return p.dereference() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def checkContents(p, expected, align = 1): | 
					
						
							|  |  |  |     if int(p.dereference()) != expected: | 
					
						
							|  |  |  |         raise RuntimeError("Contents check failed") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def checkPointer(p, align = 1): | 
					
						
							|  |  |  |     if not isNull(p): | 
					
						
							|  |  |  |         p.dereference() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def isNull(p): | 
					
						
							| 
									
										
										
										
											2010-01-04 16:15:32 +01:00
										 |  |  |     # The following can cause evaluation to abort with "UnicodeEncodeError" | 
					
						
							|  |  |  |     # for invalid char *, as their "contents" is being examined | 
					
						
							|  |  |  |     #s = str(p) | 
					
						
							|  |  |  |     #return s == "0x0" or s.startswith("0x0 ") | 
					
						
							| 
									
										
										
										
											2010-01-07 13:02:19 +01:00
										 |  |  |     return p.cast(gdb.lookup_type("void").pointer()) == 0 | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | movableTypes = set([ | 
					
						
							|  |  |  |     "QBrush", "QBitArray", "QByteArray", | 
					
						
							|  |  |  |     "QCustomTypeInfo", "QChar", | 
					
						
							|  |  |  |     "QDate", "QDateTime", | 
					
						
							|  |  |  |     "QFileInfo", "QFixed", "QFixedPoint", "QFixedSize", | 
					
						
							|  |  |  |     "QHashDummyValue", | 
					
						
							|  |  |  |     "QIcon", "QImage", | 
					
						
							|  |  |  |     "QLine", "QLineF", "QLatin1Char", "QLocal", | 
					
						
							|  |  |  |     "QMatrix", "QModelIndex", | 
					
						
							|  |  |  |     "QPoint", "QPointF", "QPen", "QPersistentModelIndex", | 
					
						
							|  |  |  |     "QResourceRoot", "QRect", "QRectF", "QRegExp", | 
					
						
							|  |  |  |     "QSize", "QSizeF", "QString", | 
					
						
							|  |  |  |     "QTime", "QTextBlock", | 
					
						
							|  |  |  |     "QUrl", | 
					
						
							|  |  |  |     "QVariant", | 
					
						
							|  |  |  |     "QXmlStreamAttribute", "QXmlStreamNamespaceDeclaration", | 
					
						
							|  |  |  |     "QXmlStreamNotationDeclaration", "QXmlStreamEntityDeclaration"]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def stripClassTag(type): | 
					
						
							|  |  |  |     if type.startswith("class "): | 
					
						
							|  |  |  |         return type[6:] | 
					
						
							|  |  |  |     return type | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def checkPointerRange(p, n): | 
					
						
							| 
									
										
										
										
											2009-12-10 17:45:13 +01:00
										 |  |  |     for i in xrange(n): | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  |         checkPointer(p) | 
					
						
							|  |  |  |         ++p | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def call(value, func): | 
					
						
							|  |  |  |     #warn("CALL: %s -> %s" % (value, func)) | 
					
						
							|  |  |  |     type = stripClassTag(str(value.type)) | 
					
						
							| 
									
										
										
										
											2009-12-09 09:53:43 +01:00
										 |  |  |     if type.find(":") >= 0: | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  |         type = "'" + type + "'" | 
					
						
							|  |  |  |     exp = "((%s*)%s)->%s" % (type, value.address, func) | 
					
						
							|  |  |  |     #warn("CALL: %s" % exp) | 
					
						
							| 
									
										
										
										
											2009-12-09 09:53:43 +01:00
										 |  |  |     result = parseAndEvaluate(exp) | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  |     #warn("  -> %s" % result) | 
					
						
							|  |  |  |     return result | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-02 14:10:14 +01:00
										 |  |  | def qtNamespace(): | 
					
						
							|  |  |  |     try: | 
					
						
							| 
									
										
										
										
											2009-12-09 09:53:43 +01:00
										 |  |  |         type = str(parseAndEvaluate("&QString::null").type.target().unqualified()) | 
					
						
							| 
									
										
										
										
											2009-12-02 14:10:14 +01:00
										 |  |  |         return type[0:len(type) - len("QString::null")] | 
					
						
							|  |  |  |     except RuntimeError: | 
					
						
							|  |  |  |         return "" | 
					
						
							| 
									
										
										
										
											2010-01-11 13:14:54 +01:00
										 |  |  |     except AttributeError: | 
					
						
							|  |  |  |         # Happens for none-Qt applications | 
					
						
							|  |  |  |         return "" | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-07 09:14:35 +01:00
										 |  |  | def encodeCharArray(p, size): | 
					
						
							|  |  |  |     s = "" | 
					
						
							| 
									
										
										
										
											2010-01-07 13:02:19 +01:00
										 |  |  |     p = p.cast(gdb.lookup_type("unsigned char").pointer()) | 
					
						
							| 
									
										
										
										
											2009-12-10 17:45:13 +01:00
										 |  |  |     for i in xrange(size): | 
					
						
							| 
									
										
										
										
											2009-12-07 09:14:35 +01:00
										 |  |  |         s += "%02x" % int(p.dereference()) | 
					
						
							|  |  |  |         p += 1 | 
					
						
							|  |  |  |     return s | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-03 13:58:14 +01:00
										 |  |  | def encodeByteArray(value): | 
					
						
							|  |  |  |     d_ptr = value['d'].dereference() | 
					
						
							|  |  |  |     data = d_ptr['data'] | 
					
						
							|  |  |  |     size = d_ptr['size'] | 
					
						
							|  |  |  |     alloc = d_ptr['alloc'] | 
					
						
							|  |  |  |     check(0 <= size and size <= alloc and alloc <= 100*1000*1000) | 
					
						
							| 
									
										
										
										
											2010-01-04 14:14:14 +01:00
										 |  |  |     checkRef(d_ptr["ref"]) | 
					
						
							| 
									
										
										
										
											2009-12-03 13:58:14 +01:00
										 |  |  |     if size > 0: | 
					
						
							|  |  |  |         checkAccess(data, 4) | 
					
						
							|  |  |  |         checkAccess(data + size) == 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     innerType = gdb.lookup_type("char") | 
					
						
							|  |  |  |     p = gdb.Value(data.cast(innerType.pointer())) | 
					
						
							| 
									
										
										
										
											2009-12-07 09:14:35 +01:00
										 |  |  |     return encodeCharArray(p, size) | 
					
						
							| 
									
										
										
										
											2009-12-03 13:58:14 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | def encodeString(value): | 
					
						
							|  |  |  |     d_ptr = value['d'].dereference() | 
					
						
							|  |  |  |     data = d_ptr['data'] | 
					
						
							|  |  |  |     size = d_ptr['size'] | 
					
						
							|  |  |  |     alloc = d_ptr['alloc'] | 
					
						
							|  |  |  |     check(0 <= size and size <= alloc and alloc <= 100*1000*1000) | 
					
						
							|  |  |  |     if size > 0: | 
					
						
							|  |  |  |         checkAccess(data, 4) | 
					
						
							|  |  |  |         checkAccess(data + size * 2) == 0 | 
					
						
							| 
									
										
										
										
											2010-01-04 14:14:14 +01:00
										 |  |  |     checkRef(d_ptr["ref"]) | 
					
						
							| 
									
										
										
										
											2009-12-03 13:58:14 +01:00
										 |  |  |     p = gdb.Value(d_ptr["data"]) | 
					
						
							|  |  |  |     s = "" | 
					
						
							| 
									
										
										
										
											2009-12-10 17:45:13 +01:00
										 |  |  |     for i in xrange(size): | 
					
						
							| 
									
										
										
										
											2009-12-03 13:58:14 +01:00
										 |  |  |         val = int(p.dereference()) | 
					
						
							|  |  |  |         s += "%02x" % (val % 256) | 
					
						
							|  |  |  |         s += "%02x" % (val / 256) | 
					
						
							|  |  |  |         p += 1 | 
					
						
							|  |  |  |     return s | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  | ####################################################################### | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # Item | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | ####################################################################### | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class Item: | 
					
						
							| 
									
										
										
										
											2009-12-14 10:28:51 +01:00
										 |  |  |     def __init__(self, value, parentiname, iname, name = None): | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  |         self.value = value | 
					
						
							| 
									
										
										
										
											2009-11-27 13:52:29 +01:00
										 |  |  |         if iname is None: | 
					
						
							|  |  |  |             self.iname = parentiname | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.iname = "%s.%s" % (parentiname, iname) | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  |         self.name = name | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ####################################################################### | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # FrameCommand | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | ####################################################################### | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class FrameCommand(gdb.Command): | 
					
						
							|  |  |  |     """Do fancy stuff. Usage bb --verbose expandedINames""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self): | 
					
						
							|  |  |  |         super(FrameCommand, self).__init__("bb", gdb.COMMAND_OBSCURE) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def invoke(self, arg, from_tty): | 
					
						
							|  |  |  |         args = arg.split(' ') | 
					
						
							| 
									
										
										
										
											2010-01-14 15:25:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  |         #warn("ARG: %s" % arg) | 
					
						
							|  |  |  |         #warn("ARGS: %s" % args) | 
					
						
							| 
									
										
										
										
											2010-01-05 10:48:14 +01:00
										 |  |  |         options = args[0].split(",") | 
					
						
							| 
									
										
										
										
											2010-01-14 15:25:53 +01:00
										 |  |  |         varList = args[1][1:] | 
					
						
							|  |  |  |         if len(varList) == 0: | 
					
						
							|  |  |  |             varList = [] | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             varList = varList.split(",") | 
					
						
							|  |  |  |         expandedINames = set(args[2].split(",")) | 
					
						
							|  |  |  |         watchers = "" | 
					
						
							|  |  |  |         if len(args) > 3: | 
					
						
							|  |  |  |             watchers = base64.b16decode(args[3], True) | 
					
						
							|  |  |  |         #warn("WATCHERS: %s" % watchers) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-05 10:48:14 +01:00
										 |  |  |         useFancy = "fancy" in options | 
					
						
							| 
									
										
										
										
											2010-01-14 15:25:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         #warn("VARIABLES: %s" % varList) | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  |         #warn("EXPANDED INAMES: %s" % expandedINames) | 
					
						
							|  |  |  |         module = sys.modules[__name__] | 
					
						
							|  |  |  |         self.dumpers = {} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-02 14:54:29 +01:00
										 |  |  |         if useFancy == -1: | 
					
						
							|  |  |  |             output = "dumpers=[" | 
					
						
							|  |  |  |             for key, value in module.__dict__.items(): | 
					
						
							| 
									
										
										
										
											2009-12-07 11:35:43 +01:00
										 |  |  |                 if key.startswith("qdump__"): | 
					
						
							| 
									
										
										
										
											2009-12-02 14:54:29 +01:00
										 |  |  |                     if output != "dumpers=[": | 
					
						
							|  |  |  |                         output += "," | 
					
						
							| 
									
										
										
										
											2009-12-07 11:35:43 +01:00
										 |  |  |                     output += '"' + key[7:] + '"' | 
					
						
							| 
									
										
										
										
											2009-12-02 14:54:29 +01:00
										 |  |  |             output += "]," | 
					
						
							|  |  |  |             #output += "qtversion=[%d,%d,%d]" | 
					
						
							| 
									
										
										
										
											2010-01-14 15:25:53 +01:00
										 |  |  |             #output += "qtversion=[4,6,0]," | 
					
						
							| 
									
										
										
										
											2009-12-02 14:54:29 +01:00
										 |  |  |             output += "namespace=\"%s\"," % qtNamespace() | 
					
						
							|  |  |  |             output += "dumperversion=\"2.0\"," | 
					
						
							|  |  |  |             output += "sizes=[]," | 
					
						
							|  |  |  |             output += "expressions=[]" | 
					
						
							|  |  |  |             output += "]" | 
					
						
							|  |  |  |             print output | 
					
						
							|  |  |  |             return | 
					
						
							| 
									
										
										
										
											2010-01-06 17:01:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-04 13:22:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  |         if useFancy: | 
					
						
							|  |  |  |             for key, value in module.__dict__.items(): | 
					
						
							| 
									
										
										
										
											2009-12-07 11:35:43 +01:00
										 |  |  |                 if key.startswith("qdump__"): | 
					
						
							|  |  |  |                     self.dumpers[key[7:]] = value | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         d = Dumper() | 
					
						
							|  |  |  |         d.dumpers = self.dumpers | 
					
						
							| 
									
										
										
										
											2010-01-05 10:48:14 +01:00
										 |  |  |         d.useFancy = useFancy | 
					
						
							|  |  |  |         d.passExceptions = "passexceptions" in options | 
					
						
							|  |  |  |         d.autoDerefPointers = "autoderef" in options | 
					
						
							| 
									
										
										
										
											2009-12-02 14:10:14 +01:00
										 |  |  |         d.ns = qtNamespace() | 
					
						
							| 
									
										
										
										
											2009-12-04 13:22:39 +01:00
										 |  |  |         d.expandedINames = expandedINames | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  |         #warn(" NAMESPACE IS: '%s'" % d.ns) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-04 13:22:39 +01:00
										 |  |  |         # | 
					
						
							|  |  |  |         # Locals | 
					
						
							|  |  |  |         # | 
					
						
							| 
									
										
										
										
											2010-01-14 15:25:53 +01:00
										 |  |  |         for item in listOfLocals(varList): | 
					
						
							| 
									
										
										
										
											2010-01-07 15:22:06 +01:00
										 |  |  |             #warn("ITEM NAME %s: " % item.name) | 
					
						
							| 
									
										
										
										
											2010-01-14 15:25:53 +01:00
										 |  |  |             try: | 
					
						
							|  |  |  |                 #warn("ITEM VALUE %s: " % item.value) | 
					
						
							|  |  |  |                 # Throw on funny stuff, catch below. | 
					
						
							|  |  |  |                 dummy = str(item.value) | 
					
						
							|  |  |  |             except: | 
					
						
							|  |  |  |                 # Locals with failing memory access. | 
					
						
							|  |  |  |                 d.beginHash() | 
					
						
							|  |  |  |                 d.put('iname="%s",' % item.iname) | 
					
						
							|  |  |  |                 d.put('name="%s",' % item.name) | 
					
						
							|  |  |  |                 d.put('addr="<not accessible>",') | 
					
						
							|  |  |  |                 d.put('value="<not accessible>",') | 
					
						
							|  |  |  |                 d.put('type="%s",' % item.value.type) | 
					
						
							|  |  |  |                 d.put('numchild="0"'); | 
					
						
							|  |  |  |                 d.endHash() | 
					
						
							|  |  |  |                 continue | 
					
						
							| 
									
										
										
										
											2009-12-09 09:53:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |             type = item.value.type | 
					
						
							|  |  |  |             if type.code == gdb.TYPE_CODE_PTR \ | 
					
						
							|  |  |  |                     and item.name == "argv" and str(type) == "char **": | 
					
						
							| 
									
										
										
										
											2010-01-14 15:25:53 +01:00
										 |  |  |                 # Special handling for char** argv. | 
					
						
							| 
									
										
										
										
											2009-12-09 09:53:43 +01:00
										 |  |  |                 n = 0 | 
					
						
							|  |  |  |                 p = item.value | 
					
						
							| 
									
										
										
										
											2010-01-28 15:21:16 +01:00
										 |  |  |                 # p is 0 for "optimized out" cases. | 
					
						
							|  |  |  |                 if not isNull(p): | 
					
						
							|  |  |  |                     while not isNull(p.dereference()) and n <= 100: | 
					
						
							|  |  |  |                         p += 1 | 
					
						
							|  |  |  |                         n += 1 | 
					
						
							| 
									
										
										
										
											2009-12-09 09:53:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 d.beginHash() | 
					
						
							|  |  |  |                 d.put('iname="%s",' % item.iname) | 
					
						
							|  |  |  |                 d.putName(item.name) | 
					
						
							|  |  |  |                 d.putItemCount(select(n <= 100, n, "> 100")) | 
					
						
							|  |  |  |                 d.putType(type) | 
					
						
							|  |  |  |                 d.putNumChild(n) | 
					
						
							|  |  |  |                 if d.isExpanded(item): | 
					
						
							| 
									
										
										
										
											2009-12-07 09:14:35 +01:00
										 |  |  |                     p = item.value | 
					
						
							| 
									
										
										
										
											2009-12-09 09:53:43 +01:00
										 |  |  |                     d.beginChildren(n) | 
					
						
							| 
									
										
										
										
											2009-12-10 17:45:13 +01:00
										 |  |  |                     for i in xrange(n): | 
					
						
							| 
									
										
										
										
											2009-12-09 09:53:43 +01:00
										 |  |  |                         value = p.dereference() | 
					
						
							|  |  |  |                         d.putItem(Item(value, item.iname, i, None)) | 
					
						
							| 
									
										
										
										
											2009-12-07 09:14:35 +01:00
										 |  |  |                         p += 1 | 
					
						
							| 
									
										
										
										
											2009-12-09 09:53:43 +01:00
										 |  |  |                     if n > 100: | 
					
						
							|  |  |  |                         d.putEllipsis() | 
					
						
							|  |  |  |                     d.endChildren() | 
					
						
							|  |  |  |                 d.endHash() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             else: | 
					
						
							| 
									
										
										
										
											2010-01-14 15:25:53 +01:00
										 |  |  |                 # A "normal" local variable or parameter. | 
					
						
							| 
									
										
										
										
											2010-01-07 15:22:06 +01:00
										 |  |  |                 try: | 
					
						
							|  |  |  |                     addr = cleanAddress(item.value.address) | 
					
						
							|  |  |  |                     d.beginHash() | 
					
						
							|  |  |  |                     d.put('iname="%s",' % item.iname) | 
					
						
							|  |  |  |                     d.put('addr="%s",' % addr) | 
					
						
							|  |  |  |                     d.safePutItemHelper(item) | 
					
						
							|  |  |  |                     d.endHash() | 
					
						
							|  |  |  |                 except AttributeError: | 
					
						
							| 
									
										
										
										
											2010-01-14 15:25:53 +01:00
										 |  |  |                     # Thrown by cleanAddress with message "'NoneType' object | 
					
						
							|  |  |  |                     # has no attribute 'cast'" for optimized-out values. | 
					
						
							| 
									
										
										
										
											2010-01-07 15:22:06 +01:00
										 |  |  |                     d.beginHash() | 
					
						
							|  |  |  |                     d.put('iname="%s",' % item.iname) | 
					
						
							|  |  |  |                     d.put('name="%s",' % item.name) | 
					
						
							|  |  |  |                     d.put('addr="<optimized out>",') | 
					
						
							|  |  |  |                     d.put('value="<optimized out>",') | 
					
						
							|  |  |  |                     d.put('type="%s"' % item.value.type) | 
					
						
							|  |  |  |                     d.endHash() | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-04 18:16:16 +01:00
										 |  |  |         d.pushOutput() | 
					
						
							|  |  |  |         locals = d.safeoutput | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-04 13:22:39 +01:00
										 |  |  |         # | 
					
						
							|  |  |  |         # Watchers | 
					
						
							|  |  |  |         # | 
					
						
							| 
									
										
										
										
											2009-12-04 18:16:16 +01:00
										 |  |  |         d.safeoutput = "" | 
					
						
							| 
									
										
										
										
											2009-12-07 09:14:35 +01:00
										 |  |  |         if len(watchers) > 0: | 
					
						
							| 
									
										
										
										
											2010-01-06 12:52:41 +01:00
										 |  |  |             for watcher in watchers.split("##"): | 
					
						
							| 
									
										
										
										
											2010-01-08 18:16:16 +01:00
										 |  |  |                 (exp, iname) = watcher.split("#") | 
					
						
							|  |  |  |                 self.handleWatch(d, exp, iname) | 
					
						
							| 
									
										
										
										
											2009-12-04 18:16:16 +01:00
										 |  |  |         d.pushOutput() | 
					
						
							|  |  |  |         watchers = d.safeoutput | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-11 13:21:48 +01:00
										 |  |  |         sep = "" | 
					
						
							|  |  |  |         if len(locals) and len(watchers): | 
					
						
							|  |  |  |             sep = "," | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-19 18:15:16 +01:00
										 |  |  |         # | 
					
						
							|  |  |  |         # Breakpoints | 
					
						
							|  |  |  |         # | 
					
						
							| 
									
										
										
										
											2010-01-20 17:26:38 +01:00
										 |  |  |         breakpoints = "" | 
					
						
							| 
									
										
										
										
											2010-01-19 18:15:16 +01:00
										 |  |  |         #d.safeoutput = "" | 
					
						
							|  |  |  |         #listOfBreakpoints(d) | 
					
						
							|  |  |  |         #d.pushOutput() | 
					
						
							|  |  |  |         #breakpoints = d.safeoutput | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         print('data=[' + locals + sep + watchers + '],bkpts=[' + breakpoints + ']\n') | 
					
						
							| 
									
										
										
										
											2010-01-05 10:48:14 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-04 18:16:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-08 18:16:16 +01:00
										 |  |  |     def handleWatch(self, d, exp, iname): | 
					
						
							|  |  |  |         #warn("HANDLING WATCH %s, INAME: '%s'" % (exp, iname)) | 
					
						
							| 
									
										
										
										
											2009-12-04 18:16:16 +01:00
										 |  |  |         if exp.startswith("["): | 
					
						
							| 
									
										
										
										
											2010-01-08 18:16:16 +01:00
										 |  |  |             warn("EVAL: EXP: %s" % exp) | 
					
						
							| 
									
										
										
										
											2009-12-04 18:16:16 +01:00
										 |  |  |             d.beginHash() | 
					
						
							| 
									
										
										
										
											2010-01-08 18:16:16 +01:00
										 |  |  |             d.put('iname="%s",' % iname) | 
					
						
							| 
									
										
										
										
											2009-12-04 18:16:16 +01:00
										 |  |  |             d.put('name="%s",' % exp) | 
					
						
							| 
									
										
										
										
											2010-01-04 13:48:44 +01:00
										 |  |  |             d.put('exp="%s",' % exp) | 
					
						
							| 
									
										
										
										
											2009-12-04 18:16:16 +01:00
										 |  |  |             try: | 
					
						
							|  |  |  |                 list = eval(exp) | 
					
						
							| 
									
										
										
										
											2009-12-07 09:14:35 +01:00
										 |  |  |                 #warn("EVAL: LIST: %s" % list) | 
					
						
							| 
									
										
										
										
											2009-12-04 18:16:16 +01:00
										 |  |  |                 d.put('value=" "') | 
					
						
							|  |  |  |                 d.put('type=" "') | 
					
						
							|  |  |  |                 d.put('numchild="%d"' % len(list)) | 
					
						
							|  |  |  |                 # This is a list of expressions to evaluate | 
					
						
							|  |  |  |                 d.beginChildren(len(list)) | 
					
						
							|  |  |  |                 itemNumber = 0 | 
					
						
							|  |  |  |                 for item in list: | 
					
						
							| 
									
										
										
										
											2010-01-08 18:16:16 +01:00
										 |  |  |                     self.handleWatch(d, item, "%s.%d" % (iname, itemNumber)) | 
					
						
							| 
									
										
										
										
											2009-12-04 18:16:16 +01:00
										 |  |  |                     itemNumber += 1 | 
					
						
							|  |  |  |                 d.endChildren() | 
					
						
							|  |  |  |             except: | 
					
						
							|  |  |  |                 warn("EVAL: ERROR CAUGHT") | 
					
						
							|  |  |  |                 d.put('value="<syntax error>"') | 
					
						
							|  |  |  |                 d.put('type=" "') | 
					
						
							|  |  |  |                 d.put('numchild="0"') | 
					
						
							|  |  |  |                 d.beginChildren(0) | 
					
						
							|  |  |  |                 d.endChildren() | 
					
						
							|  |  |  |             d.endHash() | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         d.beginHash() | 
					
						
							| 
									
										
										
										
											2010-01-08 18:16:16 +01:00
										 |  |  |         d.put('iname="%s",' % iname) | 
					
						
							| 
									
										
										
										
											2009-12-04 18:16:16 +01:00
										 |  |  |         d.put('name="%s",' % exp) | 
					
						
							| 
									
										
										
										
											2010-01-04 13:48:44 +01:00
										 |  |  |         d.put('exp="%s",' % exp) | 
					
						
							| 
									
										
										
										
											2009-12-04 18:16:16 +01:00
										 |  |  |         handled = False | 
					
						
							|  |  |  |         if exp == "<Edit>": | 
					
						
							|  |  |  |             d.put(',value=" ",') | 
					
						
							|  |  |  |             d.put('type=" ",numchild="0"') | 
					
						
							|  |  |  |         else: | 
					
						
							| 
									
										
										
										
											2009-12-04 13:22:39 +01:00
										 |  |  |             try: | 
					
						
							| 
									
										
										
										
											2009-12-09 09:53:43 +01:00
										 |  |  |                 value = parseAndEvaluate(exp) | 
					
						
							| 
									
										
										
										
											2010-01-08 18:16:16 +01:00
										 |  |  |                 item = Item(value, iname, None, None) | 
					
						
							| 
									
										
										
										
											2010-01-05 10:48:14 +01:00
										 |  |  |                 d.putItemHelper(item) | 
					
						
							| 
									
										
										
										
											2009-12-04 13:36:14 +01:00
										 |  |  |             except RuntimeError: | 
					
						
							| 
									
										
										
										
											2009-12-04 18:16:16 +01:00
										 |  |  |                 d.put(',value="<invalid>",') | 
					
						
							|  |  |  |                 d.put('type="<unknown>",numchild="0"') | 
					
						
							|  |  |  |         d.endHash() | 
					
						
							| 
									
										
										
										
											2009-12-04 13:22:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | FrameCommand() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ####################################################################### | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # The Dumper Class | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | ####################################################################### | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class Dumper: | 
					
						
							|  |  |  |     def __init__(self): | 
					
						
							|  |  |  |         self.output = "" | 
					
						
							|  |  |  |         self.safeoutput = "" | 
					
						
							|  |  |  |         self.childTypes = [""] | 
					
						
							|  |  |  |         self.childNumChilds = [-1] | 
					
						
							| 
									
										
										
										
											2009-12-14 10:28:51 +01:00
										 |  |  |         self.maxNumChilds = [-1] | 
					
						
							|  |  |  |         self.numChilds = [-1] | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def put(self, value): | 
					
						
							|  |  |  |         self.output += value | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def putCommaIfNeeded(self): | 
					
						
							|  |  |  |         c = self.output[-1:] | 
					
						
							|  |  |  |         if c == '}' or c == '"' or c == ']' or c == '\n': | 
					
						
							|  |  |  |             self.put(',') | 
					
						
							|  |  |  |         #warn("C:'%s' COND:'%d' OUT:'%s'" % | 
					
						
							|  |  |  |         #    (c, c == '}' or c == '"' or c == ']' or c == '\n', self.output)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def putField(self, name, value): | 
					
						
							|  |  |  |         self.putCommaIfNeeded() | 
					
						
							|  |  |  |         self.put('%s="%s"' % (name, value)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def beginHash(self): | 
					
						
							|  |  |  |         self.putCommaIfNeeded() | 
					
						
							|  |  |  |         self.put('{') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def endHash(self): | 
					
						
							|  |  |  |         self.put('}') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def beginItem(self, name): | 
					
						
							|  |  |  |         self.putCommaIfNeeded() | 
					
						
							|  |  |  |         self.put(name) | 
					
						
							|  |  |  |         self.put('="') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def endItem(self): | 
					
						
							|  |  |  |         self.put('"') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-14 10:28:51 +01:00
										 |  |  |     def beginChildren(self, numChild_ = 1, childType_ = None, childNumChild_ = None): | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  |         childType = "" | 
					
						
							|  |  |  |         childNumChild = -1 | 
					
						
							| 
									
										
										
										
											2009-12-14 10:28:51 +01:00
										 |  |  |         if type(numChild_) is list: | 
					
						
							|  |  |  |             numChild = numChild_[0] | 
					
						
							|  |  |  |             maxNumChild = numChild_[1] | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             numChild = numChild_ | 
					
						
							|  |  |  |             maxNumChild = numChild_ | 
					
						
							| 
									
										
										
										
											2009-11-27 13:52:29 +01:00
										 |  |  |         if numChild == 0: | 
					
						
							| 
									
										
										
										
											2009-12-14 10:28:51 +01:00
										 |  |  |             childType_ = None | 
					
						
							| 
									
										
										
										
											2009-12-04 11:24:15 +01:00
										 |  |  |         self.putCommaIfNeeded() | 
					
						
							| 
									
										
										
										
											2009-12-14 10:28:51 +01:00
										 |  |  |         if not childType_ is None: | 
					
						
							|  |  |  |             childType = stripClassTag(str(childType_)) | 
					
						
							| 
									
										
										
										
											2009-12-04 11:24:15 +01:00
										 |  |  |             self.put('childtype="%s",' % childType) | 
					
						
							| 
									
										
										
										
											2009-12-14 10:28:51 +01:00
										 |  |  |             if isSimpleType(childType_) or isStringType(self, childType_): | 
					
						
							| 
									
										
										
										
											2009-12-04 11:24:15 +01:00
										 |  |  |                 self.put('childnumchild="0",') | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  |                 childNumChild = 0 | 
					
						
							| 
									
										
										
										
											2009-12-14 10:28:51 +01:00
										 |  |  |             elif childType_.code == gdb.TYPE_CODE_PTR: | 
					
						
							| 
									
										
										
										
											2009-12-04 11:24:15 +01:00
										 |  |  |                 self.put('childnumchild="1",') | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  |                 childNumChild = 1 | 
					
						
							| 
									
										
										
										
											2009-12-14 10:28:51 +01:00
										 |  |  |         if not childNumChild_ is None: | 
					
						
							|  |  |  |             self.put('childnumchild="%s",' % childNumChild_) | 
					
						
							|  |  |  |             childNumChild = childNumChild_ | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  |         self.childTypes.append(childType) | 
					
						
							|  |  |  |         self.childNumChilds.append(childNumChild) | 
					
						
							| 
									
										
										
										
											2009-12-14 10:28:51 +01:00
										 |  |  |         self.numChilds.append(numChild) | 
					
						
							|  |  |  |         self.maxNumChilds.append(maxNumChild) | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  |         #warn("BEGIN: %s" % self.childTypes) | 
					
						
							|  |  |  |         self.put("children=[") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def endChildren(self): | 
					
						
							|  |  |  |         #warn("END: %s" % self.childTypes) | 
					
						
							| 
									
										
										
										
											2009-12-14 10:28:51 +01:00
										 |  |  |         numChild = self.numChilds.pop() | 
					
						
							|  |  |  |         maxNumChild = self.maxNumChilds.pop() | 
					
						
							|  |  |  |         if maxNumChild < numChild: | 
					
						
							|  |  |  |             self.putEllipsis(); | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  |         self.childTypes.pop() | 
					
						
							|  |  |  |         self.childNumChilds.pop() | 
					
						
							|  |  |  |         self.put(']') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-14 10:28:51 +01:00
										 |  |  |     def childRange(self): | 
					
						
							|  |  |  |         return xrange(qmin(self.maxNumChilds[-1], self.numChilds[-1])) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  |     # convenience | 
					
						
							|  |  |  |     def putItemCount(self, count): | 
					
						
							|  |  |  |         self.putCommaIfNeeded() | 
					
						
							|  |  |  |         self.put('value="<%s items>"' % count) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def putEllipsis(self): | 
					
						
							|  |  |  |         self.putCommaIfNeeded() | 
					
						
							|  |  |  |         self.put('{name="<incomplete>",value="",type="",numchild="0"}') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def putType(self, type): | 
					
						
							|  |  |  |         #warn("TYPES: '%s' '%s'" % (type, self.childTypes)) | 
					
						
							|  |  |  |         #warn("  EQUAL 2: %s " % (str(type) == self.childTypes[-1])) | 
					
						
							|  |  |  |         type = stripClassTag(str(type)) | 
					
						
							|  |  |  |         if len(type) > 0 and type != self.childTypes[-1]: | 
					
						
							| 
									
										
										
										
											2009-12-04 11:24:15 +01:00
										 |  |  |             self.putCommaIfNeeded() | 
					
						
							|  |  |  |             self.put('type="%s"' % type) # str(type.unqualified()) ? | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def putNumChild(self, numchild): | 
					
						
							|  |  |  |         #warn("NUM CHILD: '%s' '%s'" % (numchild, self.childNumChilds[-1])) | 
					
						
							| 
									
										
										
										
											2009-12-04 11:24:15 +01:00
										 |  |  |         if numchild != self.childNumChilds[-1]: | 
					
						
							|  |  |  |             self.put(',numchild="%s"' % numchild) | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-03 13:58:14 +01:00
										 |  |  |     def putValue(self, value, encoding = None): | 
					
						
							|  |  |  |         if not encoding is None: | 
					
						
							|  |  |  |             self.putField("valueencoded", encoding) | 
					
						
							|  |  |  |         self.putField("value", value) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def putStringValue(self, value): | 
					
						
							| 
									
										
										
										
											2010-01-11 17:57:50 +01:00
										 |  |  |         if value is None: | 
					
						
							|  |  |  |             self.putCommaIfNeeded() | 
					
						
							|  |  |  |             self.put('value="<not available>"') | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             str = encodeString(value) | 
					
						
							|  |  |  |             self.putCommaIfNeeded() | 
					
						
							|  |  |  |             self.put('valueencoded="%d",value="%s"' % (7, str)) | 
					
						
							| 
									
										
										
										
											2009-12-03 13:58:14 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def putByteArrayValue(self, value): | 
					
						
							|  |  |  |         str = encodeByteArray(value) | 
					
						
							|  |  |  |         self.putCommaIfNeeded() | 
					
						
							|  |  |  |         self.put('valueencoded="%d",value="%s"' % (6, str)) | 
					
						
							| 
									
										
										
										
											2010-01-06 17:01:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-03 13:58:14 +01:00
										 |  |  |     def putName(self, name): | 
					
						
							|  |  |  |         self.putCommaIfNeeded() | 
					
						
							|  |  |  |         self.put('name="%s"' % name) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  |     def isExpanded(self, item): | 
					
						
							|  |  |  |         #warn("IS EXPANDED: %s in %s" % (item.iname, self.expandedINames)) | 
					
						
							|  |  |  |         if item.iname is None: | 
					
						
							|  |  |  |             raise "Illegal iname 'None'" | 
					
						
							|  |  |  |         if item.iname.startswith("None"): | 
					
						
							|  |  |  |             raise "Illegal iname '%s'" % item.iname | 
					
						
							|  |  |  |         #warn("   --> %s" % (item.iname in self.expandedINames)) | 
					
						
							|  |  |  |         return item.iname in self.expandedINames | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def isExpandedIName(self, iname): | 
					
						
							|  |  |  |         return iname in self.expandedINames | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def unputField(self, name): | 
					
						
							|  |  |  |         pos = self.output.rfind(",") | 
					
						
							|  |  |  |         if self.output[pos + 1:].startswith(name): | 
					
						
							|  |  |  |             self.output = self.output[0:pos] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def stripNamespaceFromType(self, typeobj): | 
					
						
							| 
									
										
										
										
											2009-12-07 11:35:43 +01:00
										 |  |  |         # This breaks for dumpers type names containing '__star'. | 
					
						
							|  |  |  |         # But this should not happen as identifiers containing two | 
					
						
							|  |  |  |         # subsequent underscores are reserved for the implemention. | 
					
						
							|  |  |  |         if typeobj.code == gdb.TYPE_CODE_PTR: | 
					
						
							|  |  |  |             return self.stripNamespaceFromType(typeobj.target()) + "__star" | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  |         # FIXME: pass ns from plugin | 
					
						
							|  |  |  |         type = stripClassTag(str(typeobj)) | 
					
						
							|  |  |  |         if len(self.ns) > 0 and type.startswith(self.ns): | 
					
						
							|  |  |  |             type = type[len(self.ns):] | 
					
						
							|  |  |  |         pos = type.find("<") | 
					
						
							|  |  |  |         if pos != -1: | 
					
						
							|  |  |  |             type = type[0:pos] | 
					
						
							|  |  |  |         return type | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def isMovableType(self, type): | 
					
						
							|  |  |  |         if type.code == gdb.TYPE_CODE_PTR: | 
					
						
							|  |  |  |             return True | 
					
						
							|  |  |  |         if isSimpleType(type): | 
					
						
							|  |  |  |             return True | 
					
						
							|  |  |  |         return self.stripNamespaceFromType(type) in movableTypes | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def putIntItem(self, name, value): | 
					
						
							|  |  |  |         self.beginHash() | 
					
						
							| 
									
										
										
										
											2009-12-03 13:58:14 +01:00
										 |  |  |         self.putName(name) | 
					
						
							|  |  |  |         self.putValue(value) | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  |         self.putType("int") | 
					
						
							|  |  |  |         self.putNumChild(0) | 
					
						
							|  |  |  |         self.endHash() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def putBoolItem(self, name, value): | 
					
						
							|  |  |  |         self.beginHash() | 
					
						
							| 
									
										
										
										
											2009-12-03 13:58:14 +01:00
										 |  |  |         self.putName(name) | 
					
						
							|  |  |  |         self.putValue(value) | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  |         self.putType("bool") | 
					
						
							|  |  |  |         self.putNumChild(0) | 
					
						
							|  |  |  |         self.endHash() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def pushOutput(self): | 
					
						
							|  |  |  |         #warn("PUSH OUTPUT: %s " % self.output) | 
					
						
							|  |  |  |         self.safeoutput += self.output | 
					
						
							|  |  |  |         self.output = "" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-03 13:58:14 +01:00
										 |  |  |     def dumpInnerValueHelper(self, item): | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  |         if isSimpleType(item.value.type): | 
					
						
							| 
									
										
										
										
											2009-12-03 13:58:14 +01:00
										 |  |  |             self.safePutItemHelper(item) | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-07 11:35:43 +01:00
										 |  |  |     def safePutItem(self, item): | 
					
						
							|  |  |  |         self.beginHash() | 
					
						
							|  |  |  |         self.safePutItemHelper(item) | 
					
						
							|  |  |  |         self.endHash() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  |     def safePutItemHelper(self, item): | 
					
						
							|  |  |  |         self.pushOutput() | 
					
						
							|  |  |  |         # This is only used at the top level to ensure continuation | 
					
						
							|  |  |  |         # after failures due to uninitialized or corrupted data. | 
					
						
							|  |  |  |         if self.passExceptions: | 
					
						
							|  |  |  |             # for debugging reasons propagate errors. | 
					
						
							|  |  |  |             self.putItemHelper(item) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 self.putItemHelper(item) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-27 13:52:29 +01:00
										 |  |  |             except RuntimeError: | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  |                 self.output = "" | 
					
						
							|  |  |  |                 # FIXME: Only catch debugger related exceptions | 
					
						
							|  |  |  |                 #exType, exValue, exTraceback = sys.exc_info() | 
					
						
							|  |  |  |                 #tb = traceback.format_exception(exType, exValue, exTraceback) | 
					
						
							| 
									
										
										
										
											2009-11-27 13:52:29 +01:00
										 |  |  |                 #warn("Exception: %s" % ex.message) | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  |                 # DeprecationWarning: BaseException.message | 
					
						
							|  |  |  |                 # has been deprecated | 
					
						
							|  |  |  |                 #warn("Exception.") | 
					
						
							|  |  |  |                 #for line in tb: | 
					
						
							|  |  |  |                 #    warn("%s" % line) | 
					
						
							| 
									
										
										
										
											2009-12-03 13:58:14 +01:00
										 |  |  |                 self.putName(item.name) | 
					
						
							|  |  |  |                 self.putValue("<invalid>") | 
					
						
							|  |  |  |                 self.putType(str(item.value.type)) | 
					
						
							|  |  |  |                 self.putNumChild(0) | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  |                 #if self.isExpanded(item): | 
					
						
							|  |  |  |                 self.beginChildren() | 
					
						
							|  |  |  |                 self.endChildren() | 
					
						
							|  |  |  |         self.pushOutput() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def putItem(self, item): | 
					
						
							|  |  |  |         self.beginHash() | 
					
						
							| 
									
										
										
										
											2009-12-02 14:54:29 +01:00
										 |  |  |         self.safePutItemHelper(item) | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  |         self.endHash() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def putCallItem(self, name, item, func): | 
					
						
							| 
									
										
										
										
											2010-01-11 17:57:50 +01:00
										 |  |  |         try: | 
					
						
							|  |  |  |             result = call(item.value, func) | 
					
						
							|  |  |  |             self.safePutItem(Item(result, item.iname, name, name)) | 
					
						
							|  |  |  |         except: | 
					
						
							|  |  |  |             self.safePutItem(Item(None, item.iname)) | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-03 13:58:14 +01:00
										 |  |  |     def putItemHelper(self, item): | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  |         name = getattr(item, "name", None) | 
					
						
							|  |  |  |         if not name is None: | 
					
						
							| 
									
										
										
										
											2009-12-03 13:58:14 +01:00
										 |  |  |             self.putName(name) | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-08 11:03:00 +01:00
										 |  |  |         if item.value is None: | 
					
						
							|  |  |  |             # Happens for non-available watchers in gdb versions that | 
					
						
							|  |  |  |             # need to use gdb.execute instead of gdb.parse_and_eval | 
					
						
							|  |  |  |             self.putValue("<not available>") | 
					
						
							|  |  |  |             self.putType("<unknown>") | 
					
						
							|  |  |  |             self.putNumChild(0) | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  |         # FIXME: Gui shows references stripped? | 
					
						
							| 
									
										
										
										
											2010-01-07 13:02:19 +01:00
										 |  |  |         #warn(" "); | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  |         #warn("REAL INAME: %s " % item.iname) | 
					
						
							| 
									
										
										
										
											2010-01-06 17:01:16 +01:00
										 |  |  |         #warn("REAL NAME: %s " % name) | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  |         #warn("REAL TYPE: %s " % item.value.type) | 
					
						
							| 
									
										
										
										
											2010-01-06 16:17:05 +01:00
										 |  |  |         #warn("REAL VALUE: %s " % item.value) | 
					
						
							| 
									
										
										
										
											2010-01-05 10:48:14 +01:00
										 |  |  |         #try: | 
					
						
							|  |  |  |         #    warn("REAL VALUE: %s " % item.value) | 
					
						
							| 
									
										
										
										
											2010-01-14 15:25:53 +01:00
										 |  |  |         #except: | 
					
						
							|  |  |  |         #    #UnicodeEncodeError: | 
					
						
							| 
									
										
										
										
											2010-01-05 10:48:14 +01:00
										 |  |  |         #    warn("REAL VALUE: <unprintable>") | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         value = item.value | 
					
						
							|  |  |  |         type = value.type | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if type.code == gdb.TYPE_CODE_REF: | 
					
						
							|  |  |  |             type = type.target() | 
					
						
							|  |  |  |             value = value.cast(type) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if type.code == gdb.TYPE_CODE_TYPEDEF: | 
					
						
							|  |  |  |             type = type.target() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         strippedType = self.stripNamespaceFromType( | 
					
						
							|  |  |  |             type.strip_typedefs().unqualified()).replace("::", "__") | 
					
						
							| 
									
										
										
										
											2010-01-06 17:01:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  |         #warn(" STRIPPED: %s" % strippedType) | 
					
						
							|  |  |  |         #warn(" DUMPERS: %s" % self.dumpers) | 
					
						
							|  |  |  |         #warn(" DUMPERS: %s" % (strippedType in self.dumpers)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-06 16:17:05 +01:00
										 |  |  |         if isSimpleType(type.unqualified()): | 
					
						
							| 
									
										
										
										
											2009-12-07 11:35:43 +01:00
										 |  |  |             #warn("IS SIMPLE: %s " % type) | 
					
						
							|  |  |  |             self.putType(item.value.type) | 
					
						
							| 
									
										
										
										
											2009-12-03 13:58:14 +01:00
										 |  |  |             self.putValue(value) | 
					
						
							|  |  |  |             self.putNumChild(0) | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         elif strippedType in self.dumpers: | 
					
						
							| 
									
										
										
										
											2009-12-07 11:35:43 +01:00
										 |  |  |             #warn("IS DUMPABLE: %s " % type) | 
					
						
							|  |  |  |             self.putType(item.value.type) | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  |             self.dumpers[strippedType](self, item) | 
					
						
							| 
									
										
										
										
											2010-01-05 17:05:13 +01:00
										 |  |  |             #warn(" RESULT: %s " % self.output) | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         elif type.code == gdb.TYPE_CODE_ENUM: | 
					
						
							| 
									
										
										
										
											2010-01-05 17:05:13 +01:00
										 |  |  |             #warn("GENERIC ENUM: %s" % value) | 
					
						
							| 
									
										
										
										
											2009-12-07 11:35:43 +01:00
										 |  |  |             self.putType(item.value.type) | 
					
						
							| 
									
										
										
										
											2009-12-03 13:58:14 +01:00
										 |  |  |             self.putValue(value) | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  |             self.putNumChild(0) | 
					
						
							| 
									
										
										
										
											2010-01-06 17:01:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         elif type.code == gdb.TYPE_CODE_PTR: | 
					
						
							| 
									
										
										
										
											2010-01-05 10:48:14 +01:00
										 |  |  |             isHandled = False | 
					
						
							| 
									
										
										
										
											2010-01-07 13:02:19 +01:00
										 |  |  |             #warn("A POINTER: %s" % value.type) | 
					
						
							| 
									
										
										
										
											2009-12-07 11:35:43 +01:00
										 |  |  |             if self.useFancy: | 
					
						
							|  |  |  |                 if isNull(value): | 
					
						
							|  |  |  |                     self.putValue("0x0") | 
					
						
							|  |  |  |                     self.putType(item.value.type) | 
					
						
							|  |  |  |                     self.putNumChild(0) | 
					
						
							|  |  |  |                     isHandled = True | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-05 10:48:14 +01:00
										 |  |  |                 target = str(type.target().strip_typedefs().unqualified()) | 
					
						
							|  |  |  |                 if (not isHandled) and target == "void": | 
					
						
							| 
									
										
										
										
											2009-12-07 11:35:43 +01:00
										 |  |  |                     self.putType(item.value.type) | 
					
						
							|  |  |  |                     self.putValue(str(value)) | 
					
						
							|  |  |  |                     self.putNumChild(0) | 
					
						
							|  |  |  |                     isHandled = True | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-29 22:49:55 +01:00
										 |  |  |                 #warn("TARGET: %s " % target) | 
					
						
							| 
									
										
										
										
											2010-01-05 10:48:14 +01:00
										 |  |  |                 if (not isHandled) and (target == "char" | 
					
						
							|  |  |  |                         or target == "signed char" or target == "unsigned char"): | 
					
						
							| 
									
										
										
										
											2009-12-07 11:35:43 +01:00
										 |  |  |                     # Display values up to given length directly | 
					
						
							| 
									
										
										
										
											2010-01-05 10:48:14 +01:00
										 |  |  |                     #warn("CHAR AUTODEREF: %s" % value.address) | 
					
						
							| 
									
										
										
										
											2009-12-07 11:35:43 +01:00
										 |  |  |                     self.putType(item.value.type) | 
					
						
							|  |  |  |                     firstNul = -1 | 
					
						
							|  |  |  |                     p = value | 
					
						
							| 
									
										
										
										
											2010-01-07 13:02:19 +01:00
										 |  |  |                     found = False | 
					
						
							| 
									
										
										
										
											2009-12-10 17:45:13 +01:00
										 |  |  |                     for i in xrange(100): | 
					
						
							| 
									
										
										
										
											2009-12-07 11:35:43 +01:00
										 |  |  |                         if p.dereference() == 0: | 
					
						
							|  |  |  |                             # Found terminating NUL | 
					
						
							| 
									
										
										
										
											2010-01-07 13:02:19 +01:00
										 |  |  |                             found = True | 
					
						
							| 
									
										
										
										
											2009-12-07 11:35:43 +01:00
										 |  |  |                             break | 
					
						
							|  |  |  |                         p += 1 | 
					
						
							| 
									
										
										
										
											2010-01-07 13:02:19 +01:00
										 |  |  |                     if found: | 
					
						
							|  |  |  |                         self.putValue(encodeCharArray(value, i), "6") | 
					
						
							|  |  |  |                         self.putNumChild(0) | 
					
						
							|  |  |  |                     else: | 
					
						
							|  |  |  |                         self.putValue(encodeCharArray(value, 100) + "2e2e2e", "6") | 
					
						
							|  |  |  |                         self.putNumChild(0) | 
					
						
							|  |  |  |                     isHandled = True | 
					
						
							| 
									
										
										
										
											2009-12-07 11:35:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-05 10:48:14 +01:00
										 |  |  |             #warn("AUTODEREF: %s" % self.autoDerefPointers) | 
					
						
							|  |  |  |             #warn("IS HANDLED: %s" % isHandled) | 
					
						
							|  |  |  |             #warn("RES: %s" % (self.autoDerefPointers and not isHandled)) | 
					
						
							|  |  |  |             if self.autoDerefPointers and not isHandled: | 
					
						
							|  |  |  |                 ## Generic pointer type. | 
					
						
							| 
									
										
										
										
											2010-01-05 17:05:13 +01:00
										 |  |  |                 #warn("GENERIC AUTODEREF POINTER: %s" % value.address) | 
					
						
							| 
									
										
										
										
											2010-01-05 10:48:14 +01:00
										 |  |  |                 innerType = item.value.type.target() | 
					
						
							|  |  |  |                 self.putType(innerType) | 
					
						
							|  |  |  |                 self.childTypes.append( | 
					
						
							|  |  |  |                     stripClassTag(str(innerType))) | 
					
						
							|  |  |  |                 self.putItemHelper( | 
					
						
							|  |  |  |                     Item(item.value.dereference(), item.iname, None, None)) | 
					
						
							|  |  |  |                 self.childTypes.pop() | 
					
						
							|  |  |  |                 isHandled = True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # Fall back to plain pointer printing | 
					
						
							|  |  |  |             if not isHandled: | 
					
						
							| 
									
										
										
										
											2010-01-07 13:02:19 +01:00
										 |  |  |                 #warn("GENERIC PLAIN POINTER: %s" % value.type) | 
					
						
							| 
									
										
										
										
											2009-12-07 11:35:43 +01:00
										 |  |  |                 self.putType(item.value.type) | 
					
						
							|  |  |  |                 self.putValue(str(value.address)) | 
					
						
							|  |  |  |                 self.putNumChild(1) | 
					
						
							|  |  |  |                 if self.isExpanded(item): | 
					
						
							|  |  |  |                     self.beginChildren() | 
					
						
							|  |  |  |                     self.putItem( | 
					
						
							|  |  |  |                           Item(item.value.dereference(), item.iname, "*", "*")) | 
					
						
							|  |  |  |                     self.endChildren() | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         else: | 
					
						
							| 
									
										
										
										
											2010-01-07 13:02:19 +01:00
										 |  |  |             #warn("GENERIC STRUCT: %s" % value.type) | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  |             #warn("INAME: %s " % item.iname) | 
					
						
							|  |  |  |             #warn("INAMES: %s " % self.expandedINames) | 
					
						
							| 
									
										
										
										
											2009-12-04 11:24:15 +01:00
										 |  |  |             #warn("EXPANDED: %s " % (item.iname in self.expandedINames)) | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |             # insufficient, see http://sourceware.org/bugzilla/show_bug.cgi?id=10953 | 
					
						
							|  |  |  |             #fields = value.type.fields() | 
					
						
							|  |  |  |             fields = value.type.strip_typedefs().fields() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-07 11:35:43 +01:00
										 |  |  |             self.putType(item.value.type) | 
					
						
							| 
									
										
										
										
											2009-12-03 13:58:14 +01:00
										 |  |  |             self.putValue("{...}") | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |             if False: | 
					
						
							|  |  |  |                 numfields = 0 | 
					
						
							|  |  |  |                 for field in fields: | 
					
						
							|  |  |  |                     bitpos = getattr(field, "bitpos", None) | 
					
						
							|  |  |  |                     if not bitpos is None: | 
					
						
							|  |  |  |                         ++numfields | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 numfields = len(fields) | 
					
						
							|  |  |  |             self.putNumChild(numfields) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if self.isExpanded(item): | 
					
						
							|  |  |  |                 innerType = None | 
					
						
							|  |  |  |                 if len(fields) == 1 and fields[0].name is None: | 
					
						
							|  |  |  |                     innerType = value.type.target() | 
					
						
							| 
									
										
										
										
											2009-11-27 13:52:29 +01:00
										 |  |  |                 self.beginChildren(1, innerType) | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-04 11:24:15 +01:00
										 |  |  |                 baseNumber = 0 | 
					
						
							| 
									
										
										
										
											2010-01-07 14:41:12 +01:00
										 |  |  |                 anonNumber = 0 | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  |                 for field in fields: | 
					
						
							|  |  |  |                     #warn("FIELD: %s" % field) | 
					
						
							|  |  |  |                     #warn("  BITSIZE: %s" % field.bitsize) | 
					
						
							|  |  |  |                     #warn("  ARTIFICIAL: %s" % field.artificial) | 
					
						
							|  |  |  |                     bitpos = getattr(field, "bitpos", None) | 
					
						
							|  |  |  |                     if bitpos is None: # FIXME: Is check correct? | 
					
						
							|  |  |  |                         continue  # A static class member(?). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     if field.name is None: | 
					
						
							|  |  |  |                         innerType = value.type.target() | 
					
						
							|  |  |  |                         p = value.cast(innerType.pointer()) | 
					
						
							| 
									
										
										
										
											2009-12-10 17:45:13 +01:00
										 |  |  |                         for i in xrange(value.type.sizeof / innerType.sizeof): | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  |                             self.putItem(Item(p.dereference(), item.iname, i, None)) | 
					
						
							|  |  |  |                             p = p + 1 | 
					
						
							|  |  |  |                         continue | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     # ignore vtable pointers for virtual inheritance | 
					
						
							|  |  |  |                     if field.name.startswith("_vptr."): | 
					
						
							|  |  |  |                         continue | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     #warn("FIELD NAME: %s" % field.name) | 
					
						
							|  |  |  |                     #warn("FIELD TYPE: %s" % field.type) | 
					
						
							|  |  |  |                     if field.name == stripClassTag(str(field.type)): | 
					
						
							| 
									
										
										
										
											2009-12-04 11:24:15 +01:00
										 |  |  |                         # Field is base type. We cannot use field.name as part | 
					
						
							|  |  |  |                         # of the iname as it might contain spaces and other | 
					
						
							|  |  |  |                         # strange characters. | 
					
						
							|  |  |  |                         child = Item(value.cast(field.type), | 
					
						
							|  |  |  |                             item.iname, "@%d" % baseNumber, field.name) | 
					
						
							|  |  |  |                         baseNumber += 1 | 
					
						
							|  |  |  |                         self.beginHash() | 
					
						
							|  |  |  |                         self.putField("iname", child.iname) | 
					
						
							|  |  |  |                         self.safePutItemHelper(child) | 
					
						
							|  |  |  |                         self.endHash() | 
					
						
							| 
									
										
										
										
											2010-01-07 14:41:12 +01:00
										 |  |  |                     elif field.name == "": | 
					
						
							|  |  |  |                         # Anonymous union. We need a dummy name to distinguish | 
					
						
							|  |  |  |                         # multiple anonymous unions in the struct. | 
					
						
							|  |  |  |                         iname = "%s.#%d" % (item.iname, anonNumber) | 
					
						
							|  |  |  |                         anonNumber += 1 | 
					
						
							|  |  |  |                         self.beginHash() | 
					
						
							|  |  |  |                         self.putField("iname", iname) | 
					
						
							|  |  |  |                         self.putField("name", "<n/a>") | 
					
						
							|  |  |  |                         self.putField("value", " ") | 
					
						
							|  |  |  |                         self.putField("type", "<anonymous union>") | 
					
						
							|  |  |  |                         if self.isExpandedIName(iname): | 
					
						
							|  |  |  |                             self.beginChildren() | 
					
						
							|  |  |  |                             for f in field.type.fields(): | 
					
						
							|  |  |  |                                 child = Item(item.value[f.name], | 
					
						
							|  |  |  |                                     item.iname, f.name, f.name) | 
					
						
							|  |  |  |                                 self.safePutItem(child) | 
					
						
							|  |  |  |                             self.endChildren() | 
					
						
							|  |  |  |                         self.endHash() | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  |                     else: | 
					
						
							| 
									
										
										
										
											2010-01-07 14:41:12 +01:00
										 |  |  |                         # Named field. | 
					
						
							|  |  |  |                         self.beginHash() | 
					
						
							| 
									
										
										
										
											2009-12-04 11:24:15 +01:00
										 |  |  |                         child = Item(value[field.name], | 
					
						
							|  |  |  |                             item.iname, field.name, field.name) | 
					
						
							|  |  |  |                         self.safePutItemHelper(child) | 
					
						
							|  |  |  |                         self.endHash() | 
					
						
							| 
									
										
										
										
											2010-01-07 14:41:12 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-26 15:11:59 +01:00
										 |  |  |                 self.endChildren() |