| 
									
										
										
										
											2016-01-15 14:53:55 +01:00
										 |  |  | ############################################################################ | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # Copyright (C) 2016 The Qt Company Ltd. | 
					
						
							|  |  |  | # Contact: https://www.qt.io/licensing/ | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # This file is part of Qt Creator. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # Commercial License Usage | 
					
						
							|  |  |  | # Licensees holding valid commercial Qt licenses may use this file in | 
					
						
							|  |  |  | # accordance with the commercial license agreement provided with the | 
					
						
							|  |  |  | # Software or, alternatively, in accordance with the terms contained in | 
					
						
							|  |  |  | # a written agreement between you and The Qt Company. For licensing terms | 
					
						
							|  |  |  | # and conditions see https://www.qt.io/terms-conditions. For further | 
					
						
							|  |  |  | # information use the contact form at https://www.qt.io/contact-us. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # GNU General Public License Usage | 
					
						
							|  |  |  | # Alternatively, this file may be used under the terms of the GNU | 
					
						
							|  |  |  | # General Public License version 3 as published by the Free Software | 
					
						
							|  |  |  | # Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT | 
					
						
							|  |  |  | # included in the packaging of this file. Please review the following | 
					
						
							|  |  |  | # information to ensure the GNU General Public License requirements will | 
					
						
							|  |  |  | # be met: https://www.gnu.org/licenses/gpl-3.0.html. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | ############################################################################ | 
					
						
							| 
									
										
										
										
											2013-04-11 18:11:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  | try: | 
					
						
							|  |  |  |     import __builtin__ | 
					
						
							|  |  |  | except: | 
					
						
							|  |  |  |     import builtins | 
					
						
							|  |  |  | try: | 
					
						
							|  |  |  |     import gdb | 
					
						
							|  |  |  | except: | 
					
						
							|  |  |  |     pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-11 18:11:54 +02:00
										 |  |  | import os | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  | import os.path | 
					
						
							| 
									
										
										
										
											2013-04-12 16:58:25 +02:00
										 |  |  | import sys | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  | import struct | 
					
						
							| 
									
										
										
										
											2014-10-14 21:13:22 +02:00
										 |  |  | import types | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | from dumper import * | 
					
						
							| 
									
										
										
										
											2014-10-14 21:13:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-10 13:55:15 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | ####################################################################### | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # Infrastructure | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | ####################################################################### | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-25 09:10:25 +02:00
										 |  |  | def safePrint(output): | 
					
						
							| 
									
										
										
										
											2013-04-10 13:55:15 +02:00
										 |  |  |     try: | 
					
						
							|  |  |  |         print(output) | 
					
						
							|  |  |  |     except: | 
					
						
							|  |  |  |         out = "" | 
					
						
							|  |  |  |         for c in output: | 
					
						
							|  |  |  |             cc = ord(c) | 
					
						
							|  |  |  |             if cc > 127: | 
					
						
							|  |  |  |                 out += "\\\\%d" % cc | 
					
						
							|  |  |  |             elif cc < 0: | 
					
						
							|  |  |  |                 out += "\\\\%d" % (cc + 256) | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 out += c | 
					
						
							|  |  |  |         print(out) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def registerCommand(name, func): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     class Command(gdb.Command): | 
					
						
							|  |  |  |         def __init__(self): | 
					
						
							|  |  |  |             super(Command, self).__init__(name, gdb.COMMAND_OBSCURE) | 
					
						
							|  |  |  |         def invoke(self, args, from_tty): | 
					
						
							| 
									
										
										
										
											2015-06-25 09:10:25 +02:00
										 |  |  |             safePrint(func(args)) | 
					
						
							| 
									
										
										
										
											2013-04-10 13:55:15 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Command() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ####################################################################### | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # Types | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | ####################################################################### | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PointerCode = gdb.TYPE_CODE_PTR | 
					
						
							|  |  |  | ArrayCode = gdb.TYPE_CODE_ARRAY | 
					
						
							|  |  |  | StructCode = gdb.TYPE_CODE_STRUCT | 
					
						
							|  |  |  | UnionCode = gdb.TYPE_CODE_UNION | 
					
						
							|  |  |  | EnumCode = gdb.TYPE_CODE_ENUM | 
					
						
							|  |  |  | FlagsCode = gdb.TYPE_CODE_FLAGS | 
					
						
							|  |  |  | FunctionCode = gdb.TYPE_CODE_FUNC | 
					
						
							|  |  |  | IntCode = gdb.TYPE_CODE_INT | 
					
						
							|  |  |  | FloatCode = gdb.TYPE_CODE_FLT # Parts of GDB assume that this means complex. | 
					
						
							|  |  |  | VoidCode = gdb.TYPE_CODE_VOID | 
					
						
							|  |  |  | #SetCode = gdb.TYPE_CODE_SET | 
					
						
							|  |  |  | RangeCode = gdb.TYPE_CODE_RANGE | 
					
						
							|  |  |  | StringCode = gdb.TYPE_CODE_STRING | 
					
						
							|  |  |  | #BitStringCode = gdb.TYPE_CODE_BITSTRING | 
					
						
							|  |  |  | #ErrorTypeCode = gdb.TYPE_CODE_ERROR | 
					
						
							|  |  |  | MethodCode = gdb.TYPE_CODE_METHOD | 
					
						
							|  |  |  | MethodPointerCode = gdb.TYPE_CODE_METHODPTR | 
					
						
							|  |  |  | MemberPointerCode = gdb.TYPE_CODE_MEMBERPTR | 
					
						
							|  |  |  | ReferenceCode = gdb.TYPE_CODE_REF | 
					
						
							|  |  |  | CharCode = gdb.TYPE_CODE_CHAR | 
					
						
							|  |  |  | BoolCode = gdb.TYPE_CODE_BOOL | 
					
						
							|  |  |  | ComplexCode = gdb.TYPE_CODE_COMPLEX | 
					
						
							|  |  |  | TypedefCode = gdb.TYPE_CODE_TYPEDEF | 
					
						
							|  |  |  | NamespaceCode = gdb.TYPE_CODE_NAMESPACE | 
					
						
							|  |  |  | #Code = gdb.TYPE_CODE_DECFLOAT # Decimal floating point. | 
					
						
							|  |  |  | #Code = gdb.TYPE_CODE_MODULE # Fortran | 
					
						
							|  |  |  | #Code = gdb.TYPE_CODE_INTERNAL_FUNCTION | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ####################################################################### | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # Convenience | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | ####################################################################### | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Just convienience for 'python print ...' | 
					
						
							|  |  |  | class PPCommand(gdb.Command): | 
					
						
							|  |  |  |     def __init__(self): | 
					
						
							|  |  |  |         super(PPCommand, self).__init__("pp", gdb.COMMAND_OBSCURE) | 
					
						
							|  |  |  |     def invoke(self, args, from_tty): | 
					
						
							|  |  |  |         print(eval(args)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PPCommand() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Just convienience for 'python print gdb.parse_and_eval(...)' | 
					
						
							|  |  |  | class PPPCommand(gdb.Command): | 
					
						
							|  |  |  |     def __init__(self): | 
					
						
							|  |  |  |         super(PPPCommand, self).__init__("ppp", gdb.COMMAND_OBSCURE) | 
					
						
							|  |  |  |     def invoke(self, args, from_tty): | 
					
						
							|  |  |  |         print(gdb.parse_and_eval(args)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PPPCommand() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def scanStack(p, n): | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |     p = int(p) | 
					
						
							| 
									
										
										
										
											2013-04-10 13:55:15 +02:00
										 |  |  |     r = [] | 
					
						
							|  |  |  |     for i in xrange(n): | 
					
						
							|  |  |  |         f = gdb.parse_and_eval("{void*}%s" % p) | 
					
						
							|  |  |  |         m = gdb.execute("info symbol %s" % f, to_string=True) | 
					
						
							|  |  |  |         if not m.startswith("No symbol matches"): | 
					
						
							|  |  |  |             r.append(m) | 
					
						
							|  |  |  |         p += f.type.sizeof | 
					
						
							|  |  |  |     return r | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ScanStackCommand(gdb.Command): | 
					
						
							|  |  |  |     def __init__(self): | 
					
						
							|  |  |  |         super(ScanStackCommand, self).__init__("scanStack", gdb.COMMAND_OBSCURE) | 
					
						
							|  |  |  |     def invoke(self, args, from_tty): | 
					
						
							|  |  |  |         if len(args) == 0: | 
					
						
							|  |  |  |             args = 20 | 
					
						
							| 
									
										
										
										
											2015-06-25 09:10:25 +02:00
										 |  |  |         safePrint(scanStack(gdb.parse_and_eval("$sp"), int(args))) | 
					
						
							| 
									
										
										
										
											2013-04-10 13:55:15 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | ScanStackCommand() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-11 18:11:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-12 16:58:25 +02:00
										 |  |  | ####################################################################### | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # Import plain gdb pretty printers | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | ####################################################################### | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class PlainDumper: | 
					
						
							|  |  |  |     def __init__(self, printer): | 
					
						
							|  |  |  |         self.printer = printer | 
					
						
							| 
									
										
										
										
											2015-07-10 10:09:34 +02:00
										 |  |  |         self.typeCache = {} | 
					
						
							| 
									
										
										
										
											2013-04-12 16:58:25 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def __call__(self, d, value): | 
					
						
							| 
									
										
										
										
											2014-01-07 15:19:09 +01:00
										 |  |  |         printer = self.printer.invoke(value) | 
					
						
							| 
									
										
										
										
											2013-04-12 16:58:25 +02:00
										 |  |  |         lister = getattr(printer, "children", None) | 
					
						
							|  |  |  |         children = [] if lister is None else list(lister()) | 
					
						
							|  |  |  |         d.putType(self.printer.name) | 
					
						
							| 
									
										
										
										
											2015-01-14 15:00:09 +01:00
										 |  |  |         val = printer.to_string() | 
					
						
							|  |  |  |         if isinstance(val, str): | 
					
						
							|  |  |  |             d.putValue(val) | 
					
						
							|  |  |  |         else: # Assuming LazyString | 
					
						
							| 
									
										
										
										
											2015-08-12 09:05:28 +02:00
										 |  |  |             d.putCharArrayHelper(val.address, val.length, val.type.sizeof) | 
					
						
							| 
									
										
										
										
											2015-01-14 15:00:09 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-12 16:58:25 +02:00
										 |  |  |         d.putNumChild(len(children)) | 
					
						
							|  |  |  |         if d.isExpanded(): | 
					
						
							|  |  |  |             with Children(d): | 
					
						
							|  |  |  |                 for child in children: | 
					
						
							|  |  |  |                     d.putSubItem(child[0], child[1]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def importPlainDumpers(args): | 
					
						
							| 
									
										
										
										
											2015-01-25 01:36:08 +01:00
										 |  |  |     if args == "off": | 
					
						
							|  |  |  |         gdb.execute("disable pretty-printer .* .*") | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         theDumper.importPlainDumpers() | 
					
						
							| 
									
										
										
										
											2013-04-12 16:58:25 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | registerCommand("importPlainDumpers", importPlainDumpers) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | class OutputSafer: | 
					
						
							|  |  |  |     def __init__(self, d): | 
					
						
							|  |  |  |         self.d = d | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __enter__(self): | 
					
						
							|  |  |  |         self.savedOutput = self.d.output | 
					
						
							|  |  |  |         self.d.output = [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __exit__(self, exType, exValue, exTraceBack): | 
					
						
							|  |  |  |         if self.d.passExceptions and not exType is None: | 
					
						
							|  |  |  |             showException("OUTPUTSAFER", exType, exValue, exTraceBack) | 
					
						
							|  |  |  |             self.d.output = self.savedOutput | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.savedOutput.extend(self.d.output) | 
					
						
							|  |  |  |             self.d.output = self.savedOutput | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #def couldBePointer(p, align): | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  | #    typeobj = lookupType("unsigned int") | 
					
						
							|  |  |  | #    ptr = gdb.Value(p).cast(typeobj) | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  | #    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) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Value = gdb.Value | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-24 15:13:20 +01:00
										 |  |  | def stripTypedefs(typeobj): | 
					
						
							|  |  |  |     typeobj = typeobj.unqualified() | 
					
						
							|  |  |  |     while typeobj.code == TypedefCode: | 
					
						
							|  |  |  |         typeobj = typeobj.strip_typedefs().unqualified() | 
					
						
							|  |  |  |     return typeobj | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ####################################################################### | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # The Dumper Class | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | ####################################################################### | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  | class Dumper(DumperBase): | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-30 12:38:29 +01:00
										 |  |  |     def __init__(self): | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |         DumperBase.__init__(self) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |         # These values will be kept between calls to 'fetchVariables'. | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |         self.isGdb = True | 
					
						
							| 
									
										
										
										
											2015-07-10 10:09:34 +02:00
										 |  |  |         self.typeCache = {} | 
					
						
							| 
									
										
										
										
											2013-10-31 10:28:11 +01:00
										 |  |  |         self.typesReported = {} | 
					
						
							|  |  |  |         self.typesToReport = {} | 
					
						
							| 
									
										
										
										
											2014-02-27 12:54:20 +01:00
										 |  |  |         self.qtNamespaceToReport = None | 
					
						
							| 
									
										
										
										
											2015-10-09 15:00:20 +02:00
										 |  |  |         self.interpreterBreakpointResolvers = [] | 
					
						
							| 
									
										
										
										
											2013-10-30 12:38:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-02 16:01:43 +01:00
										 |  |  |         # The guess does not need to be updated during a fetchVariables() | 
					
						
							|  |  |  |         # as the result is fixed during that time (ignoring "active" | 
					
						
							|  |  |  |         # dumpers causing loading of shared objects etc). | 
					
						
							|  |  |  |         self.currentQtNamespaceGuess = None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												Debugger: Make dumpers somewhat work in command line GDB
With
    python sys.path.insert(1, '/data/dev/creator/share/qtcreator/debugger/')
    python from gdbbridge import *
in .gdbinit there's a new "GDB command", called "pp".
With code like
    int main(int argc, char *argv[])
    {
        QString ss = "Hello";
        QApplication app(argc, argv);
        app.setObjectName(ss);
        // break here
    }
the 'pp' command can be used as follows:
(gdb) pp app
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = <Myns::QObjectList> = {"<3 items>"}
      [properties] = "<>0 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp app [properties],[children]
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = [
         <Myns::QObject> = {""}
         <Myns::QObject> = {""}
         <Myns::QObject> = {"fusion"}
      ],<Myns::QObjectList> = {"<3 items>"}
      [properties] = [
         windowIcon = <Myns::QVariant (QIcon)> = {""}
         cursorFlashTime = <Myns::QVariant (int)> = {"1000"}
         doubleClickInterval = <Myns::QVariant (int)> = {"400"}
         keyboardInputInterval = <Myns::QVariant (int)> = {"400"}
         wheelScrollLines = <Myns::QVariant (int)> = {"3"}
         globalStrut = <Myns::QVariant (QSize)> = {"(0, 0)"}
         startDragTime = <Myns::QVariant (int)> = {"500"}
         startDragDistance = <Myns::QVariant (int)> = {"10"}
         styleSheet = <Myns::QVariant (QString)> = {""}
         autoSipEnabled = <Myns::QVariant (bool)> = {"true"}
      ],"<10 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp ss
ss =
   <Myns::QString> = {"Hello"}
Change-Id: I6e4714a5cfe34c38917500d114ad9a70d20cff39
Reviewed-by: Christian Stenger <christian.stenger@digia.com>
Reviewed-by: hjk <hjk121@nokiamail.com>
											
										 
											2014-06-13 17:45:34 +02:00
										 |  |  |     def prepare(self, args): | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |         self.output = [] | 
					
						
							|  |  |  |         self.currentIName = "" | 
					
						
							|  |  |  |         self.currentPrintsAddress = True | 
					
						
							|  |  |  |         self.currentChildType = "" | 
					
						
							|  |  |  |         self.currentChildNumChild = -1 | 
					
						
							|  |  |  |         self.currentMaxNumChild = -1 | 
					
						
							|  |  |  |         self.currentNumChild = -1 | 
					
						
							| 
									
										
										
										
											2014-05-16 00:18:17 +02:00
										 |  |  |         self.currentValue = ReportItem() | 
					
						
							|  |  |  |         self.currentType = ReportItem() | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |         self.currentAddress = None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-11 17:51:15 +01:00
										 |  |  |         self.resultVarName = args.get("resultvarname", "") | 
					
						
							|  |  |  |         self.expandedINames = set(args.get("expanded", [])) | 
					
						
							|  |  |  |         self.stringCutOff = int(args.get("stringcutoff", 10000)) | 
					
						
							| 
									
										
										
										
											2015-02-12 11:31:02 +01:00
										 |  |  |         self.displayStringLimit = int(args.get("displaystringlimit", 100)) | 
					
						
							|  |  |  |         self.typeformats = args.get("typeformats", {}) | 
					
						
							|  |  |  |         self.formats = args.get("formats", {}) | 
					
						
							| 
									
										
										
										
											2015-02-11 17:51:15 +01:00
										 |  |  |         self.watchers = args.get("watchers", {}) | 
					
						
							|  |  |  |         self.useDynamicType = int(args.get("dyntype", "0")) | 
					
						
							|  |  |  |         self.useFancy = int(args.get("fancy", "0")) | 
					
						
							|  |  |  |         self.forceQtNamespace = int(args.get("forcens", "0")) | 
					
						
							| 
									
										
										
										
											2015-10-27 15:50:41 +01:00
										 |  |  |         self.passExceptions = int(args.get("passexceptions", "0")) | 
					
						
							| 
									
										
										
										
											2015-12-16 14:13:44 +01:00
										 |  |  |         self.showQObjectNames = int(args.get("qobjectnames", "0")) | 
					
						
							| 
									
										
										
										
											2015-02-11 17:51:15 +01:00
										 |  |  |         self.nativeMixed = int(args.get("nativemixed", "0")) | 
					
						
							|  |  |  |         self.autoDerefPointers = int(args.get("autoderef", "0")) | 
					
						
							|  |  |  |         self.partialUpdate = int(args.get("partial", "0")) | 
					
						
							| 
									
										
										
										
											2014-03-07 15:48:13 +01:00
										 |  |  |         self.fallbackQtVersion = 0x50200 | 
					
						
							| 
									
										
										
										
											2015-10-27 15:50:41 +01:00
										 |  |  |         self.sortStructMembers = bool(args.get("sortstructs", True)) | 
					
						
							| 
									
										
										
										
											2015-05-29 08:23:52 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-30 15:07:54 +01:00
										 |  |  |         #warn("NAMESPACE: '%s'" % self.qtNamespace()) | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |         #warn("EXPANDED INAMES: %s" % self.expandedINames) | 
					
						
							| 
									
										
											  
											
												Debugger: Make dumpers somewhat work in command line GDB
With
    python sys.path.insert(1, '/data/dev/creator/share/qtcreator/debugger/')
    python from gdbbridge import *
in .gdbinit there's a new "GDB command", called "pp".
With code like
    int main(int argc, char *argv[])
    {
        QString ss = "Hello";
        QApplication app(argc, argv);
        app.setObjectName(ss);
        // break here
    }
the 'pp' command can be used as follows:
(gdb) pp app
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = <Myns::QObjectList> = {"<3 items>"}
      [properties] = "<>0 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp app [properties],[children]
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = [
         <Myns::QObject> = {""}
         <Myns::QObject> = {""}
         <Myns::QObject> = {"fusion"}
      ],<Myns::QObjectList> = {"<3 items>"}
      [properties] = [
         windowIcon = <Myns::QVariant (QIcon)> = {""}
         cursorFlashTime = <Myns::QVariant (int)> = {"1000"}
         doubleClickInterval = <Myns::QVariant (int)> = {"400"}
         keyboardInputInterval = <Myns::QVariant (int)> = {"400"}
         wheelScrollLines = <Myns::QVariant (int)> = {"3"}
         globalStrut = <Myns::QVariant (QSize)> = {"(0, 0)"}
         startDragTime = <Myns::QVariant (int)> = {"500"}
         startDragDistance = <Myns::QVariant (int)> = {"10"}
         styleSheet = <Myns::QVariant (QString)> = {""}
         autoSipEnabled = <Myns::QVariant (bool)> = {"true"}
      ],"<10 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp ss
ss =
   <Myns::QString> = {"Hello"}
Change-Id: I6e4714a5cfe34c38917500d114ad9a70d20cff39
Reviewed-by: Christian Stenger <christian.stenger@digia.com>
Reviewed-by: hjk <hjk121@nokiamail.com>
											
										 
											2014-06-13 17:45:34 +02:00
										 |  |  |         #warn("WATCHERS: %s" % self.watchers) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-12 10:12:18 +01:00
										 |  |  |     def listOfLocals(self): | 
					
						
							|  |  |  |         frame = gdb.selected_frame() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             block = frame.block() | 
					
						
							|  |  |  |             #warn("BLOCK: %s " % block) | 
					
						
							|  |  |  |         except RuntimeError as error: | 
					
						
							|  |  |  |             #warn("BLOCK IN FRAME NOT ACCESSIBLE: %s" % error) | 
					
						
							|  |  |  |             return [] | 
					
						
							|  |  |  |         except: | 
					
						
							|  |  |  |             warn("BLOCK NOT ACCESSIBLE FOR UNKNOWN REASONS") | 
					
						
							|  |  |  |             return [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         items = [] | 
					
						
							|  |  |  |         shadowed = {} | 
					
						
							|  |  |  |         while True: | 
					
						
							|  |  |  |             if block is None: | 
					
						
							|  |  |  |                 warn("UNEXPECTED 'None' BLOCK") | 
					
						
							|  |  |  |                 break | 
					
						
							|  |  |  |             for symbol in block: | 
					
						
							| 
									
										
										
										
											2015-10-08 16:05:29 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |               # Filter out labels etc. | 
					
						
							|  |  |  |               if symbol.is_variable or symbol.is_argument: | 
					
						
							| 
									
										
										
										
											2014-12-12 10:12:18 +01:00
										 |  |  |                 name = symbol.print_name | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if name == "__in_chrg" or name == "__PRETTY_FUNCTION__": | 
					
						
							|  |  |  |                     continue | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 # "NotImplementedError: Symbol type not yet supported in | 
					
						
							|  |  |  |                 # Python scripts." | 
					
						
							|  |  |  |                 #warn("SYMBOL %s  (%s): " % (symbol, name)) | 
					
						
							|  |  |  |                 if name in shadowed: | 
					
						
							|  |  |  |                     level = shadowed[name] | 
					
						
							|  |  |  |                     name1 = "%s@%s" % (name, level) | 
					
						
							|  |  |  |                     shadowed[name] = level + 1 | 
					
						
							|  |  |  |                 else: | 
					
						
							|  |  |  |                     name1 = name | 
					
						
							|  |  |  |                     shadowed[name] = 1 | 
					
						
							|  |  |  |                 #warn("SYMBOL %s  (%s, %s)): " % (symbol, name, symbol.name)) | 
					
						
							| 
									
										
										
										
											2015-02-05 12:51:25 +01:00
										 |  |  |                 item = self.LocalItem() | 
					
						
							| 
									
										
										
										
											2014-12-12 10:12:18 +01:00
										 |  |  |                 item.iname = "local." + name1 | 
					
						
							|  |  |  |                 item.name = name1 | 
					
						
							|  |  |  |                 try: | 
					
						
							|  |  |  |                     item.value = frame.read_var(name, block) | 
					
						
							|  |  |  |                     #warn("READ 1: %s" % item.value) | 
					
						
							|  |  |  |                     items.append(item) | 
					
						
							|  |  |  |                     continue | 
					
						
							|  |  |  |                 except: | 
					
						
							|  |  |  |                     pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 try: | 
					
						
							|  |  |  |                     #warn("READ 2: %s" % item.value) | 
					
						
							|  |  |  |                     item.value = frame.read_var(name) | 
					
						
							|  |  |  |                     items.append(item) | 
					
						
							|  |  |  |                     continue | 
					
						
							|  |  |  |                 except: | 
					
						
							|  |  |  |                     # RuntimeError: happens for | 
					
						
							|  |  |  |                     #     void foo() { std::string s; std::wstring w; } | 
					
						
							|  |  |  |                     # ValueError: happens for (as of 2010/11/4) | 
					
						
							|  |  |  |                     #     a local struct as found e.g. in | 
					
						
							|  |  |  |                     #     gcc sources in gcc.c, int execute() | 
					
						
							|  |  |  |                     pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 try: | 
					
						
							|  |  |  |                     #warn("READ 3: %s %s" % (name, item.value)) | 
					
						
							|  |  |  |                     item.value = gdb.parse_and_eval(name) | 
					
						
							|  |  |  |                     #warn("ITEM 3: %s" % item.value) | 
					
						
							|  |  |  |                     items.append(item) | 
					
						
							|  |  |  |                 except: | 
					
						
							|  |  |  |                     # Can happen in inlined code (see last line of | 
					
						
							|  |  |  |                     # RowPainter::paintChars(): "RuntimeError: | 
					
						
							|  |  |  |                     # No symbol \"__val\" in current context.\n" | 
					
						
							|  |  |  |                     pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # 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 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return items | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-15 12:38:11 +02:00
										 |  |  |     # Hack to avoid QDate* dumper timeouts with GDB 7.4 on 32 bit | 
					
						
							|  |  |  |     # due to misaligned %ebx in SSE calls (qstring.cpp:findChar) | 
					
						
							|  |  |  |     # This seems to be fixed in 7.9 (or earlier) | 
					
						
							|  |  |  |     def canCallLocale(self): | 
					
						
							|  |  |  |         return False if self.is32bit() else True | 
					
						
							| 
									
										
										
										
											2014-12-12 10:12:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-16 17:17:38 +01:00
										 |  |  |     def reportTime(self, hint): | 
					
						
							|  |  |  |         #from datetime import datetime | 
					
						
							|  |  |  |         #warn("%s: %s" % (hint, datetime.now().time().isoformat())) | 
					
						
							|  |  |  |         pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |     def fetchVariables(self, args): | 
					
						
							| 
									
										
										
										
											2015-12-16 17:17:38 +01:00
										 |  |  |         self.reportTime("begin fetch") | 
					
						
							| 
									
										
											  
											
												Debugger: Make dumpers somewhat work in command line GDB
With
    python sys.path.insert(1, '/data/dev/creator/share/qtcreator/debugger/')
    python from gdbbridge import *
in .gdbinit there's a new "GDB command", called "pp".
With code like
    int main(int argc, char *argv[])
    {
        QString ss = "Hello";
        QApplication app(argc, argv);
        app.setObjectName(ss);
        // break here
    }
the 'pp' command can be used as follows:
(gdb) pp app
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = <Myns::QObjectList> = {"<3 items>"}
      [properties] = "<>0 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp app [properties],[children]
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = [
         <Myns::QObject> = {""}
         <Myns::QObject> = {""}
         <Myns::QObject> = {"fusion"}
      ],<Myns::QObjectList> = {"<3 items>"}
      [properties] = [
         windowIcon = <Myns::QVariant (QIcon)> = {""}
         cursorFlashTime = <Myns::QVariant (int)> = {"1000"}
         doubleClickInterval = <Myns::QVariant (int)> = {"400"}
         keyboardInputInterval = <Myns::QVariant (int)> = {"400"}
         wheelScrollLines = <Myns::QVariant (int)> = {"3"}
         globalStrut = <Myns::QVariant (QSize)> = {"(0, 0)"}
         startDragTime = <Myns::QVariant (int)> = {"500"}
         startDragDistance = <Myns::QVariant (int)> = {"10"}
         styleSheet = <Myns::QVariant (QString)> = {""}
         autoSipEnabled = <Myns::QVariant (bool)> = {"true"}
      ],"<10 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp ss
ss =
   <Myns::QString> = {"Hello"}
Change-Id: I6e4714a5cfe34c38917500d114ad9a70d20cff39
Reviewed-by: Christian Stenger <christian.stenger@digia.com>
Reviewed-by: hjk <hjk121@nokiamail.com>
											
										 
											2014-06-13 17:45:34 +02:00
										 |  |  |         self.prepare(args) | 
					
						
							| 
									
										
										
										
											2015-10-27 15:50:41 +01:00
										 |  |  |         partialVariable = args.get("partialvar", "") | 
					
						
							| 
									
										
										
										
											2015-03-26 13:03:38 +01:00
										 |  |  |         isPartial = len(partialVariable) > 0 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-09 15:00:20 +02:00
										 |  |  |         (ok, res) = self.tryFetchInterpreterVariables(args) | 
					
						
							|  |  |  |         if ok: | 
					
						
							|  |  |  |             safePrint(res) | 
					
						
							|  |  |  |             return | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |         # | 
					
						
							|  |  |  |         # Locals | 
					
						
							|  |  |  |         # | 
					
						
							| 
									
										
											  
											
												Debugger: Make dumpers somewhat work in command line GDB
With
    python sys.path.insert(1, '/data/dev/creator/share/qtcreator/debugger/')
    python from gdbbridge import *
in .gdbinit there's a new "GDB command", called "pp".
With code like
    int main(int argc, char *argv[])
    {
        QString ss = "Hello";
        QApplication app(argc, argv);
        app.setObjectName(ss);
        // break here
    }
the 'pp' command can be used as follows:
(gdb) pp app
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = <Myns::QObjectList> = {"<3 items>"}
      [properties] = "<>0 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp app [properties],[children]
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = [
         <Myns::QObject> = {""}
         <Myns::QObject> = {""}
         <Myns::QObject> = {"fusion"}
      ],<Myns::QObjectList> = {"<3 items>"}
      [properties] = [
         windowIcon = <Myns::QVariant (QIcon)> = {""}
         cursorFlashTime = <Myns::QVariant (int)> = {"1000"}
         doubleClickInterval = <Myns::QVariant (int)> = {"400"}
         keyboardInputInterval = <Myns::QVariant (int)> = {"400"}
         wheelScrollLines = <Myns::QVariant (int)> = {"3"}
         globalStrut = <Myns::QVariant (QSize)> = {"(0, 0)"}
         startDragTime = <Myns::QVariant (int)> = {"500"}
         startDragDistance = <Myns::QVariant (int)> = {"10"}
         styleSheet = <Myns::QVariant (QString)> = {""}
         autoSipEnabled = <Myns::QVariant (bool)> = {"true"}
      ],"<10 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp ss
ss =
   <Myns::QString> = {"Hello"}
Change-Id: I6e4714a5cfe34c38917500d114ad9a70d20cff39
Reviewed-by: Christian Stenger <christian.stenger@digia.com>
Reviewed-by: hjk <hjk121@nokiamail.com>
											
										 
											2014-06-13 17:45:34 +02:00
										 |  |  |         self.output.append('data=[') | 
					
						
							| 
									
										
										
										
											2015-02-05 12:51:25 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |         if isPartial: | 
					
						
							| 
									
										
										
										
											2015-03-26 13:03:38 +01:00
										 |  |  |             parts = partialVariable.split('.') | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |             name = parts[1] | 
					
						
							| 
									
										
										
										
											2015-02-05 12:51:25 +01:00
										 |  |  |             item = self.LocalItem() | 
					
						
							| 
									
										
										
										
											2014-11-13 15:15:11 +01:00
										 |  |  |             item.iname = parts[0] + '.' + name | 
					
						
							|  |  |  |             item.name = name | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |             try: | 
					
						
							| 
									
										
										
										
											2014-11-13 15:15:11 +01:00
										 |  |  |                 if parts[0] == 'local': | 
					
						
							|  |  |  |                     frame = gdb.selected_frame() | 
					
						
							|  |  |  |                     item.value = frame.read_var(name) | 
					
						
							|  |  |  |                 else: | 
					
						
							|  |  |  |                     item.name = self.hexdecode(name) | 
					
						
							|  |  |  |                     item.value = gdb.parse_and_eval(item.name) | 
					
						
							|  |  |  |             except RuntimeError as error: | 
					
						
							|  |  |  |                 item.value = error | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |             except: | 
					
						
							| 
									
										
										
										
											2014-11-13 15:15:11 +01:00
										 |  |  |                 item.value = "<no value>" | 
					
						
							|  |  |  |             locals = [item] | 
					
						
							|  |  |  |         else: | 
					
						
							| 
									
										
										
										
											2014-12-12 10:12:18 +01:00
										 |  |  |             locals = self.listOfLocals() | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-16 17:17:38 +01:00
										 |  |  |         self.reportTime("locals") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |         # Take care of the return value of the last function call. | 
					
						
							| 
									
										
											  
											
												Debugger: Make dumpers somewhat work in command line GDB
With
    python sys.path.insert(1, '/data/dev/creator/share/qtcreator/debugger/')
    python from gdbbridge import *
in .gdbinit there's a new "GDB command", called "pp".
With code like
    int main(int argc, char *argv[])
    {
        QString ss = "Hello";
        QApplication app(argc, argv);
        app.setObjectName(ss);
        // break here
    }
the 'pp' command can be used as follows:
(gdb) pp app
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = <Myns::QObjectList> = {"<3 items>"}
      [properties] = "<>0 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp app [properties],[children]
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = [
         <Myns::QObject> = {""}
         <Myns::QObject> = {""}
         <Myns::QObject> = {"fusion"}
      ],<Myns::QObjectList> = {"<3 items>"}
      [properties] = [
         windowIcon = <Myns::QVariant (QIcon)> = {""}
         cursorFlashTime = <Myns::QVariant (int)> = {"1000"}
         doubleClickInterval = <Myns::QVariant (int)> = {"400"}
         keyboardInputInterval = <Myns::QVariant (int)> = {"400"}
         wheelScrollLines = <Myns::QVariant (int)> = {"3"}
         globalStrut = <Myns::QVariant (QSize)> = {"(0, 0)"}
         startDragTime = <Myns::QVariant (int)> = {"500"}
         startDragDistance = <Myns::QVariant (int)> = {"10"}
         styleSheet = <Myns::QVariant (QString)> = {""}
         autoSipEnabled = <Myns::QVariant (bool)> = {"true"}
      ],"<10 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp ss
ss =
   <Myns::QString> = {"Hello"}
Change-Id: I6e4714a5cfe34c38917500d114ad9a70d20cff39
Reviewed-by: Christian Stenger <christian.stenger@digia.com>
Reviewed-by: hjk <hjk121@nokiamail.com>
											
										 
											2014-06-13 17:45:34 +02:00
										 |  |  |         if len(self.resultVarName) > 0: | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |             try: | 
					
						
							| 
									
										
										
										
											2015-02-05 12:51:25 +01:00
										 |  |  |                 item = self.LocalItem() | 
					
						
							| 
									
										
											  
											
												Debugger: Make dumpers somewhat work in command line GDB
With
    python sys.path.insert(1, '/data/dev/creator/share/qtcreator/debugger/')
    python from gdbbridge import *
in .gdbinit there's a new "GDB command", called "pp".
With code like
    int main(int argc, char *argv[])
    {
        QString ss = "Hello";
        QApplication app(argc, argv);
        app.setObjectName(ss);
        // break here
    }
the 'pp' command can be used as follows:
(gdb) pp app
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = <Myns::QObjectList> = {"<3 items>"}
      [properties] = "<>0 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp app [properties],[children]
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = [
         <Myns::QObject> = {""}
         <Myns::QObject> = {""}
         <Myns::QObject> = {"fusion"}
      ],<Myns::QObjectList> = {"<3 items>"}
      [properties] = [
         windowIcon = <Myns::QVariant (QIcon)> = {""}
         cursorFlashTime = <Myns::QVariant (int)> = {"1000"}
         doubleClickInterval = <Myns::QVariant (int)> = {"400"}
         keyboardInputInterval = <Myns::QVariant (int)> = {"400"}
         wheelScrollLines = <Myns::QVariant (int)> = {"3"}
         globalStrut = <Myns::QVariant (QSize)> = {"(0, 0)"}
         startDragTime = <Myns::QVariant (int)> = {"500"}
         startDragDistance = <Myns::QVariant (int)> = {"10"}
         styleSheet = <Myns::QVariant (QString)> = {""}
         autoSipEnabled = <Myns::QVariant (bool)> = {"true"}
      ],"<10 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp ss
ss =
   <Myns::QString> = {"Hello"}
Change-Id: I6e4714a5cfe34c38917500d114ad9a70d20cff39
Reviewed-by: Christian Stenger <christian.stenger@digia.com>
Reviewed-by: hjk <hjk121@nokiamail.com>
											
										 
											2014-06-13 17:45:34 +02:00
										 |  |  |                 item.name = self.resultVarName | 
					
						
							|  |  |  |                 item.iname = "return." + self.resultVarName | 
					
						
							|  |  |  |                 item.value = self.parseAndEvaluate(self.resultVarName) | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |                 locals.append(item) | 
					
						
							|  |  |  |             except: | 
					
						
							|  |  |  |                 # Don't bother. It's only supplementary information anyway. | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-29 08:23:52 +02:00
										 |  |  |         locals.sort(key = lambda item: item.name) | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |         for item in locals: | 
					
						
							| 
									
										
										
										
											2013-10-31 10:28:11 +01:00
										 |  |  |             value = self.downcast(item.value) if self.useDynamicType else item.value | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |             with OutputSafer(self): | 
					
						
							|  |  |  |                 self.anonNumber = -1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-04 14:48:40 +01:00
										 |  |  |                 if item.iname == "local.argv" and str(value.type) == "char **": | 
					
						
							|  |  |  |                     self.putSpecialArgv(value) | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |                 else: | 
					
						
							|  |  |  |                     # A "normal" local variable or parameter. | 
					
						
							|  |  |  |                     with TopLevelItem(self, item.iname): | 
					
						
							|  |  |  |                         self.put('iname="%s",' % item.iname) | 
					
						
							|  |  |  |                         self.put('name="%s",' % item.name) | 
					
						
							|  |  |  |                         self.putItem(value) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-26 13:03:38 +01:00
										 |  |  |         with OutputSafer(self): | 
					
						
							|  |  |  |             self.handleWatches(args) | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-31 10:28:11 +01:00
										 |  |  |         self.output.append('],typeinfo=[') | 
					
						
							|  |  |  |         for name in self.typesToReport.keys(): | 
					
						
							| 
									
										
										
										
											2014-01-24 15:13:20 +01:00
										 |  |  |             typeobj = self.typesToReport[name] | 
					
						
							| 
									
										
										
										
											2013-10-31 10:28:11 +01:00
										 |  |  |             # Happens e.g. for '(anonymous namespace)::InsertDefOperation' | 
					
						
							| 
									
										
										
										
											2014-01-24 15:13:20 +01:00
										 |  |  |             if not typeobj is None: | 
					
						
							| 
									
										
										
										
											2013-10-31 10:28:11 +01:00
										 |  |  |                 self.output.append('{name="%s",size="%s"}' | 
					
						
							| 
									
										
										
										
											2014-01-24 15:13:20 +01:00
										 |  |  |                     % (self.hexencode(name), typeobj.sizeof)) | 
					
						
							| 
									
										
										
										
											2013-10-31 10:28:11 +01:00
										 |  |  |         self.output.append(']') | 
					
						
							|  |  |  |         self.typesToReport = {} | 
					
						
							| 
									
										
										
										
											2014-01-24 15:13:20 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-11 17:51:15 +01:00
										 |  |  |         if self.forceQtNamespace: | 
					
						
							| 
									
										
										
										
											2014-07-24 13:22:19 +02:00
										 |  |  |             self.qtNamepaceToReport = self.qtNamespace() | 
					
						
							| 
									
										
										
										
											2014-03-07 15:48:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-27 12:54:20 +01:00
										 |  |  |         if self.qtNamespaceToReport: | 
					
						
							|  |  |  |             self.output.append(',qtnamespace="%s"' % self.qtNamespaceToReport) | 
					
						
							|  |  |  |             self.qtNamespaceToReport = None | 
					
						
							| 
									
										
										
										
											2015-03-26 13:03:38 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.output.append(',partial="%d"' % isPartial) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-16 17:17:38 +01:00
										 |  |  |         self.reportTime("before print: %s" % len(self.output)) | 
					
						
							| 
									
										
										
										
											2015-06-25 09:10:25 +02:00
										 |  |  |         safePrint(''.join(self.output)) | 
					
						
							| 
									
										
										
										
											2015-12-16 17:17:38 +01:00
										 |  |  |         self.reportTime("after print") | 
					
						
							| 
									
										
										
										
											2013-05-23 15:47:28 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |     def enterSubItem(self, item): | 
					
						
							|  |  |  |         if not item.iname: | 
					
						
							|  |  |  |             item.iname = "%s.%s" % (self.currentIName, item.name) | 
					
						
							|  |  |  |         #warn("INAME %s" % item.iname) | 
					
						
							|  |  |  |         self.put('{') | 
					
						
							|  |  |  |         #if not item.name is None: | 
					
						
							|  |  |  |         if isinstance(item.name, str): | 
					
						
							|  |  |  |             self.put('name="%s",' % item.name) | 
					
						
							|  |  |  |         item.savedIName = self.currentIName | 
					
						
							|  |  |  |         item.savedValue = self.currentValue | 
					
						
							|  |  |  |         item.savedType = self.currentType | 
					
						
							|  |  |  |         item.savedCurrentAddress = self.currentAddress | 
					
						
							|  |  |  |         self.currentIName = item.iname | 
					
						
							| 
									
										
										
										
											2014-05-16 00:18:17 +02:00
										 |  |  |         self.currentValue = ReportItem(); | 
					
						
							|  |  |  |         self.currentType = ReportItem(); | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |         self.currentAddress = None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def exitSubItem(self, item, exType, exValue, exTraceBack): | 
					
						
							| 
									
										
										
										
											2014-05-19 10:55:33 +02:00
										 |  |  |         #warn("CURRENT VALUE: %s: %s %s" % (self.currentIName, self.currentValue, self.currentType)) | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |         if not exType is None: | 
					
						
							|  |  |  |             if self.passExceptions: | 
					
						
							|  |  |  |                 showException("SUBITEM", exType, exValue, exTraceBack) | 
					
						
							|  |  |  |             self.putNumChild(0) | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |             self.putSpecialValue("notaccessible") | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |         try: | 
					
						
							| 
									
										
										
										
											2014-05-19 10:55:33 +02:00
										 |  |  |             if self.currentType.value: | 
					
						
							| 
									
										
										
										
											2014-09-12 13:31:12 +02:00
										 |  |  |                 typeName = self.stripClassTag(self.currentType.value) | 
					
						
							| 
									
										
										
										
											2014-05-19 10:55:33 +02:00
										 |  |  |                 if len(typeName) > 0 and typeName != self.currentChildType: | 
					
						
							|  |  |  |                     self.put('type="%s",' % typeName) # str(type.unqualified()) ? | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-16 00:18:17 +02:00
										 |  |  |             if  self.currentValue.value is None: | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |                 self.put('value="",encoding="notaccessible",numchild="0",') | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |             else: | 
					
						
							| 
									
										
										
										
											2014-05-16 00:18:17 +02:00
										 |  |  |                 if not self.currentValue.encoding is None: | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |                     self.put('valueencoded="%s",' % self.currentValue.encoding) | 
					
						
							| 
									
										
										
										
											2014-05-16 00:18:17 +02:00
										 |  |  |                 if self.currentValue.elided: | 
					
						
							|  |  |  |                     self.put('valueelided="%d",' % self.currentValue.elided) | 
					
						
							|  |  |  |                 self.put('value="%s",' % self.currentValue.value) | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |         except: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  |         if not self.currentAddress is None: | 
					
						
							|  |  |  |             self.put(self.currentAddress) | 
					
						
							|  |  |  |         self.put('},') | 
					
						
							|  |  |  |         self.currentIName = item.savedIName | 
					
						
							|  |  |  |         self.currentValue = item.savedValue | 
					
						
							|  |  |  |         self.currentType = item.savedType | 
					
						
							|  |  |  |         self.currentAddress = item.savedCurrentAddress | 
					
						
							|  |  |  |         return True | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-16 16:50:26 +02:00
										 |  |  |     def parseAndEvaluate(self, exp): | 
					
						
							|  |  |  |         return gdb.parse_and_eval(exp) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |     def callHelper(self, value, function, args): | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |         # args is a tuple. | 
					
						
							|  |  |  |         arg = "" | 
					
						
							|  |  |  |         for i in range(len(args)): | 
					
						
							|  |  |  |             if i: | 
					
						
							|  |  |  |                 arg += ',' | 
					
						
							|  |  |  |             a = args[i] | 
					
						
							|  |  |  |             if (':' in a) and not ("'" in a): | 
					
						
							|  |  |  |                 arg = "'%s'" % a | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 arg += a | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |         #warn("CALL: %s -> %s(%s)" % (value, function, arg)) | 
					
						
							| 
									
										
										
										
											2014-09-12 13:31:12 +02:00
										 |  |  |         typeName = self.stripClassTag(str(value.type)) | 
					
						
							| 
									
										
										
										
											2014-01-29 00:41:48 +01:00
										 |  |  |         if typeName.find(":") >= 0: | 
					
						
							|  |  |  |             typeName = "'" + typeName + "'" | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |         # 'class' is needed, see http://sourceware.org/bugzilla/show_bug.cgi?id=11912 | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |         #exp = "((class %s*)%s)->%s(%s)" % (typeName, value.address, function, arg) | 
					
						
							| 
									
										
										
										
											2014-01-29 00:41:48 +01:00
										 |  |  |         ptr = value.address if value.address else self.pokeValue(value) | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |         exp = "((%s*)%s)->%s(%s)" % (typeName, ptr, function, arg) | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |         #warn("CALL: %s" % exp) | 
					
						
							| 
									
										
										
										
											2014-01-29 00:41:48 +01:00
										 |  |  |         result = gdb.parse_and_eval(exp) | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |         #warn("  -> %s" % result) | 
					
						
							| 
									
										
										
										
											2014-01-29 00:41:48 +01:00
										 |  |  |         if not value.address: | 
					
						
							|  |  |  |             gdb.parse_and_eval("free(0x%x)" % ptr) | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |         return result | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-20 15:03:27 +01:00
										 |  |  |     def childWithName(self, value, name): | 
					
						
							| 
									
										
										
										
											2014-01-15 17:38:23 +01:00
										 |  |  |         try: | 
					
						
							| 
									
										
										
										
											2014-01-20 15:03:27 +01:00
										 |  |  |             return value[name] | 
					
						
							| 
									
										
										
										
											2014-01-15 17:38:23 +01:00
										 |  |  |         except: | 
					
						
							| 
									
										
										
										
											2014-01-20 15:03:27 +01:00
										 |  |  |             return None | 
					
						
							| 
									
										
										
										
											2014-01-15 17:38:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-06 12:15:39 +01:00
										 |  |  |     def pointerInfo(self, value): | 
					
						
							| 
									
										
										
										
											2015-04-30 15:52:33 +02:00
										 |  |  |         try: | 
					
						
							|  |  |  |             target = value.dereference() | 
					
						
							|  |  |  |             target.is_optimized_out # Access test. | 
					
						
							| 
									
										
										
										
											2016-01-06 12:15:39 +01:00
										 |  |  |             return (True, toInteger(value)) | 
					
						
							| 
									
										
										
										
											2015-04-30 15:52:33 +02:00
										 |  |  |         except: | 
					
						
							| 
									
										
										
										
											2016-01-06 12:15:39 +01:00
										 |  |  |             return (False, toInteger(value)) | 
					
						
							| 
									
										
										
										
											2015-04-30 15:52:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |     def makeValue(self, typeobj, init): | 
					
						
							|  |  |  |         typename = "::" + self.stripClassTag(str(typeobj)); | 
					
						
							| 
									
										
										
										
											2013-10-16 17:04:34 +02:00
										 |  |  |         # Avoid malloc symbol clash with QVector. | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |         gdb.execute("set $d = (%s*)calloc(sizeof(%s), 1)" % (typename, typename)) | 
					
						
							| 
									
										
										
										
											2013-10-16 17:04:34 +02:00
										 |  |  |         gdb.execute("set *$d = {%s}" % init) | 
					
						
							| 
									
										
										
										
											2014-02-21 17:34:08 +01:00
										 |  |  |         value = gdb.parse_and_eval("$d").dereference() | 
					
						
							| 
									
										
										
										
											2013-10-16 17:04:34 +02:00
										 |  |  |         #warn("  TYPE: %s" % value.type) | 
					
						
							|  |  |  |         #warn("  ADDR: %s" % value.address) | 
					
						
							|  |  |  |         #warn("  VALUE: %s" % value) | 
					
						
							|  |  |  |         return value | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def makeExpression(self, value): | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |         typename = "::" + self.stripClassTag(str(value.type)) | 
					
						
							|  |  |  |         #warn("  TYPE: %s" % typename) | 
					
						
							|  |  |  |         #exp = "(*(%s*)(&%s))" % (typename, value.address) | 
					
						
							|  |  |  |         exp = "(*(%s*)(%s))" % (typename, value.address) | 
					
						
							| 
									
										
										
										
											2013-10-16 17:04:34 +02:00
										 |  |  |         #warn("  EXP: %s" % exp) | 
					
						
							|  |  |  |         return exp | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def makeStdString(init): | 
					
						
							|  |  |  |         # Works only for small allocators, but they are usually empty. | 
					
						
							|  |  |  |         gdb.execute("set $d=(std::string*)calloc(sizeof(std::string), 2)"); | 
					
						
							|  |  |  |         gdb.execute("call($d->basic_string(\"" + init + | 
					
						
							|  |  |  |             "\",*(std::allocator<char>*)(1+$d)))") | 
					
						
							| 
									
										
										
										
											2014-02-21 17:34:08 +01:00
										 |  |  |         value = gdb.parse_and_eval("$d").dereference() | 
					
						
							| 
									
										
										
										
											2013-10-16 17:04:34 +02:00
										 |  |  |         #warn("  TYPE: %s" % value.type) | 
					
						
							|  |  |  |         #warn("  ADDR: %s" % value.address) | 
					
						
							|  |  |  |         #warn("  VALUE: %s" % value) | 
					
						
							|  |  |  |         return value | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |     def childAt(self, value, index): | 
					
						
							|  |  |  |         field = value.type.fields()[index] | 
					
						
							| 
									
										
										
										
											2014-06-18 13:15:15 +02:00
										 |  |  |         try: | 
					
						
							|  |  |  |             # Official access in GDB 7.6 or later. | 
					
						
							|  |  |  |             return value[field] | 
					
						
							|  |  |  |         except: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             # Won't work with anon entities, tradionally with empty | 
					
						
							|  |  |  |             # field name, but starting with GDB 7.7 commit b5b08fb4 | 
					
						
							|  |  |  |             # with None field name. | 
					
						
							|  |  |  |             return value[field.name] | 
					
						
							|  |  |  |         except: | 
					
						
							|  |  |  |             pass | 
					
						
							| 
									
										
										
										
											2014-01-31 16:56:32 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |         # FIXME: Cheat. There seems to be no official way to access | 
					
						
							|  |  |  |         # the real item, so we pass back the value. That at least | 
					
						
							|  |  |  |         # enables later ...["name"] style accesses as gdb handles | 
					
						
							|  |  |  |         # them transparently. | 
					
						
							|  |  |  |         return value | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |     def fieldAt(self, typeobj, index): | 
					
						
							|  |  |  |         return typeobj.fields()[index] | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-31 16:56:32 +01:00
										 |  |  |     def simpleValue(self, value): | 
					
						
							|  |  |  |         return str(value) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |     def directBaseClass(self, typeobj, index = 0): | 
					
						
							| 
									
										
										
										
											2014-03-12 13:20:21 +01:00
										 |  |  |         for f in typeobj.fields(): | 
					
						
							|  |  |  |             if f.is_base_class: | 
					
						
							|  |  |  |                 if index == 0: | 
					
						
							|  |  |  |                     return f.type | 
					
						
							|  |  |  |                 index -= 1; | 
					
						
							| 
									
										
										
										
											2014-03-17 17:48:46 +01:00
										 |  |  |         return None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def directBaseObject(self, value, index = 0): | 
					
						
							|  |  |  |         for f in value.type.fields(): | 
					
						
							|  |  |  |             if f.is_base_class: | 
					
						
							|  |  |  |                 if index == 0: | 
					
						
							|  |  |  |                     return value.cast(f.type) | 
					
						
							|  |  |  |                 index -= 1; | 
					
						
							| 
									
										
										
										
											2014-03-12 13:20:21 +01:00
										 |  |  |         return None | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def checkPointer(self, p, align = 1): | 
					
						
							|  |  |  |         if not self.isNull(p): | 
					
						
							|  |  |  |             p.dereference() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def pointerValue(self, p): | 
					
						
							|  |  |  |         return toInteger(p) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def isNull(self, p): | 
					
						
							|  |  |  |         # 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 ") | 
					
						
							|  |  |  |         #try: | 
					
						
							|  |  |  |         #    # Can fail with: "RuntimeError: Cannot access memory at address 0x5" | 
					
						
							| 
									
										
										
										
											2013-10-16 18:39:01 +02:00
										 |  |  |         #    return p.cast(self.lookupType("void").pointer()) == 0 | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |         #except: | 
					
						
							|  |  |  |         #    return False | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             # Can fail with: "RuntimeError: Cannot access memory at address 0x5" | 
					
						
							|  |  |  |             return toInteger(p) == 0 | 
					
						
							|  |  |  |         except: | 
					
						
							|  |  |  |             return False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-23 15:47:28 +02:00
										 |  |  |     def templateArgument(self, typeobj, position): | 
					
						
							| 
									
										
										
										
											2013-10-31 10:28:11 +01:00
										 |  |  |         try: | 
					
						
							|  |  |  |             # This fails on stock 7.2 with | 
					
						
							|  |  |  |             # "RuntimeError: No type named myns::QObject.\n" | 
					
						
							|  |  |  |             return typeobj.template_argument(position) | 
					
						
							|  |  |  |         except: | 
					
						
							|  |  |  |             # That's something like "myns::QList<...>" | 
					
						
							|  |  |  |             return self.lookupType(self.extractTemplateArgument(str(typeobj.strip_typedefs()), position)) | 
					
						
							| 
									
										
										
										
											2013-05-23 15:47:28 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def numericTemplateArgument(self, typeobj, position): | 
					
						
							| 
									
										
										
										
											2013-10-31 10:28:11 +01:00
										 |  |  |         # Workaround for gdb < 7.1 | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             return int(typeobj.template_argument(position)) | 
					
						
							|  |  |  |         except RuntimeError as error: | 
					
						
							|  |  |  |             # ": No type named 30." | 
					
						
							|  |  |  |             msg = str(error) | 
					
						
							|  |  |  |             msg = msg[14:-1] | 
					
						
							|  |  |  |             # gdb at least until 7.4 produces for std::array<int, 4u> | 
					
						
							|  |  |  |             # for template_argument(1): RuntimeError: No type named 4u. | 
					
						
							|  |  |  |             if msg[-1] == 'u': | 
					
						
							|  |  |  |                msg = msg[0:-1] | 
					
						
							|  |  |  |             return int(msg) | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-17 13:53:49 +02:00
										 |  |  |     def intType(self): | 
					
						
							| 
									
										
										
										
											2013-10-31 10:28:11 +01:00
										 |  |  |         self.cachedIntType = self.lookupType('int') | 
					
						
							|  |  |  |         self.intType = lambda: self.cachedIntType | 
					
						
							|  |  |  |         return self.cachedIntType | 
					
						
							| 
									
										
										
										
											2013-05-17 13:53:49 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def charType(self): | 
					
						
							| 
									
										
										
										
											2013-06-13 17:56:35 +02:00
										 |  |  |         return self.lookupType('char') | 
					
						
							| 
									
										
										
										
											2013-05-17 13:53:49 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def sizetType(self): | 
					
						
							| 
									
										
										
										
											2013-06-13 17:56:35 +02:00
										 |  |  |         return self.lookupType('size_t') | 
					
						
							| 
									
										
										
										
											2013-05-17 13:53:49 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def charPtrType(self): | 
					
						
							| 
									
										
										
										
											2013-06-13 17:56:35 +02:00
										 |  |  |         return self.lookupType('char*') | 
					
						
							| 
									
										
										
										
											2013-05-17 13:53:49 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def voidPtrType(self): | 
					
						
							| 
									
										
										
										
											2013-06-13 17:56:35 +02:00
										 |  |  |         return self.lookupType('void*') | 
					
						
							| 
									
										
										
										
											2013-05-17 13:53:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-17 17:14:45 +02:00
										 |  |  |     def addressOf(self, value): | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |         return toInteger(value.address) | 
					
						
							| 
									
										
										
										
											2013-05-17 17:14:45 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-28 14:04:05 +02:00
										 |  |  |     def createPointerValue(self, address, pointeeType): | 
					
						
							| 
									
										
										
										
											2013-10-24 17:38:57 +02:00
										 |  |  |         # This might not always work: | 
					
						
							|  |  |  |         # a Python 3 based GDB due to the bug addressed in | 
					
						
							|  |  |  |         # https://sourceware.org/ml/gdb-patches/2013-09/msg00571.html | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             return gdb.Value(address).cast(pointeeType.pointer()) | 
					
						
							|  |  |  |         except: | 
					
						
							|  |  |  |             # Try _some_ fallback (good enough for the std::complex dumper) | 
					
						
							|  |  |  |             return gdb.parse_and_eval("(%s*)%s" % (pointeeType, address)) | 
					
						
							| 
									
										
										
										
											2013-06-28 14:04:05 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def intSize(self): | 
					
						
							|  |  |  |         return 4 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def ptrSize(self): | 
					
						
							| 
									
										
										
										
											2013-10-31 13:32:12 +01:00
										 |  |  |         self.cachedPtrSize = self.lookupType('void*').sizeof | 
					
						
							|  |  |  |         self.ptrSize = lambda: self.cachedPtrSize | 
					
						
							|  |  |  |         return self.cachedPtrSize | 
					
						
							| 
									
										
										
										
											2013-06-28 14:04:05 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-29 00:41:48 +01:00
										 |  |  |     def pokeValue(self, value): | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         Allocates inferior memory and copies the contents of value. | 
					
						
							|  |  |  |         Returns a pointer to the copy. | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         # Avoid malloc symbol clash with QVector | 
					
						
							|  |  |  |         size = value.type.sizeof | 
					
						
							|  |  |  |         data = value.cast(gdb.lookup_type("unsigned char").array(0, int(size - 1))) | 
					
						
							|  |  |  |         string = ''.join("\\x%02x" % int(data[i]) for i in range(size)) | 
					
						
							|  |  |  |         exp = '(%s*)memcpy(calloc(%s, 1), "%s", %s)' % (value.type, size, string, size) | 
					
						
							|  |  |  |         #warn("EXP: %s" % exp) | 
					
						
							|  |  |  |         return toInteger(gdb.parse_and_eval(exp)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-28 14:04:05 +02:00
										 |  |  |     def createValue(self, address, referencedType): | 
					
						
							| 
									
										
										
										
											2013-10-24 17:38:57 +02:00
										 |  |  |         try: | 
					
						
							|  |  |  |             return gdb.Value(address).cast(referencedType.pointer()).dereference() | 
					
						
							|  |  |  |         except: | 
					
						
							|  |  |  |             # Try _some_ fallback (good enough for the std::complex dumper) | 
					
						
							|  |  |  |             return gdb.parse_and_eval("{%s}%s" % (referencedType, address)) | 
					
						
							| 
									
										
										
										
											2013-06-28 14:04:05 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |     def setValue(self, address, typename, value): | 
					
						
							|  |  |  |         cmd = "set {%s}%s=%s" % (typename, address, value) | 
					
						
							| 
									
										
										
										
											2013-11-20 18:55:09 +01:00
										 |  |  |         gdb.execute(cmd) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |     def setValues(self, address, typename, values): | 
					
						
							| 
									
										
										
										
											2013-11-20 18:55:09 +01:00
										 |  |  |         cmd = "set {%s[%s]}%s={%s}" \ | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |             % (typename, len(values), address, ','.join(map(str, values))) | 
					
						
							| 
									
										
										
										
											2013-11-20 18:55:09 +01:00
										 |  |  |         gdb.execute(cmd) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-30 11:40:53 +01:00
										 |  |  |     def selectedInferior(self): | 
					
						
							|  |  |  |         try: | 
					
						
							| 
									
										
										
										
											2013-10-30 12:38:29 +01:00
										 |  |  |             # gdb.Inferior is new in gdb 7.2 | 
					
						
							| 
									
										
										
										
											2013-10-30 15:07:54 +01:00
										 |  |  |             self.cachedInferior = gdb.selected_inferior() | 
					
						
							| 
									
										
										
										
											2013-10-30 11:40:53 +01:00
										 |  |  |         except: | 
					
						
							|  |  |  |             # Pre gdb 7.4. Right now we don't have more than one inferior anyway. | 
					
						
							| 
									
										
										
										
											2013-10-30 15:07:54 +01:00
										 |  |  |             self.cachedInferior = gdb.inferiors()[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Memoize result. | 
					
						
							|  |  |  |         self.selectedInferior = lambda: self.cachedInferior | 
					
						
							|  |  |  |         return self.cachedInferior | 
					
						
							| 
									
										
										
										
											2013-10-30 11:40:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |     def readRawMemory(self, address, size): | 
					
						
							|  |  |  |         mem = self.selectedInferior().read_memory(address, size) | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |         if sys.version_info[0] >= 3: | 
					
						
							|  |  |  |             mem.tobytes() | 
					
						
							|  |  |  |         return mem | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |     def extractInt64(self, address): | 
					
						
							|  |  |  |         return struct.unpack("q", self.readRawMemory(address, 8))[0] | 
					
						
							| 
									
										
										
										
											2013-10-22 13:51:35 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |     def extractUInt64(self, address): | 
					
						
							|  |  |  |         return struct.unpack("Q", self.readRawMemory(address, 8))[0] | 
					
						
							| 
									
										
										
										
											2015-04-13 17:55:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |     def extractInt(self, address): | 
					
						
							|  |  |  |         return struct.unpack("i", self.readRawMemory(address, 4))[0] | 
					
						
							| 
									
										
										
										
											2013-06-28 14:04:05 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |     def extractUInt(self, address): | 
					
						
							|  |  |  |         return struct.unpack("I", self.readRawMemory(address, 4))[0] | 
					
						
							| 
									
										
										
										
											2015-04-13 17:55:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |     def extractShort(self, address): | 
					
						
							|  |  |  |         return struct.unpack("h", self.readRawMemory(address, 2))[0] | 
					
						
							| 
									
										
										
										
											2015-07-01 17:24:56 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |     def extractUShort(self, address): | 
					
						
							|  |  |  |         return struct.unpack("H", self.readRawMemory(address, 2))[0] | 
					
						
							| 
									
										
										
										
											2015-07-01 17:24:56 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |     def extractByte(self, address): | 
					
						
							|  |  |  |         return struct.unpack("b", self.readRawMemory(address, 1))[0] | 
					
						
							| 
									
										
										
										
											2013-07-09 14:19:45 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |     def findStaticMetaObject(self, typename): | 
					
						
							|  |  |  |         return self.findSymbol(typename + "::staticMetaObject") | 
					
						
							| 
									
										
										
										
											2014-04-11 13:20:59 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-28 12:05:48 +01:00
										 |  |  |     def findSymbol(self, symbolName): | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             result = gdb.lookup_global_symbol(symbolName) | 
					
						
							|  |  |  |             return result.value() if result else 0 | 
					
						
							|  |  |  |         except: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  |         # Older GDB ~7.4 | 
					
						
							|  |  |  |         try: | 
					
						
							| 
									
										
										
										
											2014-03-10 17:03:29 +01:00
										 |  |  |             address = gdb.parse_and_eval("&'%s'" % symbolName) | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |             typeobj = gdb.lookup_type(self.qtNamespace() + "QMetaObject") | 
					
						
							|  |  |  |             return self.createPointerValue(address, typeobj) | 
					
						
							| 
									
										
										
										
											2014-02-28 12:05:48 +01:00
										 |  |  |         except: | 
					
						
							|  |  |  |             return 0 | 
					
						
							| 
									
										
										
										
											2014-02-25 15:52:22 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |     def put(self, value): | 
					
						
							|  |  |  |         self.output.append(value) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def childRange(self): | 
					
						
							|  |  |  |         if self.currentMaxNumChild is None: | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |             return xrange(0, toInteger(self.currentNumChild)) | 
					
						
							|  |  |  |         return xrange(min(toInteger(self.currentMaxNumChild), toInteger(self.currentNumChild))) | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-11 09:54:54 +01:00
										 |  |  |     def isArmArchitecture(self): | 
					
						
							|  |  |  |         return 'arm' in gdb.TARGET_CONFIG.lower() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def isQnxTarget(self): | 
					
						
							|  |  |  |         return 'qnx' in gdb.TARGET_CONFIG.lower() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-01 18:11:57 +02:00
										 |  |  |     def isWindowsTarget(self): | 
					
						
							|  |  |  |         # We get i686-w64-mingw32 | 
					
						
							|  |  |  |         return 'mingw' in gdb.TARGET_CONFIG.lower() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-07 18:46:44 +01:00
										 |  |  |     def qtVersionString(self): | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             return str(gdb.lookup_symbol("qVersion")[0].value()()) | 
					
						
							|  |  |  |         except: | 
					
						
							|  |  |  |             pass | 
					
						
							| 
									
										
										
										
											2013-10-30 15:07:54 +01:00
										 |  |  |         try: | 
					
						
							| 
									
										
										
										
											2014-01-30 12:40:24 +01:00
										 |  |  |             ns = self.qtNamespace() | 
					
						
							| 
									
										
										
										
											2014-03-07 18:46:44 +01:00
										 |  |  |             return str(gdb.parse_and_eval("((const char*(*)())'%sqVersion')()" % ns)) | 
					
						
							|  |  |  |         except: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  |         return None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def qtVersion(self): | 
					
						
							| 
									
										
										
										
											2015-08-13 12:12:54 +02:00
										 |  |  |         try: | 
					
						
							|  |  |  |             # Only available with Qt 5.3+ | 
					
						
							|  |  |  |             qtversion = int(gdb.parse_and_eval("((void**)&qtHookData)[2]")) | 
					
						
							|  |  |  |             self.qtVersion = lambda: qtversion | 
					
						
							|  |  |  |             return qtversion | 
					
						
							|  |  |  |         except: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-07 18:46:44 +01:00
										 |  |  |         try: | 
					
						
							|  |  |  |             version = self.qtVersionString() | 
					
						
							| 
									
										
										
										
											2013-10-31 10:28:11 +01:00
										 |  |  |             (major, minor, patch) = version[version.find('"')+1:version.rfind('"')].split('.') | 
					
						
							| 
									
										
										
										
											2014-03-07 18:46:44 +01:00
										 |  |  |             qtversion = 0x10000 * int(major) + 0x100 * int(minor) + int(patch) | 
					
						
							|  |  |  |             self.qtVersion = lambda: qtversion | 
					
						
							|  |  |  |             return qtversion | 
					
						
							| 
									
										
										
										
											2013-10-30 15:07:54 +01:00
										 |  |  |         except: | 
					
						
							| 
									
										
										
										
											2014-03-07 15:48:13 +01:00
										 |  |  |             # Use fallback until we have a better answer. | 
					
						
							|  |  |  |             return self.fallbackQtVersion | 
					
						
							| 
									
										
										
										
											2013-10-30 15:07:54 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-11 09:54:54 +01:00
										 |  |  |     def isQt3Support(self): | 
					
						
							|  |  |  |         if self.qtVersion() >= 0x050000: | 
					
						
							|  |  |  |             return False | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 # This will fail on Qt 4 without Qt 3 support | 
					
						
							|  |  |  |                 gdb.execute("ptype QChar::null", to_string=True) | 
					
						
							|  |  |  |                 self.cachedIsQt3Suport = True | 
					
						
							|  |  |  |             except: | 
					
						
							|  |  |  |                 self.cachedIsQt3Suport = False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Memoize good results. | 
					
						
							|  |  |  |         self.isQt3Support = lambda: self.cachedIsQt3Suport | 
					
						
							|  |  |  |         return self.cachedIsQt3Suport | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |     def putAddress(self, address): | 
					
						
							| 
									
										
											  
											
												Debugger: Make dumpers somewhat work in command line GDB
With
    python sys.path.insert(1, '/data/dev/creator/share/qtcreator/debugger/')
    python from gdbbridge import *
in .gdbinit there's a new "GDB command", called "pp".
With code like
    int main(int argc, char *argv[])
    {
        QString ss = "Hello";
        QApplication app(argc, argv);
        app.setObjectName(ss);
        // break here
    }
the 'pp' command can be used as follows:
(gdb) pp app
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = <Myns::QObjectList> = {"<3 items>"}
      [properties] = "<>0 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp app [properties],[children]
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = [
         <Myns::QObject> = {""}
         <Myns::QObject> = {""}
         <Myns::QObject> = {"fusion"}
      ],<Myns::QObjectList> = {"<3 items>"}
      [properties] = [
         windowIcon = <Myns::QVariant (QIcon)> = {""}
         cursorFlashTime = <Myns::QVariant (int)> = {"1000"}
         doubleClickInterval = <Myns::QVariant (int)> = {"400"}
         keyboardInputInterval = <Myns::QVariant (int)> = {"400"}
         wheelScrollLines = <Myns::QVariant (int)> = {"3"}
         globalStrut = <Myns::QVariant (QSize)> = {"(0, 0)"}
         startDragTime = <Myns::QVariant (int)> = {"500"}
         startDragDistance = <Myns::QVariant (int)> = {"10"}
         styleSheet = <Myns::QVariant (QString)> = {""}
         autoSipEnabled = <Myns::QVariant (bool)> = {"true"}
      ],"<10 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp ss
ss =
   <Myns::QString> = {"Hello"}
Change-Id: I6e4714a5cfe34c38917500d114ad9a70d20cff39
Reviewed-by: Christian Stenger <christian.stenger@digia.com>
Reviewed-by: hjk <hjk121@nokiamail.com>
											
										 
											2014-06-13 17:45:34 +02:00
										 |  |  |         if self.currentPrintsAddress and not self.isCli: | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |             try: | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |                 # address can be "None", int(None) fails. | 
					
						
							|  |  |  |                 #self.put('address="0x%x",' % int(address)) | 
					
						
							|  |  |  |                 self.currentAddress = 'address="0x%x",' % toInteger(address) | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |             except: | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-24 13:27:10 +02:00
										 |  |  |     def putSimpleValue(self, value, encoding = None, priority = 0): | 
					
						
							|  |  |  |         self.putValue(value, encoding, priority) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |     def putPointerValue(self, value): | 
					
						
							|  |  |  |         # Use a lower priority | 
					
						
							|  |  |  |         if value is None: | 
					
						
							|  |  |  |             self.putEmptyValue(-1) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.putValue("0x%x" % value.cast( | 
					
						
							| 
									
										
										
										
											2013-10-16 18:39:01 +02:00
										 |  |  |                 self.lookupType("unsigned long")), None, -1) | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def stripNamespaceFromType(self, typeName): | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |         typename = self.stripClassTag(typeName) | 
					
						
							| 
									
										
										
										
											2013-10-30 15:07:54 +01:00
										 |  |  |         ns = self.qtNamespace() | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |         if len(ns) > 0 and typename.startswith(ns): | 
					
						
							|  |  |  |             typename = typename[len(ns):] | 
					
						
							|  |  |  |         pos = typename.find("<") | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |         # FIXME: make it recognize  foo<A>::bar<B>::iterator? | 
					
						
							|  |  |  |         while pos != -1: | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |             pos1 = typename.rfind(">", pos) | 
					
						
							|  |  |  |             typename = typename[0:pos] + typename[pos1+1:] | 
					
						
							|  |  |  |             pos = typename.find("<") | 
					
						
							|  |  |  |         return typename | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |     def isMovableType(self, typeobj): | 
					
						
							|  |  |  |         if typeobj.code == PointerCode: | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |             return True | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |         if self.isSimpleType(typeobj): | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |             return True | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |         return self.isKnownMovableType(self.stripNamespaceFromType(str(typeobj))) | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def putSubItem(self, component, value, tryDynamic=True): | 
					
						
							|  |  |  |         with SubItem(self, component): | 
					
						
							|  |  |  |             self.putItem(value, tryDynamic) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |     def isSimpleType(self, typeobj): | 
					
						
							|  |  |  |         code = typeobj.code | 
					
						
							|  |  |  |         return code == BoolCode \ | 
					
						
							|  |  |  |             or code == CharCode \ | 
					
						
							|  |  |  |             or code == IntCode \ | 
					
						
							|  |  |  |             or code == FloatCode \ | 
					
						
							| 
									
										
										
										
											2013-10-10 14:33:05 +02:00
										 |  |  |             or code == EnumCode | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def simpleEncoding(self, typeobj): | 
					
						
							|  |  |  |         code = typeobj.code | 
					
						
							|  |  |  |         if code == BoolCode or code == CharCode: | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |             return "int:1" | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |         if code == IntCode: | 
					
						
							|  |  |  |             if str(typeobj).find("unsigned") >= 0: | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |                  return "uint:%d" % typeobj.sizeof | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |             else: | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |                  return "int:%d" % typeobj.sizeof | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |         if code == FloatCode: | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |             return "float:%d" % typeobj.sizeof | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |         return None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-03 13:32:19 +02:00
										 |  |  |     def isReferenceType(self, typeobj): | 
					
						
							|  |  |  |         return typeobj.code == gdb.TYPE_CODE_REF | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def isStructType(self, typeobj): | 
					
						
							|  |  |  |         return typeobj.code == gdb.TYPE_CODE_STRUCT | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |     def isFunctionType(self, typeobj): | 
					
						
							|  |  |  |         return typeobj.code == MethodCode or typeobj.code == FunctionCode | 
					
						
							| 
									
										
										
										
											2013-11-06 17:57:12 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |     def putItem(self, value, tryDynamic=True): | 
					
						
							|  |  |  |         if value is None: | 
					
						
							|  |  |  |             # Happens for non-available watchers in gdb versions that | 
					
						
							|  |  |  |             # need to use gdb.execute instead of gdb.parse_and_eval | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |             self.putSpecialValue("notaccessible") | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |             self.putType("<unknown>") | 
					
						
							|  |  |  |             self.putNumChild(0) | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |         typeobj = value.type.unqualified() | 
					
						
							|  |  |  |         typeName = str(typeobj) | 
					
						
							| 
									
										
										
										
											2014-11-18 15:38:05 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if value.is_optimized_out: | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |             self.putSpecialValue("optimizedout") | 
					
						
							| 
									
										
										
										
											2014-11-18 15:38:05 +01:00
										 |  |  |             self.putType(typeName) | 
					
						
							|  |  |  |             self.putNumChild(0) | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |         tryDynamic &= self.useDynamicType | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |         self.addToCache(typeobj) # Fill type cache | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |         if tryDynamic: | 
					
						
							|  |  |  |             self.putAddress(value.address) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # FIXME: Gui shows references stripped? | 
					
						
							|  |  |  |         #warn(" ") | 
					
						
							| 
									
										
										
										
											2014-12-12 10:12:23 +01:00
										 |  |  |         #warn("REAL INAME: %s" % self.currentIName) | 
					
						
							|  |  |  |         #warn("REAL TYPE: %s" % value.type) | 
					
						
							|  |  |  |         #warn("REAL CODE: %s" % value.type.code) | 
					
						
							|  |  |  |         #warn("REAL VALUE: %s" % value) | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |         if typeobj.code == ReferenceCode: | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |             try: | 
					
						
							|  |  |  |                 # Try to recognize null references explicitly. | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |                 if toInteger(value.address) == 0: | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |                     self.putSpecialValue("nullreference") | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |                     self.putType(typeName) | 
					
						
							|  |  |  |                     self.putNumChild(0) | 
					
						
							|  |  |  |                     return | 
					
						
							|  |  |  |             except: | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if tryDynamic: | 
					
						
							|  |  |  |                 try: | 
					
						
							|  |  |  |                     # Dynamic references are not supported by gdb, see | 
					
						
							|  |  |  |                     # http://sourceware.org/bugzilla/show_bug.cgi?id=14077. | 
					
						
							|  |  |  |                     # Find the dynamic type manually using referenced_type. | 
					
						
							|  |  |  |                     value = value.referenced_value() | 
					
						
							|  |  |  |                     value = value.cast(value.dynamic_type) | 
					
						
							|  |  |  |                     self.putItem(value) | 
					
						
							|  |  |  |                     self.putBetterType("%s &" % value.type) | 
					
						
							|  |  |  |                     return | 
					
						
							|  |  |  |                 except: | 
					
						
							|  |  |  |                     pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 # FIXME: This throws "RuntimeError: Attempt to dereference a | 
					
						
							|  |  |  |                 # generic pointer." with MinGW's gcc 4.5 when it "identifies" | 
					
						
							|  |  |  |                 # a "QWidget &" as "void &" and with optimized out code. | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |                 self.putItem(value.cast(typeobj.target().unqualified())) | 
					
						
							| 
									
										
										
										
											2014-05-19 10:55:33 +02:00
										 |  |  |                 self.putBetterType("%s &" % self.currentType.value) | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |                 return | 
					
						
							|  |  |  |             except RuntimeError: | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |                 self.putSpecialValue("optimizedout") | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |                 self.putType(typeName) | 
					
						
							|  |  |  |                 self.putNumChild(0) | 
					
						
							|  |  |  |                 return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |         if typeobj.code == IntCode or typeobj.code == CharCode: | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |             self.putType(typeName) | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |             if typeobj.sizeof == 1: | 
					
						
							| 
									
										
										
										
											2014-03-11 18:46:33 +01:00
										 |  |  |                 # Force unadorned value transport for char and Co. | 
					
						
							|  |  |  |                 self.putValue(int(value) & 0xff) | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |             else: | 
					
						
							|  |  |  |                 self.putValue(value) | 
					
						
							|  |  |  |             self.putNumChild(0) | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |         if typeobj.code == FloatCode or typeobj.code == BoolCode: | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |             self.putType(typeName) | 
					
						
							| 
									
										
										
										
											2014-11-18 15:38:05 +01:00
										 |  |  |             self.putValue(value) | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |             self.putNumChild(0) | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |         if typeobj.code == EnumCode: | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |             self.putType(typeName) | 
					
						
							| 
									
										
										
										
											2014-11-18 15:38:05 +01:00
										 |  |  |             self.putValue("%s (%d)" % (value, value)) | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |             self.putNumChild(0) | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |         if typeobj.code == ComplexCode: | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |             self.putType(typeName) | 
					
						
							| 
									
										
										
										
											2014-11-18 15:38:05 +01:00
										 |  |  |             self.putValue("%s" % value) | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |             self.putNumChild(0) | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |         if typeobj.code == TypedefCode: | 
					
						
							| 
									
										
										
										
											2013-10-30 15:07:54 +01:00
										 |  |  |             if typeName in self.qqDumpers: | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |                 self.putType(typeName) | 
					
						
							| 
									
										
										
										
											2013-10-30 15:07:54 +01:00
										 |  |  |                 self.qqDumpers[typeName](self, value) | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |                 return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |             typeobj = stripTypedefs(typeobj) | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |             # The cast can destroy the address? | 
					
						
							|  |  |  |             #self.putAddress(value.address) | 
					
						
							|  |  |  |             # Workaround for http://sourceware.org/bugzilla/show_bug.cgi?id=13380 | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |             if typeobj.code == ArrayCode: | 
					
						
							|  |  |  |                 value = self.parseAndEvaluate("{%s}%s" % (typeobj, value.address)) | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |             else: | 
					
						
							|  |  |  |                 try: | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |                     value = value.cast(typeobj) | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |                 except: | 
					
						
							|  |  |  |                     self.putValue("<optimized out typedef>") | 
					
						
							|  |  |  |                     self.putType(typeName) | 
					
						
							|  |  |  |                     self.putNumChild(0) | 
					
						
							|  |  |  |                     return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             self.putItem(value) | 
					
						
							|  |  |  |             self.putBetterType(typeName) | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |         if typeobj.code == ArrayCode: | 
					
						
							| 
									
										
										
										
											2013-11-07 12:26:14 +01:00
										 |  |  |             self.putCStyleArray(value) | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |         if typeobj.code == PointerCode: | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |             # This could still be stored in a register and | 
					
						
							|  |  |  |             # potentially dereferencable. | 
					
						
							| 
									
										
										
										
											2013-11-06 17:57:12 +01:00
										 |  |  |             self.putFormattedPointer(value) | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |         if typeobj.code == MethodPointerCode \ | 
					
						
							|  |  |  |                 or typeobj.code == MethodCode \ | 
					
						
							|  |  |  |                 or typeobj.code == FunctionCode \ | 
					
						
							|  |  |  |                 or typeobj.code == MemberPointerCode: | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |             self.putType(typeName) | 
					
						
							|  |  |  |             self.putValue(value) | 
					
						
							|  |  |  |             self.putNumChild(0) | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if typeName.startswith("<anon"): | 
					
						
							|  |  |  |             # Anonymous union. We need a dummy name to distinguish | 
					
						
							|  |  |  |             # multiple anonymous unions in the struct. | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |             self.putType(typeobj) | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |             self.putSpecialValue("emptystructure") | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |             self.anonNumber += 1 | 
					
						
							|  |  |  |             with Children(self, 1): | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |                 self.listAnonymous(value, "#%d" % self.anonNumber, typeobj) | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |         if typeobj.code == StringCode: | 
					
						
							| 
									
										
										
										
											2013-08-26 22:39:18 +02:00
										 |  |  |             # FORTRAN strings | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |             size = typeobj.sizeof | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |             data = self.readMemory(value.address, size) | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |             self.putValue(data, "latin1", 1) | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |             self.putType(typeobj) | 
					
						
							| 
									
										
										
										
											2013-08-26 22:39:18 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |         if typeobj.code != StructCode and typeobj.code != UnionCode: | 
					
						
							|  |  |  |             warn("WRONG ASSUMPTION HERE: %s " % typeobj.code) | 
					
						
							| 
									
										
										
										
											2015-04-15 13:29:25 +02:00
										 |  |  |             self.check(False) | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if tryDynamic: | 
					
						
							| 
									
										
										
										
											2013-10-31 10:28:11 +01:00
										 |  |  |             self.putItem(self.expensiveDowncast(value), False) | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-20 16:03:59 +01:00
										 |  |  |         if self.tryPutPrettyItem(typeName, value): | 
					
						
							|  |  |  |             return | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # D arrays, gdc compiled. | 
					
						
							|  |  |  |         if typeName.endswith("[]"): | 
					
						
							|  |  |  |             n = value["length"] | 
					
						
							|  |  |  |             base = value["ptr"] | 
					
						
							|  |  |  |             self.putType(typeName) | 
					
						
							|  |  |  |             self.putItemCount(n) | 
					
						
							|  |  |  |             if self.isExpanded(): | 
					
						
							|  |  |  |                 self.putArrayData(base.type.target(), base, n) | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |         #warn("GENERIC STRUCT: %s" % typeobj) | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |         #warn("INAME: %s " % self.currentIName) | 
					
						
							|  |  |  |         #warn("INAMES: %s " % self.expandedINames) | 
					
						
							|  |  |  |         #warn("EXPANDED: %s " % (self.currentIName in self.expandedINames)) | 
					
						
							| 
									
										
										
										
											2015-12-16 14:13:44 +01:00
										 |  |  |         if self.showQObjectNames: | 
					
						
							|  |  |  |             staticMetaObject = self.extractStaticMetaObject(value.type) | 
					
						
							|  |  |  |             if staticMetaObject: | 
					
						
							|  |  |  |                 self.putQObjectNameValue(value) | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |         self.putType(typeName) | 
					
						
							|  |  |  |         self.putEmptyValue() | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |         self.putNumChild(len(typeobj.fields())) | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if self.currentIName in self.expandedINames: | 
					
						
							|  |  |  |             innerType = None | 
					
						
							|  |  |  |             with Children(self, 1, childType=innerType): | 
					
						
							|  |  |  |                 self.putFields(value) | 
					
						
							| 
									
										
										
										
											2015-12-16 14:13:44 +01:00
										 |  |  |                 if not self.showQObjectNames: | 
					
						
							|  |  |  |                     staticMetaObject = self.extractStaticMetaObject(value.type) | 
					
						
							| 
									
										
										
										
											2014-01-28 23:23:01 +01:00
										 |  |  |                 if staticMetaObject: | 
					
						
							|  |  |  |                     self.putQObjectGuts(value, staticMetaObject) | 
					
						
							| 
									
										
										
										
											2014-01-20 15:03:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-24 15:13:20 +01:00
										 |  |  |     def toBlob(self, value): | 
					
						
							|  |  |  |         size = toInteger(value.type.sizeof) | 
					
						
							|  |  |  |         if value.address: | 
					
						
							|  |  |  |             return self.extractBlob(value.address, size) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # No address. Possibly the result of an inferior call. | 
					
						
							|  |  |  |         y = value.cast(gdb.lookup_type("unsigned char").array(0, int(size - 1))) | 
					
						
							|  |  |  |         buf = bytearray(struct.pack('x' * size)) | 
					
						
							|  |  |  |         for i in range(size): | 
					
						
							|  |  |  |             buf[i] = int(y[i]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return Blob(bytes(buf)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-23 15:30:51 +01:00
										 |  |  |     def extractBlob(self, base, size): | 
					
						
							| 
									
										
										
										
											2013-10-30 12:38:29 +01:00
										 |  |  |         inferior = self.selectedInferior() | 
					
						
							| 
									
										
										
										
											2014-01-23 15:30:51 +01:00
										 |  |  |         return Blob(inferior.read_memory(base, size)) | 
					
						
							| 
									
										
										
										
											2013-05-15 16:17:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-20 15:03:27 +01:00
										 |  |  |     def readCString(self, base): | 
					
						
							|  |  |  |         inferior = self.selectedInferior() | 
					
						
							|  |  |  |         mem = "" | 
					
						
							|  |  |  |         while True: | 
					
						
							|  |  |  |             char = inferior.read_memory(base, 1)[0] | 
					
						
							|  |  |  |             if not char: | 
					
						
							|  |  |  |                 break | 
					
						
							|  |  |  |             mem += char | 
					
						
							|  |  |  |             base += 1 | 
					
						
							|  |  |  |         #if sys.version_info[0] >= 3: | 
					
						
							|  |  |  |         #    return mem.tobytes() | 
					
						
							|  |  |  |         return mem | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-02 16:01:43 +01:00
										 |  |  |     def createSpecialBreakpoints(self, args): | 
					
						
							|  |  |  |         self.specialBreakpoints = [] | 
					
						
							|  |  |  |         def newSpecial(spec): | 
					
						
							|  |  |  |             class SpecialBreakpoint(gdb.Breakpoint): | 
					
						
							|  |  |  |                 def __init__(self, spec): | 
					
						
							|  |  |  |                     super(SpecialBreakpoint, self).\ | 
					
						
							|  |  |  |                         __init__(spec, gdb.BP_BREAKPOINT, internal=True) | 
					
						
							|  |  |  |                     self.spec = spec | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 def stop(self): | 
					
						
							|  |  |  |                     print("Breakpoint on '%s' hit." % self.spec) | 
					
						
							|  |  |  |                     return True | 
					
						
							|  |  |  |             return SpecialBreakpoint(spec) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # FIXME: ns is accessed too early. gdb.Breakpoint() has no | 
					
						
							|  |  |  |         # 'rbreak' replacement, and breakpoints created with | 
					
						
							|  |  |  |         # 'gdb.execute("rbreak...") cannot be made invisible. | 
					
						
							|  |  |  |         # So let's ignore the existing of namespaced builds for this | 
					
						
							|  |  |  |         # fringe feature here for now. | 
					
						
							|  |  |  |         ns = self.qtNamespace() | 
					
						
							|  |  |  |         if args.get('breakonabort', 0): | 
					
						
							|  |  |  |             self.specialBreakpoints.append(newSpecial("abort")) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if args.get('breakonwarning', 0): | 
					
						
							|  |  |  |             self.specialBreakpoints.append(newSpecial(ns + "qWarning")) | 
					
						
							|  |  |  |             self.specialBreakpoints.append(newSpecial(ns + "QMessageLogger::warning")) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if args.get('breakonfatal', 0): | 
					
						
							|  |  |  |             self.specialBreakpoints.append(newSpecial(ns + "qFatal")) | 
					
						
							|  |  |  |             self.specialBreakpoints.append(newSpecial(ns + "QMessageLogger::fatal")) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |     def putFields(self, value, dumpBase = True): | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |             fields = value.type.fields() | 
					
						
							| 
									
										
										
										
											2015-05-29 08:23:52 +02:00
										 |  |  |             if self.sortStructMembers: | 
					
						
							| 
									
										
										
										
											2015-07-21 16:00:30 +02:00
										 |  |  |                 def sortOrder(field): | 
					
						
							|  |  |  |                     if field.is_base_class: | 
					
						
							|  |  |  |                         return 0 | 
					
						
							| 
									
										
										
										
											2015-07-28 00:09:33 +03:00
										 |  |  |                     if field.name and field.name.startswith("_vptr."): | 
					
						
							| 
									
										
										
										
											2015-07-21 16:00:30 +02:00
										 |  |  |                         return 1 | 
					
						
							|  |  |  |                     return 2 | 
					
						
							|  |  |  |                 fields.sort(key = lambda field: "%d%s" % (sortOrder(field), field.name)) | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-16 18:10:02 +02:00
										 |  |  |             #warn("TYPE: %s" % value.type) | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |             #warn("FIELDS: %s" % fields) | 
					
						
							|  |  |  |             baseNumber = 0 | 
					
						
							|  |  |  |             for field in fields: | 
					
						
							|  |  |  |                 #warn("FIELD: %s" % field) | 
					
						
							|  |  |  |                 #warn("  BITSIZE: %s" % field.bitsize) | 
					
						
							|  |  |  |                 #warn("  ARTIFICIAL: %s" % field.artificial) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-16 18:10:02 +02:00
										 |  |  |                 # Since GDB commit b5b08fb4 anonymous structs get also reported | 
					
						
							|  |  |  |                 # with a 'None' name. | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |                 if field.name is None: | 
					
						
							| 
									
										
										
										
											2014-06-16 18:10:02 +02:00
										 |  |  |                     if value.type.code == ArrayCode: | 
					
						
							|  |  |  |                         # An array. | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |                         typeobj = stripTypedefs(value.type) | 
					
						
							|  |  |  |                         innerType = typeobj.target() | 
					
						
							| 
									
										
										
										
											2014-06-16 18:10:02 +02:00
										 |  |  |                         p = value.cast(innerType.pointer()) | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |                         for i in xrange(int(typeobj.sizeof / innerType.sizeof)): | 
					
						
							| 
									
										
										
										
											2014-06-16 18:10:02 +02:00
										 |  |  |                             with SubItem(self, i): | 
					
						
							|  |  |  |                                 self.putItem(p.dereference()) | 
					
						
							|  |  |  |                             p = p + 1 | 
					
						
							|  |  |  |                     else: | 
					
						
							|  |  |  |                         # Something without a name. | 
					
						
							|  |  |  |                         self.anonNumber += 1 | 
					
						
							|  |  |  |                         with SubItem(self, str(self.anonNumber)): | 
					
						
							|  |  |  |                             self.putItem(value[field]) | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |                     continue | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 # Ignore vtable pointers for virtual inheritance. | 
					
						
							|  |  |  |                 if field.name.startswith("_vptr."): | 
					
						
							|  |  |  |                     with SubItem(self, "[vptr]"): | 
					
						
							|  |  |  |                         # int (**)(void) | 
					
						
							|  |  |  |                         n = 100 | 
					
						
							|  |  |  |                         self.putType(" ") | 
					
						
							|  |  |  |                         self.putValue(value[field.name]) | 
					
						
							|  |  |  |                         self.putNumChild(n) | 
					
						
							|  |  |  |                         if self.isExpanded(): | 
					
						
							|  |  |  |                             with Children(self): | 
					
						
							|  |  |  |                                 p = value[field.name] | 
					
						
							|  |  |  |                                 for i in xrange(n): | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |                                     if toInteger(p.dereference()) != 0: | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |                                         with SubItem(self, i): | 
					
						
							|  |  |  |                                             self.putItem(p.dereference()) | 
					
						
							|  |  |  |                                             self.putType(" ") | 
					
						
							|  |  |  |                                             p = p + 1 | 
					
						
							|  |  |  |                     continue | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 #warn("FIELD NAME: %s" % field.name) | 
					
						
							|  |  |  |                 #warn("FIELD TYPE: %s" % field.type) | 
					
						
							|  |  |  |                 if field.is_base_class: | 
					
						
							|  |  |  |                     # Field is base type. We cannot use field.name as part | 
					
						
							|  |  |  |                     # of the iname as it might contain spaces and other | 
					
						
							|  |  |  |                     # strange characters. | 
					
						
							|  |  |  |                     if dumpBase: | 
					
						
							|  |  |  |                         baseNumber += 1 | 
					
						
							|  |  |  |                         with UnnamedSubItem(self, "@%d" % baseNumber): | 
					
						
							| 
									
										
										
										
											2013-12-15 19:24:10 +01:00
										 |  |  |                             baseValue = value.cast(field.type) | 
					
						
							| 
									
										
											  
											
												Debugger: Make dumpers somewhat work in command line GDB
With
    python sys.path.insert(1, '/data/dev/creator/share/qtcreator/debugger/')
    python from gdbbridge import *
in .gdbinit there's a new "GDB command", called "pp".
With code like
    int main(int argc, char *argv[])
    {
        QString ss = "Hello";
        QApplication app(argc, argv);
        app.setObjectName(ss);
        // break here
    }
the 'pp' command can be used as follows:
(gdb) pp app
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = <Myns::QObjectList> = {"<3 items>"}
      [properties] = "<>0 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp app [properties],[children]
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = [
         <Myns::QObject> = {""}
         <Myns::QObject> = {""}
         <Myns::QObject> = {"fusion"}
      ],<Myns::QObjectList> = {"<3 items>"}
      [properties] = [
         windowIcon = <Myns::QVariant (QIcon)> = {""}
         cursorFlashTime = <Myns::QVariant (int)> = {"1000"}
         doubleClickInterval = <Myns::QVariant (int)> = {"400"}
         keyboardInputInterval = <Myns::QVariant (int)> = {"400"}
         wheelScrollLines = <Myns::QVariant (int)> = {"3"}
         globalStrut = <Myns::QVariant (QSize)> = {"(0, 0)"}
         startDragTime = <Myns::QVariant (int)> = {"500"}
         startDragDistance = <Myns::QVariant (int)> = {"10"}
         styleSheet = <Myns::QVariant (QString)> = {""}
         autoSipEnabled = <Myns::QVariant (bool)> = {"true"}
      ],"<10 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp ss
ss =
   <Myns::QString> = {"Hello"}
Change-Id: I6e4714a5cfe34c38917500d114ad9a70d20cff39
Reviewed-by: Christian Stenger <christian.stenger@digia.com>
Reviewed-by: hjk <hjk121@nokiamail.com>
											
										 
											2014-06-13 17:45:34 +02:00
										 |  |  |                             self.putBaseClassName(field.name) | 
					
						
							| 
									
										
										
										
											2013-12-15 19:24:10 +01:00
										 |  |  |                             self.putAddress(baseValue.address) | 
					
						
							|  |  |  |                             self.putItem(baseValue, False) | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |                 elif len(field.name) == 0: | 
					
						
							|  |  |  |                     # Anonymous union. We need a dummy name to distinguish | 
					
						
							|  |  |  |                     # multiple anonymous unions in the struct. | 
					
						
							|  |  |  |                     self.anonNumber += 1 | 
					
						
							|  |  |  |                     self.listAnonymous(value, "#%d" % self.anonNumber, | 
					
						
							|  |  |  |                         field.type) | 
					
						
							|  |  |  |                 else: | 
					
						
							|  |  |  |                     # Named field. | 
					
						
							|  |  |  |                     with SubItem(self, field.name): | 
					
						
							|  |  |  |                         #bitsize = getattr(field, "bitsize", None) | 
					
						
							|  |  |  |                         #if not bitsize is None: | 
					
						
							|  |  |  |                         #    self.put("bitsize=\"%s\"" % bitsize) | 
					
						
							| 
									
										
										
										
											2013-10-31 10:28:11 +01:00
										 |  |  |                         self.putItem(self.downcast(value[field.name])) | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												Debugger: Make dumpers somewhat work in command line GDB
With
    python sys.path.insert(1, '/data/dev/creator/share/qtcreator/debugger/')
    python from gdbbridge import *
in .gdbinit there's a new "GDB command", called "pp".
With code like
    int main(int argc, char *argv[])
    {
        QString ss = "Hello";
        QApplication app(argc, argv);
        app.setObjectName(ss);
        // break here
    }
the 'pp' command can be used as follows:
(gdb) pp app
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = <Myns::QObjectList> = {"<3 items>"}
      [properties] = "<>0 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp app [properties],[children]
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = [
         <Myns::QObject> = {""}
         <Myns::QObject> = {""}
         <Myns::QObject> = {"fusion"}
      ],<Myns::QObjectList> = {"<3 items>"}
      [properties] = [
         windowIcon = <Myns::QVariant (QIcon)> = {""}
         cursorFlashTime = <Myns::QVariant (int)> = {"1000"}
         doubleClickInterval = <Myns::QVariant (int)> = {"400"}
         keyboardInputInterval = <Myns::QVariant (int)> = {"400"}
         wheelScrollLines = <Myns::QVariant (int)> = {"3"}
         globalStrut = <Myns::QVariant (QSize)> = {"(0, 0)"}
         startDragTime = <Myns::QVariant (int)> = {"500"}
         startDragDistance = <Myns::QVariant (int)> = {"10"}
         styleSheet = <Myns::QVariant (QString)> = {""}
         autoSipEnabled = <Myns::QVariant (bool)> = {"true"}
      ],"<10 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp ss
ss =
   <Myns::QString> = {"Hello"}
Change-Id: I6e4714a5cfe34c38917500d114ad9a70d20cff39
Reviewed-by: Christian Stenger <christian.stenger@digia.com>
Reviewed-by: hjk <hjk121@nokiamail.com>
											
										 
											2014-06-13 17:45:34 +02:00
										 |  |  |     def putBaseClassName(self, name): | 
					
						
							| 
									
										
										
										
											2014-06-17 09:02:01 +02:00
										 |  |  |         self.put('iname="%s",' % self.currentIName) | 
					
						
							| 
									
										
											  
											
												Debugger: Make dumpers somewhat work in command line GDB
With
    python sys.path.insert(1, '/data/dev/creator/share/qtcreator/debugger/')
    python from gdbbridge import *
in .gdbinit there's a new "GDB command", called "pp".
With code like
    int main(int argc, char *argv[])
    {
        QString ss = "Hello";
        QApplication app(argc, argv);
        app.setObjectName(ss);
        // break here
    }
the 'pp' command can be used as follows:
(gdb) pp app
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = <Myns::QObjectList> = {"<3 items>"}
      [properties] = "<>0 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp app [properties],[children]
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = [
         <Myns::QObject> = {""}
         <Myns::QObject> = {""}
         <Myns::QObject> = {"fusion"}
      ],<Myns::QObjectList> = {"<3 items>"}
      [properties] = [
         windowIcon = <Myns::QVariant (QIcon)> = {""}
         cursorFlashTime = <Myns::QVariant (int)> = {"1000"}
         doubleClickInterval = <Myns::QVariant (int)> = {"400"}
         keyboardInputInterval = <Myns::QVariant (int)> = {"400"}
         wheelScrollLines = <Myns::QVariant (int)> = {"3"}
         globalStrut = <Myns::QVariant (QSize)> = {"(0, 0)"}
         startDragTime = <Myns::QVariant (int)> = {"500"}
         startDragDistance = <Myns::QVariant (int)> = {"10"}
         styleSheet = <Myns::QVariant (QString)> = {""}
         autoSipEnabled = <Myns::QVariant (bool)> = {"true"}
      ],"<10 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp ss
ss =
   <Myns::QString> = {"Hello"}
Change-Id: I6e4714a5cfe34c38917500d114ad9a70d20cff39
Reviewed-by: Christian Stenger <christian.stenger@digia.com>
Reviewed-by: hjk <hjk121@nokiamail.com>
											
										 
											2014-06-13 17:45:34 +02:00
										 |  |  |         self.put('name="[%s]",' % name) | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |     def listAnonymous(self, value, name, typeobj): | 
					
						
							|  |  |  |         for field in typeobj.fields(): | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |             #warn("FIELD NAME: %s" % field.name) | 
					
						
							| 
									
										
										
										
											2014-06-16 18:10:02 +02:00
										 |  |  |             if field.name: | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  |                 with SubItem(self, field.name): | 
					
						
							|  |  |  |                     self.putItem(value[field.name]) | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 # Further nested. | 
					
						
							|  |  |  |                 self.anonNumber += 1 | 
					
						
							|  |  |  |                 name = "#%d" % self.anonNumber | 
					
						
							|  |  |  |                 #iname = "%s.%s" % (selitem.iname, name) | 
					
						
							|  |  |  |                 #child = SameItem(item.value, iname) | 
					
						
							|  |  |  |                 with SubItem(self, name): | 
					
						
							|  |  |  |                     self.put('name="%s",' % name) | 
					
						
							|  |  |  |                     self.putEmptyValue() | 
					
						
							|  |  |  |                     fieldTypeName = str(field.type) | 
					
						
							|  |  |  |                     if fieldTypeName.endswith("<anonymous union>"): | 
					
						
							|  |  |  |                         self.putType("<anonymous union>") | 
					
						
							|  |  |  |                     elif fieldTypeName.endswith("<anonymous struct>"): | 
					
						
							|  |  |  |                         self.putType("<anonymous struct>") | 
					
						
							|  |  |  |                     else: | 
					
						
							|  |  |  |                         self.putType(fieldTypeName) | 
					
						
							|  |  |  |                     with Children(self, 1): | 
					
						
							|  |  |  |                         self.listAnonymous(value, name, field.type) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-11 13:24:19 +01:00
										 |  |  |     #def threadname(self, maximalStackDepth, objectPrivateType): | 
					
						
							|  |  |  |     #    e = gdb.selected_frame() | 
					
						
							|  |  |  |     #    out = "" | 
					
						
							|  |  |  |     #    ns = self.qtNamespace() | 
					
						
							|  |  |  |     #    while True: | 
					
						
							|  |  |  |     #        maximalStackDepth -= 1 | 
					
						
							|  |  |  |     #        if maximalStackDepth < 0: | 
					
						
							|  |  |  |     #            break | 
					
						
							|  |  |  |     #        e = e.older() | 
					
						
							|  |  |  |     #        if e == None or e.name() == None: | 
					
						
							|  |  |  |     #            break | 
					
						
							|  |  |  |     #        if e.name() == ns + "QThreadPrivate::start" \ | 
					
						
							|  |  |  |     #                or e.name() == "_ZN14QThreadPrivate5startEPv@4": | 
					
						
							|  |  |  |     #            try: | 
					
						
							|  |  |  |     #                thrptr = e.read_var("thr").dereference() | 
					
						
							|  |  |  |     #                d_ptr = thrptr["d_ptr"]["d"].cast(objectPrivateType).dereference() | 
					
						
							|  |  |  |     #                try: | 
					
						
							|  |  |  |     #                    objectName = d_ptr["objectName"] | 
					
						
							|  |  |  |     #                except: # Qt 5 | 
					
						
							|  |  |  |     #                    p = d_ptr["extraData"] | 
					
						
							|  |  |  |     #                    if not self.isNull(p): | 
					
						
							|  |  |  |     #                        objectName = p.dereference()["objectName"] | 
					
						
							|  |  |  |     #                if not objectName is None: | 
					
						
							|  |  |  |     #                    data, size, alloc = self.stringData(objectName) | 
					
						
							|  |  |  |     #                    if size > 0: | 
					
						
							|  |  |  |     #                         s = self.readMemory(data, 2 * size) | 
					
						
							|  |  |  |     # | 
					
						
							|  |  |  |     #                thread = gdb.selected_thread() | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |     #                inner = '{valueencoded="uf16:2:0",id="' | 
					
						
							| 
									
										
										
										
											2014-03-11 13:24:19 +01:00
										 |  |  |     #                inner += str(thread.num) + '",value="' | 
					
						
							|  |  |  |     #                inner += s | 
					
						
							|  |  |  |     #                #inner += self.encodeString(objectName) | 
					
						
							|  |  |  |     #                inner += '"},' | 
					
						
							|  |  |  |     # | 
					
						
							|  |  |  |     #                out += inner | 
					
						
							|  |  |  |     #            except: | 
					
						
							|  |  |  |     #                pass | 
					
						
							|  |  |  |     #    return out | 
					
						
							| 
									
										
										
										
											2013-10-30 12:38:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def threadnames(self, maximalStackDepth): | 
					
						
							| 
									
										
										
										
											2013-11-20 00:34:58 +01:00
										 |  |  |         # FIXME: This needs a proper implementation for MinGW, and only there. | 
					
						
							| 
									
										
										
										
											2014-03-11 13:24:19 +01:00
										 |  |  |         # Linux, Mac and QNX mirror the objectName() to the underlying threads, | 
					
						
							| 
									
										
										
										
											2013-11-20 00:34:58 +01:00
										 |  |  |         # so we get the names already as part of the -thread-info output. | 
					
						
							|  |  |  |         return '[]' | 
					
						
							| 
									
										
										
										
											2014-03-11 13:24:19 +01:00
										 |  |  |         #out = '[' | 
					
						
							|  |  |  |         #oldthread = gdb.selected_thread() | 
					
						
							|  |  |  |         #if oldthread: | 
					
						
							|  |  |  |         #    try: | 
					
						
							|  |  |  |         #        objectPrivateType = gdb.lookup_type(ns + "QObjectPrivate").pointer() | 
					
						
							|  |  |  |         #        inferior = self.selectedInferior() | 
					
						
							|  |  |  |         #        for thread in inferior.threads(): | 
					
						
							|  |  |  |         #            thread.switch() | 
					
						
							|  |  |  |         #            out += self.threadname(maximalStackDepth, objectPrivateType) | 
					
						
							|  |  |  |         #    except: | 
					
						
							|  |  |  |         #        pass | 
					
						
							|  |  |  |         #    oldthread.switch() | 
					
						
							|  |  |  |         #return out + ']' | 
					
						
							| 
									
										
										
										
											2013-10-30 12:38:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-30 15:07:54 +01:00
										 |  |  |     def importPlainDumper(self, printer): | 
					
						
							|  |  |  |         name = printer.name.replace("::", "__") | 
					
						
							|  |  |  |         self.qqDumpers[name] = PlainDumper(printer) | 
					
						
							|  |  |  |         self.qqFormats[name] = "" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def importPlainDumpers(self): | 
					
						
							|  |  |  |         for obj in gdb.objfiles(): | 
					
						
							|  |  |  |             for printers in obj.pretty_printers + gdb.pretty_printers: | 
					
						
							|  |  |  |                 for printer in printers.subprinters: | 
					
						
							|  |  |  |                     self.importPlainDumper(printer) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def qtNamespace(self): | 
					
						
							| 
									
										
										
										
											2014-03-27 13:53:33 +01:00
										 |  |  |         if not self.currentQtNamespaceGuess is None: | 
					
						
							|  |  |  |             return self.currentQtNamespaceGuess | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-07 15:48:13 +01:00
										 |  |  |         # This only works when called from a valid frame. | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             cand = "QArrayData::shared_null" | 
					
						
							|  |  |  |             symbol = gdb.lookup_symbol(cand)[0] | 
					
						
							|  |  |  |             if symbol: | 
					
						
							|  |  |  |                 ns = symbol.name[:-len(cand)] | 
					
						
							|  |  |  |                 self.qtNamespaceToReport = ns | 
					
						
							|  |  |  |                 self.qtNamespace = lambda: ns | 
					
						
							|  |  |  |                 return ns | 
					
						
							|  |  |  |         except: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-30 15:07:54 +01:00
										 |  |  |         try: | 
					
						
							| 
									
										
										
										
											2014-03-07 15:48:13 +01:00
										 |  |  |             # This is Qt, but not 5.x. | 
					
						
							|  |  |  |             cand = "QByteArray::shared_null" | 
					
						
							|  |  |  |             symbol = gdb.lookup_symbol(cand)[0] | 
					
						
							|  |  |  |             if symbol: | 
					
						
							|  |  |  |                 ns = symbol.name[:-len(cand)] | 
					
						
							|  |  |  |                 self.qtNamespaceToReport = ns | 
					
						
							|  |  |  |                 self.qtNamespace = lambda: ns | 
					
						
							|  |  |  |                 self.fallbackQtVersion = 0x40800 | 
					
						
							|  |  |  |                 return ns | 
					
						
							| 
									
										
										
										
											2013-10-30 15:07:54 +01:00
										 |  |  |         except: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-24 13:22:19 +02:00
										 |  |  |         try: | 
					
						
							| 
									
										
										
										
											2014-10-10 12:05:47 +02:00
										 |  |  |             # Last fall backs. | 
					
						
							| 
									
										
										
										
											2014-07-24 13:22:19 +02:00
										 |  |  |             s = gdb.execute("ptype QByteArray", to_string=True) | 
					
						
							| 
									
										
										
										
											2014-10-10 12:05:47 +02:00
										 |  |  |             if s.find("QMemArray") >= 0: | 
					
						
							|  |  |  |                 # Qt 3. | 
					
						
							|  |  |  |                 self.qtNamespaceToReport = "" | 
					
						
							|  |  |  |                 self.qtNamespace = lambda: "" | 
					
						
							|  |  |  |                 self.qtVersion = lambda: 0x30308 | 
					
						
							|  |  |  |                 self.fallbackQtVersion = 0x30308 | 
					
						
							|  |  |  |                 return "" | 
					
						
							|  |  |  |             # Seemingly needed with Debian's GDB 7.4.1 | 
					
						
							| 
									
										
										
										
											2014-07-24 13:22:19 +02:00
										 |  |  |             ns = s[s.find("class")+6:s.find("QByteArray")] | 
					
						
							|  |  |  |             if len(ns): | 
					
						
							|  |  |  |                 self.qtNamespaceToReport = ns | 
					
						
							|  |  |  |                 self.qtNamespace = lambda: ns | 
					
						
							|  |  |  |                 return ns | 
					
						
							|  |  |  |         except: | 
					
						
							|  |  |  |             pass | 
					
						
							| 
									
										
										
										
											2014-03-27 13:53:33 +01:00
										 |  |  |         self.currentQtNamespaceGuess = "" | 
					
						
							| 
									
										
										
										
											2014-03-07 15:48:13 +01:00
										 |  |  |         return "" | 
					
						
							| 
									
										
										
										
											2013-10-30 15:07:54 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-10 13:40:26 +01:00
										 |  |  |     def assignValue(self, args): | 
					
						
							|  |  |  |         typeName = self.hexdecode(args['type']) | 
					
						
							|  |  |  |         expr = self.hexdecode(args['expr']) | 
					
						
							|  |  |  |         value = self.hexdecode(args['value']) | 
					
						
							|  |  |  |         simpleType = int(args['simpleType']) | 
					
						
							| 
									
										
										
										
											2013-10-30 15:07:54 +01:00
										 |  |  |         ns = self.qtNamespace() | 
					
						
							| 
									
										
										
										
											2013-11-20 18:55:09 +01:00
										 |  |  |         if typeName.startswith(ns): | 
					
						
							|  |  |  |             typeName = typeName[len(ns):] | 
					
						
							|  |  |  |         typeName = typeName.replace("::", "__") | 
					
						
							|  |  |  |         pos = typeName.find('<') | 
					
						
							| 
									
										
										
										
											2013-10-30 15:07:54 +01:00
										 |  |  |         if pos != -1: | 
					
						
							| 
									
										
										
										
											2013-11-20 18:55:09 +01:00
										 |  |  |             typeName = typeName[0:pos] | 
					
						
							| 
									
										
										
										
											2015-02-10 13:40:26 +01:00
										 |  |  |         if typeName in self.qqEditable and not simpleType: | 
					
						
							|  |  |  |             #self.qqEditable[typeName](self, expr, value) | 
					
						
							|  |  |  |             expr = gdb.parse_and_eval(expr) | 
					
						
							|  |  |  |             self.qqEditable[typeName](self, expr, value) | 
					
						
							| 
									
										
										
										
											2013-10-30 15:07:54 +01:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2015-02-10 13:40:26 +01:00
										 |  |  |             cmd = "set variable (%s)=%s" % (expr, value) | 
					
						
							| 
									
										
										
										
											2013-11-20 18:55:09 +01:00
										 |  |  |             gdb.execute(cmd) | 
					
						
							| 
									
										
										
										
											2013-10-30 15:07:54 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |     def hasVTable(self, typeobj): | 
					
						
							|  |  |  |         fields = typeobj.fields() | 
					
						
							| 
									
										
										
										
											2013-10-31 10:28:11 +01:00
										 |  |  |         if len(fields) == 0: | 
					
						
							|  |  |  |             return False | 
					
						
							|  |  |  |         if fields[0].is_base_class: | 
					
						
							|  |  |  |             return hasVTable(fields[0].type) | 
					
						
							|  |  |  |         return str(fields[0].type) ==  "int (**)(void)" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def dynamicTypeName(self, value): | 
					
						
							|  |  |  |         if self.hasVTable(value.type): | 
					
						
							| 
									
										
										
										
											2014-02-21 17:34:08 +01:00
										 |  |  |             #vtbl = str(gdb.parse_and_eval("{int(*)(int)}%s" % int(value.address))) | 
					
						
							| 
									
										
										
										
											2013-10-31 10:28:11 +01:00
										 |  |  |             try: | 
					
						
							|  |  |  |                 # Fails on 7.1 due to the missing to_string. | 
					
						
							|  |  |  |                 vtbl = gdb.execute("info symbol {int*}%s" % int(value.address), | 
					
						
							|  |  |  |                     to_string = True) | 
					
						
							|  |  |  |                 pos1 = vtbl.find("vtable ") | 
					
						
							|  |  |  |                 if pos1 != -1: | 
					
						
							|  |  |  |                     pos1 += 11 | 
					
						
							|  |  |  |                     pos2 = vtbl.find(" +", pos1) | 
					
						
							|  |  |  |                     if pos2 != -1: | 
					
						
							|  |  |  |                         return vtbl[pos1 : pos2] | 
					
						
							|  |  |  |             except: | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  |         return str(value.type) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def downcast(self, value): | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             return value.cast(value.dynamic_type) | 
					
						
							|  |  |  |         except: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  |         #try: | 
					
						
							|  |  |  |         #    return value.cast(self.lookupType(self.dynamicTypeName(value))) | 
					
						
							|  |  |  |         #except: | 
					
						
							|  |  |  |         #    pass | 
					
						
							|  |  |  |         return value | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def expensiveDowncast(self, value): | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             return value.cast(value.dynamic_type) | 
					
						
							|  |  |  |         except: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             return value.cast(self.lookupType(self.dynamicTypeName(value))) | 
					
						
							|  |  |  |         except: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  |         return value | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |     def addToCache(self, typeobj): | 
					
						
							|  |  |  |         typename = str(typeobj) | 
					
						
							| 
									
										
										
										
											2013-10-31 10:28:11 +01:00
										 |  |  |         if typename in self.typesReported: | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  |         self.typesReported[typename] = True | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |         self.typesToReport[typename] = typeobj | 
					
						
							| 
									
										
										
										
											2013-10-31 10:28:11 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-10 20:01:35 +01:00
										 |  |  |     def enumExpression(self, enumType, enumValue): | 
					
						
							|  |  |  |         return self.qtNamespace() + "Qt::" + enumValue | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-31 10:28:11 +01:00
										 |  |  |     def lookupType(self, typestring): | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |         typeobj = self.typeCache.get(typestring) | 
					
						
							|  |  |  |         #warn("LOOKUP 1: %s -> %s" % (typestring, typeobj)) | 
					
						
							|  |  |  |         if not typeobj is None: | 
					
						
							|  |  |  |             return typeobj | 
					
						
							| 
									
										
										
										
											2013-10-31 10:28:11 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if typestring == "void": | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |             typeobj = gdb.lookup_type(typestring) | 
					
						
							|  |  |  |             self.typeCache[typestring] = typeobj | 
					
						
							|  |  |  |             self.typesToReport[typestring] = typeobj | 
					
						
							|  |  |  |             return typeobj | 
					
						
							| 
									
										
										
										
											2013-10-31 10:28:11 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         #try: | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |         #    typeobj = gdb.parse_and_eval("{%s}&main" % typestring).typeobj | 
					
						
							|  |  |  |         #    if not typeobj is None: | 
					
						
							|  |  |  |         #        self.typeCache[typestring] = typeobj | 
					
						
							|  |  |  |         #        self.typesToReport[typestring] = typeobj | 
					
						
							|  |  |  |         #        return typeobj | 
					
						
							| 
									
										
										
										
											2013-10-31 10:28:11 +01:00
										 |  |  |         #except: | 
					
						
							|  |  |  |         #    pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # See http://sourceware.org/bugzilla/show_bug.cgi?id=13269 | 
					
						
							|  |  |  |         # gcc produces "{anonymous}", gdb "(anonymous namespace)" | 
					
						
							|  |  |  |         # "<unnamed>" has been seen too. The only thing gdb | 
					
						
							|  |  |  |         # understands when reading things back is "(anonymous namespace)" | 
					
						
							|  |  |  |         if typestring.find("{anonymous}") != -1: | 
					
						
							|  |  |  |             ts = typestring | 
					
						
							|  |  |  |             ts = ts.replace("{anonymous}", "(anonymous namespace)") | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |             typeobj = self.lookupType(ts) | 
					
						
							|  |  |  |             if not typeobj is None: | 
					
						
							|  |  |  |                 self.typeCache[typestring] = typeobj | 
					
						
							|  |  |  |                 self.typesToReport[typestring] = typeobj | 
					
						
							|  |  |  |                 return typeobj | 
					
						
							| 
									
										
										
										
											2013-10-31 10:28:11 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |         #warn(" RESULT FOR 7.2: '%s': %s" % (typestring, typeobj)) | 
					
						
							| 
									
										
										
										
											2013-10-31 10:28:11 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # This part should only trigger for | 
					
						
							|  |  |  |         # gdb 7.1 for types with namespace separators. | 
					
						
							|  |  |  |         # And anonymous namespaces. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         ts = typestring | 
					
						
							|  |  |  |         while True: | 
					
						
							|  |  |  |             #warn("TS: '%s'" % ts) | 
					
						
							|  |  |  |             if ts.startswith("class "): | 
					
						
							|  |  |  |                 ts = ts[6:] | 
					
						
							|  |  |  |             elif ts.startswith("struct "): | 
					
						
							|  |  |  |                 ts = ts[7:] | 
					
						
							|  |  |  |             elif ts.startswith("const "): | 
					
						
							|  |  |  |                 ts = ts[6:] | 
					
						
							|  |  |  |             elif ts.startswith("volatile "): | 
					
						
							|  |  |  |                 ts = ts[9:] | 
					
						
							|  |  |  |             elif ts.startswith("enum "): | 
					
						
							|  |  |  |                 ts = ts[5:] | 
					
						
							|  |  |  |             elif ts.endswith(" const"): | 
					
						
							|  |  |  |                 ts = ts[:-6] | 
					
						
							|  |  |  |             elif ts.endswith(" volatile"): | 
					
						
							|  |  |  |                 ts = ts[:-9] | 
					
						
							|  |  |  |             elif ts.endswith("*const"): | 
					
						
							|  |  |  |                 ts = ts[:-5] | 
					
						
							|  |  |  |             elif ts.endswith("*volatile"): | 
					
						
							|  |  |  |                 ts = ts[:-8] | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 break | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ts.endswith('*'): | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |             typeobj = self.lookupType(ts[0:-1]) | 
					
						
							|  |  |  |             if not typeobj is None: | 
					
						
							|  |  |  |                 typeobj = typeobj.pointer() | 
					
						
							|  |  |  |                 self.typeCache[typestring] = typeobj | 
					
						
							|  |  |  |                 self.typesToReport[typestring] = typeobj | 
					
						
							|  |  |  |                 return typeobj | 
					
						
							| 
									
										
										
										
											2013-10-31 10:28:11 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             #warn("LOOKING UP '%s'" % ts) | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |             typeobj = gdb.lookup_type(ts) | 
					
						
							| 
									
										
										
										
											2013-10-31 10:28:11 +01:00
										 |  |  |         except RuntimeError as error: | 
					
						
							|  |  |  |             #warn("LOOKING UP '%s': %s" % (ts, error)) | 
					
						
							|  |  |  |             # See http://sourceware.org/bugzilla/show_bug.cgi?id=11912 | 
					
						
							|  |  |  |             exp = "(class '%s'*)0" % ts | 
					
						
							|  |  |  |             try: | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |                 typeobj = self.parseAndEvaluate(exp).type.target() | 
					
						
							| 
									
										
										
										
											2013-10-31 10:28:11 +01:00
										 |  |  |             except: | 
					
						
							|  |  |  |                 # Can throw "RuntimeError: No type named class Foo." | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  |         except: | 
					
						
							|  |  |  |             #warn("LOOKING UP '%s' FAILED" % ts) | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |         if not typeobj is None: | 
					
						
							|  |  |  |             self.typeCache[typestring] = typeobj | 
					
						
							|  |  |  |             self.typesToReport[typestring] = typeobj | 
					
						
							|  |  |  |             return typeobj | 
					
						
							| 
									
										
										
										
											2013-10-31 10:28:11 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # This could still be None as gdb.lookup_type("char[3]") generates | 
					
						
							|  |  |  |         # "RuntimeError: No type named char[3]" | 
					
						
							| 
									
										
										
										
											2014-12-12 09:00:30 +01:00
										 |  |  |         self.typeCache[typestring] = typeobj | 
					
						
							|  |  |  |         self.typesToReport[typestring] = typeobj | 
					
						
							|  |  |  |         return typeobj | 
					
						
							| 
									
										
										
										
											2013-10-31 10:28:11 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |     def doContinue(self): | 
					
						
							|  |  |  |         gdb.execute('continue') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-27 16:13:04 +01:00
										 |  |  |     def fetchStack(self, args): | 
					
						
							| 
									
										
										
										
											2015-03-01 11:49:19 +02:00
										 |  |  |         def fromNativePath(str): | 
					
						
							| 
									
										
										
										
											2015-05-09 14:49:19 +01:00
										 |  |  |             return str.replace('\\', '/') | 
					
						
							| 
									
										
										
										
											2015-03-01 11:49:19 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-11 16:05:55 +01:00
										 |  |  |         limit = int(args['limit']) | 
					
						
							|  |  |  |         if limit <= 0: | 
					
						
							|  |  |  |            limit = 10000 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |         self.prepare(args) | 
					
						
							| 
									
										
										
										
											2014-12-05 18:45:54 +01:00
										 |  |  |         self.output = [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         frame = gdb.newest_frame() | 
					
						
							|  |  |  |         i = 0 | 
					
						
							| 
									
										
										
										
											2015-01-22 12:05:00 +01:00
										 |  |  |         self.currentCallContext = None | 
					
						
							| 
									
										
										
										
											2015-02-11 16:05:55 +01:00
										 |  |  |         while i < limit and frame: | 
					
						
							| 
									
										
										
										
											2014-12-05 18:45:54 +01:00
										 |  |  |             with OutputSafer(self): | 
					
						
							|  |  |  |                 name = frame.name() | 
					
						
							|  |  |  |                 functionName = "??" if name is None else name | 
					
						
							|  |  |  |                 fileName = "" | 
					
						
							|  |  |  |                 objfile = "" | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |                 symtab = "" | 
					
						
							| 
									
										
										
										
											2014-12-05 18:45:54 +01:00
										 |  |  |                 pc = frame.pc() | 
					
						
							|  |  |  |                 sal = frame.find_sal() | 
					
						
							|  |  |  |                 line = -1 | 
					
						
							|  |  |  |                 if sal: | 
					
						
							|  |  |  |                     line = sal.line | 
					
						
							|  |  |  |                     symtab = sal.symtab | 
					
						
							|  |  |  |                     if not symtab is None: | 
					
						
							| 
									
										
										
										
											2015-03-01 11:49:19 +02:00
										 |  |  |                         objfile = fromNativePath(symtab.objfile.filename) | 
					
						
							| 
									
										
										
										
											2015-11-20 09:29:51 -06:00
										 |  |  |                         fullname = symtab.fullname() | 
					
						
							|  |  |  |                         if fullname is None: | 
					
						
							|  |  |  |                             fileName = "" | 
					
						
							|  |  |  |                         else: | 
					
						
							|  |  |  |                             fileName = fromNativePath(fullname) | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-14 13:26:22 +02:00
										 |  |  |                 if self.nativeMixed and functionName == "qt_qmlDebugMessageAvailable": | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |                     interpreterStack = self.extractInterpreterStack() | 
					
						
							|  |  |  |                     #print("EXTRACTED INTEPRETER STACK: %s" % interpreterStack) | 
					
						
							|  |  |  |                     for interpreterFrame in interpreterStack.get('frames', []): | 
					
						
							|  |  |  |                         function = interpreterFrame.get('function', '') | 
					
						
							|  |  |  |                         fileName = interpreterFrame.get('file', '') | 
					
						
							|  |  |  |                         language = interpreterFrame.get('language', '') | 
					
						
							|  |  |  |                         lineNumber = interpreterFrame.get('line', 0) | 
					
						
							|  |  |  |                         context = interpreterFrame.get('context', 0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                         self.put(('frame={function="%s",file="%s",' | 
					
						
							|  |  |  |                                  'line="%s",language="%s",context="%s"}') | 
					
						
							|  |  |  |                             % (function, fileName, lineNumber, language, context)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     if False and self.isInternalInterpreterFrame(functionName): | 
					
						
							| 
									
										
										
										
											2015-01-22 12:05:00 +01:00
										 |  |  |                         frame = frame.older() | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |                         self.put(('frame={address="0x%x",function="%s",' | 
					
						
							|  |  |  |                                 'file="%s",line="%s",' | 
					
						
							|  |  |  |                                 'module="%s",language="c",usable="0"}') % | 
					
						
							|  |  |  |                             (pc, functionName, fileName, line, objfile)) | 
					
						
							| 
									
										
										
										
											2015-01-22 12:05:00 +01:00
										 |  |  |                         i += 1 | 
					
						
							|  |  |  |                         frame = frame.older() | 
					
						
							|  |  |  |                         continue | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |                 self.put(('frame={level="%s",address="0x%x",function="%s",' | 
					
						
							|  |  |  |                         'file="%s",line="%s",module="%s",language="c"}') % | 
					
						
							|  |  |  |                     (i, pc, functionName, fileName, line, objfile)) | 
					
						
							| 
									
										
										
										
											2014-12-05 18:45:54 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |             frame = frame.older() | 
					
						
							|  |  |  |             i += 1 | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |         safePrint('frames=[' + ','.join(self.output) + ']') | 
					
						
							| 
									
										
										
										
											2014-12-05 18:45:54 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-04 16:27:46 +01:00
										 |  |  |     def createResolvePendingBreakpointsHookBreakpoint(self, args): | 
					
						
							| 
									
										
										
										
											2015-02-04 10:48:33 +01:00
										 |  |  |         class Resolver(gdb.Breakpoint): | 
					
						
							| 
									
										
										
										
											2015-02-04 16:27:46 +01:00
										 |  |  |             def __init__(self, dumper, args): | 
					
						
							| 
									
										
										
										
											2015-02-04 10:48:33 +01:00
										 |  |  |                 self.dumper = dumper | 
					
						
							| 
									
										
										
										
											2015-02-04 16:27:46 +01:00
										 |  |  |                 self.args = args | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |                 spec = "qt_qmlDebugConnectorOpen" | 
					
						
							| 
									
										
										
										
											2015-02-04 10:48:33 +01:00
										 |  |  |                 super(Resolver, self).\ | 
					
						
							|  |  |  |                     __init__(spec, gdb.BP_BREAKPOINT, internal=True, temporary=False) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             def stop(self): | 
					
						
							| 
									
										
										
										
											2015-10-14 13:26:22 +02:00
										 |  |  |                 self.dumper.resolvePendingInterpreterBreakpoint(args) | 
					
						
							| 
									
										
										
										
											2015-02-04 10:48:33 +01:00
										 |  |  |                 self.enabled = False | 
					
						
							|  |  |  |                 return False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-09 15:00:20 +02:00
										 |  |  |         self.interpreterBreakpointResolvers.append(Resolver(self, args)) | 
					
						
							| 
									
										
										
										
											2015-02-04 10:48:33 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-11 12:20:21 +01:00
										 |  |  |     def exitGdb(self, _): | 
					
						
							|  |  |  |         gdb.execute("quit") | 
					
						
							| 
									
										
										
										
											2015-02-04 10:48:33 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-18 16:48:57 +01:00
										 |  |  |     def loadDumpers(self, args): | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |         print(self.setupDumpers()) | 
					
						
							| 
									
										
										
										
											2015-03-18 16:48:57 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-11 17:51:15 +01:00
										 |  |  |     def profile1(self, args): | 
					
						
							|  |  |  |         """Internal profiling""" | 
					
						
							|  |  |  |         import tempfile | 
					
						
							|  |  |  |         import cProfile | 
					
						
							|  |  |  |         tempDir = tempfile.gettempdir() + "/bbprof" | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |         cProfile.run('theDumper.fetchVariables(%s)' % args, tempDir) | 
					
						
							| 
									
										
										
										
											2015-02-11 17:51:15 +01:00
										 |  |  |         import pstats | 
					
						
							|  |  |  |         pstats.Stats(tempDir).sort_stats('time').print_stats() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def profile2(self, args): | 
					
						
							|  |  |  |         import timeit | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |         print(timeit.repeat('theDumper.fetchVariables(%s)' % args, | 
					
						
							| 
									
										
										
										
											2015-02-11 17:51:15 +01:00
										 |  |  |             'from __main__ import theDumper', number=10)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-04 10:48:33 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												Debugger: Make dumpers somewhat work in command line GDB
With
    python sys.path.insert(1, '/data/dev/creator/share/qtcreator/debugger/')
    python from gdbbridge import *
in .gdbinit there's a new "GDB command", called "pp".
With code like
    int main(int argc, char *argv[])
    {
        QString ss = "Hello";
        QApplication app(argc, argv);
        app.setObjectName(ss);
        // break here
    }
the 'pp' command can be used as follows:
(gdb) pp app
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = <Myns::QObjectList> = {"<3 items>"}
      [properties] = "<>0 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp app [properties],[children]
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = [
         <Myns::QObject> = {""}
         <Myns::QObject> = {""}
         <Myns::QObject> = {"fusion"}
      ],<Myns::QObjectList> = {"<3 items>"}
      [properties] = [
         windowIcon = <Myns::QVariant (QIcon)> = {""}
         cursorFlashTime = <Myns::QVariant (int)> = {"1000"}
         doubleClickInterval = <Myns::QVariant (int)> = {"400"}
         keyboardInputInterval = <Myns::QVariant (int)> = {"400"}
         wheelScrollLines = <Myns::QVariant (int)> = {"3"}
         globalStrut = <Myns::QVariant (QSize)> = {"(0, 0)"}
         startDragTime = <Myns::QVariant (int)> = {"500"}
         startDragDistance = <Myns::QVariant (int)> = {"10"}
         styleSheet = <Myns::QVariant (QString)> = {""}
         autoSipEnabled = <Myns::QVariant (bool)> = {"true"}
      ],"<10 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp ss
ss =
   <Myns::QString> = {"Hello"}
Change-Id: I6e4714a5cfe34c38917500d114ad9a70d20cff39
Reviewed-by: Christian Stenger <christian.stenger@digia.com>
Reviewed-by: hjk <hjk121@nokiamail.com>
											
										 
											2014-06-13 17:45:34 +02:00
										 |  |  | class CliDumper(Dumper): | 
					
						
							|  |  |  |     def __init__(self): | 
					
						
							|  |  |  |         Dumper.__init__(self) | 
					
						
							|  |  |  |         self.childrenPrefix = '[' | 
					
						
							|  |  |  |         self.chidrenSuffix = '] ' | 
					
						
							|  |  |  |         self.indent = 0 | 
					
						
							|  |  |  |         self.isCli = True | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-15 12:38:11 +02:00
										 |  |  |     def reportDumpers(self, msg): | 
					
						
							|  |  |  |         return msg | 
					
						
							| 
									
										
											  
											
												Debugger: Make dumpers somewhat work in command line GDB
With
    python sys.path.insert(1, '/data/dev/creator/share/qtcreator/debugger/')
    python from gdbbridge import *
in .gdbinit there's a new "GDB command", called "pp".
With code like
    int main(int argc, char *argv[])
    {
        QString ss = "Hello";
        QApplication app(argc, argv);
        app.setObjectName(ss);
        // break here
    }
the 'pp' command can be used as follows:
(gdb) pp app
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = <Myns::QObjectList> = {"<3 items>"}
      [properties] = "<>0 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp app [properties],[children]
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = [
         <Myns::QObject> = {""}
         <Myns::QObject> = {""}
         <Myns::QObject> = {"fusion"}
      ],<Myns::QObjectList> = {"<3 items>"}
      [properties] = [
         windowIcon = <Myns::QVariant (QIcon)> = {""}
         cursorFlashTime = <Myns::QVariant (int)> = {"1000"}
         doubleClickInterval = <Myns::QVariant (int)> = {"400"}
         keyboardInputInterval = <Myns::QVariant (int)> = {"400"}
         wheelScrollLines = <Myns::QVariant (int)> = {"3"}
         globalStrut = <Myns::QVariant (QSize)> = {"(0, 0)"}
         startDragTime = <Myns::QVariant (int)> = {"500"}
         startDragDistance = <Myns::QVariant (int)> = {"10"}
         styleSheet = <Myns::QVariant (QString)> = {""}
         autoSipEnabled = <Myns::QVariant (bool)> = {"true"}
      ],"<10 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp ss
ss =
   <Myns::QString> = {"Hello"}
Change-Id: I6e4714a5cfe34c38917500d114ad9a70d20cff39
Reviewed-by: Christian Stenger <christian.stenger@digia.com>
Reviewed-by: hjk <hjk121@nokiamail.com>
											
										 
											2014-06-13 17:45:34 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def enterSubItem(self, item): | 
					
						
							|  |  |  |         if not item.iname: | 
					
						
							|  |  |  |             item.iname = "%s.%s" % (self.currentIName, item.name) | 
					
						
							|  |  |  |         self.indent += 1 | 
					
						
							|  |  |  |         self.putNewline() | 
					
						
							|  |  |  |         if isinstance(item.name, str): | 
					
						
							|  |  |  |             self.output += item.name + ' = ' | 
					
						
							|  |  |  |         item.savedIName = self.currentIName | 
					
						
							|  |  |  |         item.savedValue = self.currentValue | 
					
						
							|  |  |  |         item.savedType = self.currentType | 
					
						
							|  |  |  |         item.savedCurrentAddress = self.currentAddress | 
					
						
							|  |  |  |         self.currentIName = item.iname | 
					
						
							|  |  |  |         self.currentValue = ReportItem(); | 
					
						
							|  |  |  |         self.currentType = ReportItem(); | 
					
						
							|  |  |  |         self.currentAddress = None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def exitSubItem(self, item, exType, exValue, exTraceBack): | 
					
						
							|  |  |  |         self.indent -= 1 | 
					
						
							| 
									
										
										
										
											2014-12-12 10:12:23 +01:00
										 |  |  |         #warn("CURRENT VALUE: %s: %s %s" % | 
					
						
							|  |  |  |         #  (self.currentIName, self.currentValue, self.currentType)) | 
					
						
							| 
									
										
											  
											
												Debugger: Make dumpers somewhat work in command line GDB
With
    python sys.path.insert(1, '/data/dev/creator/share/qtcreator/debugger/')
    python from gdbbridge import *
in .gdbinit there's a new "GDB command", called "pp".
With code like
    int main(int argc, char *argv[])
    {
        QString ss = "Hello";
        QApplication app(argc, argv);
        app.setObjectName(ss);
        // break here
    }
the 'pp' command can be used as follows:
(gdb) pp app
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = <Myns::QObjectList> = {"<3 items>"}
      [properties] = "<>0 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp app [properties],[children]
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = [
         <Myns::QObject> = {""}
         <Myns::QObject> = {""}
         <Myns::QObject> = {"fusion"}
      ],<Myns::QObjectList> = {"<3 items>"}
      [properties] = [
         windowIcon = <Myns::QVariant (QIcon)> = {""}
         cursorFlashTime = <Myns::QVariant (int)> = {"1000"}
         doubleClickInterval = <Myns::QVariant (int)> = {"400"}
         keyboardInputInterval = <Myns::QVariant (int)> = {"400"}
         wheelScrollLines = <Myns::QVariant (int)> = {"3"}
         globalStrut = <Myns::QVariant (QSize)> = {"(0, 0)"}
         startDragTime = <Myns::QVariant (int)> = {"500"}
         startDragDistance = <Myns::QVariant (int)> = {"10"}
         styleSheet = <Myns::QVariant (QString)> = {""}
         autoSipEnabled = <Myns::QVariant (bool)> = {"true"}
      ],"<10 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp ss
ss =
   <Myns::QString> = {"Hello"}
Change-Id: I6e4714a5cfe34c38917500d114ad9a70d20cff39
Reviewed-by: Christian Stenger <christian.stenger@digia.com>
Reviewed-by: hjk <hjk121@nokiamail.com>
											
										 
											2014-06-13 17:45:34 +02:00
										 |  |  |         if not exType is None: | 
					
						
							|  |  |  |             if self.passExceptions: | 
					
						
							|  |  |  |                 showException("SUBITEM", exType, exValue, exTraceBack) | 
					
						
							|  |  |  |             self.putNumChild(0) | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |             self.putSpecialValue("notaccessible") | 
					
						
							| 
									
										
											  
											
												Debugger: Make dumpers somewhat work in command line GDB
With
    python sys.path.insert(1, '/data/dev/creator/share/qtcreator/debugger/')
    python from gdbbridge import *
in .gdbinit there's a new "GDB command", called "pp".
With code like
    int main(int argc, char *argv[])
    {
        QString ss = "Hello";
        QApplication app(argc, argv);
        app.setObjectName(ss);
        // break here
    }
the 'pp' command can be used as follows:
(gdb) pp app
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = <Myns::QObjectList> = {"<3 items>"}
      [properties] = "<>0 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp app [properties],[children]
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = [
         <Myns::QObject> = {""}
         <Myns::QObject> = {""}
         <Myns::QObject> = {"fusion"}
      ],<Myns::QObjectList> = {"<3 items>"}
      [properties] = [
         windowIcon = <Myns::QVariant (QIcon)> = {""}
         cursorFlashTime = <Myns::QVariant (int)> = {"1000"}
         doubleClickInterval = <Myns::QVariant (int)> = {"400"}
         keyboardInputInterval = <Myns::QVariant (int)> = {"400"}
         wheelScrollLines = <Myns::QVariant (int)> = {"3"}
         globalStrut = <Myns::QVariant (QSize)> = {"(0, 0)"}
         startDragTime = <Myns::QVariant (int)> = {"500"}
         startDragDistance = <Myns::QVariant (int)> = {"10"}
         styleSheet = <Myns::QVariant (QString)> = {""}
         autoSipEnabled = <Myns::QVariant (bool)> = {"true"}
      ],"<10 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp ss
ss =
   <Myns::QString> = {"Hello"}
Change-Id: I6e4714a5cfe34c38917500d114ad9a70d20cff39
Reviewed-by: Christian Stenger <christian.stenger@digia.com>
Reviewed-by: hjk <hjk121@nokiamail.com>
											
										 
											2014-06-13 17:45:34 +02:00
										 |  |  |         try: | 
					
						
							|  |  |  |             if self.currentType.value: | 
					
						
							| 
									
										
										
										
											2014-09-12 13:31:12 +02:00
										 |  |  |                 typeName = self.stripClassTag(self.currentType.value) | 
					
						
							| 
									
										
											  
											
												Debugger: Make dumpers somewhat work in command line GDB
With
    python sys.path.insert(1, '/data/dev/creator/share/qtcreator/debugger/')
    python from gdbbridge import *
in .gdbinit there's a new "GDB command", called "pp".
With code like
    int main(int argc, char *argv[])
    {
        QString ss = "Hello";
        QApplication app(argc, argv);
        app.setObjectName(ss);
        // break here
    }
the 'pp' command can be used as follows:
(gdb) pp app
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = <Myns::QObjectList> = {"<3 items>"}
      [properties] = "<>0 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp app [properties],[children]
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = [
         <Myns::QObject> = {""}
         <Myns::QObject> = {""}
         <Myns::QObject> = {"fusion"}
      ],<Myns::QObjectList> = {"<3 items>"}
      [properties] = [
         windowIcon = <Myns::QVariant (QIcon)> = {""}
         cursorFlashTime = <Myns::QVariant (int)> = {"1000"}
         doubleClickInterval = <Myns::QVariant (int)> = {"400"}
         keyboardInputInterval = <Myns::QVariant (int)> = {"400"}
         wheelScrollLines = <Myns::QVariant (int)> = {"3"}
         globalStrut = <Myns::QVariant (QSize)> = {"(0, 0)"}
         startDragTime = <Myns::QVariant (int)> = {"500"}
         startDragDistance = <Myns::QVariant (int)> = {"10"}
         styleSheet = <Myns::QVariant (QString)> = {""}
         autoSipEnabled = <Myns::QVariant (bool)> = {"true"}
      ],"<10 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp ss
ss =
   <Myns::QString> = {"Hello"}
Change-Id: I6e4714a5cfe34c38917500d114ad9a70d20cff39
Reviewed-by: Christian Stenger <christian.stenger@digia.com>
Reviewed-by: hjk <hjk121@nokiamail.com>
											
										 
											2014-06-13 17:45:34 +02:00
										 |  |  |                 self.put('<%s> = {' % typeName) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if  self.currentValue.value is None: | 
					
						
							|  |  |  |                 self.put('<not accessible>') | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 value = self.currentValue.value | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |                 if self.currentValue.encoding == "latin1": | 
					
						
							| 
									
										
											  
											
												Debugger: Make dumpers somewhat work in command line GDB
With
    python sys.path.insert(1, '/data/dev/creator/share/qtcreator/debugger/')
    python from gdbbridge import *
in .gdbinit there's a new "GDB command", called "pp".
With code like
    int main(int argc, char *argv[])
    {
        QString ss = "Hello";
        QApplication app(argc, argv);
        app.setObjectName(ss);
        // break here
    }
the 'pp' command can be used as follows:
(gdb) pp app
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = <Myns::QObjectList> = {"<3 items>"}
      [properties] = "<>0 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp app [properties],[children]
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = [
         <Myns::QObject> = {""}
         <Myns::QObject> = {""}
         <Myns::QObject> = {"fusion"}
      ],<Myns::QObjectList> = {"<3 items>"}
      [properties] = [
         windowIcon = <Myns::QVariant (QIcon)> = {""}
         cursorFlashTime = <Myns::QVariant (int)> = {"1000"}
         doubleClickInterval = <Myns::QVariant (int)> = {"400"}
         keyboardInputInterval = <Myns::QVariant (int)> = {"400"}
         wheelScrollLines = <Myns::QVariant (int)> = {"3"}
         globalStrut = <Myns::QVariant (QSize)> = {"(0, 0)"}
         startDragTime = <Myns::QVariant (int)> = {"500"}
         startDragDistance = <Myns::QVariant (int)> = {"10"}
         styleSheet = <Myns::QVariant (QString)> = {""}
         autoSipEnabled = <Myns::QVariant (bool)> = {"true"}
      ],"<10 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp ss
ss =
   <Myns::QString> = {"Hello"}
Change-Id: I6e4714a5cfe34c38917500d114ad9a70d20cff39
Reviewed-by: Christian Stenger <christian.stenger@digia.com>
Reviewed-by: hjk <hjk121@nokiamail.com>
											
										 
											2014-06-13 17:45:34 +02:00
										 |  |  |                     value = self.hexdecode(value) | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |                 elif self.currentValue.encoding == "utf8": | 
					
						
							| 
									
										
											  
											
												Debugger: Make dumpers somewhat work in command line GDB
With
    python sys.path.insert(1, '/data/dev/creator/share/qtcreator/debugger/')
    python from gdbbridge import *
in .gdbinit there's a new "GDB command", called "pp".
With code like
    int main(int argc, char *argv[])
    {
        QString ss = "Hello";
        QApplication app(argc, argv);
        app.setObjectName(ss);
        // break here
    }
the 'pp' command can be used as follows:
(gdb) pp app
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = <Myns::QObjectList> = {"<3 items>"}
      [properties] = "<>0 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp app [properties],[children]
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = [
         <Myns::QObject> = {""}
         <Myns::QObject> = {""}
         <Myns::QObject> = {"fusion"}
      ],<Myns::QObjectList> = {"<3 items>"}
      [properties] = [
         windowIcon = <Myns::QVariant (QIcon)> = {""}
         cursorFlashTime = <Myns::QVariant (int)> = {"1000"}
         doubleClickInterval = <Myns::QVariant (int)> = {"400"}
         keyboardInputInterval = <Myns::QVariant (int)> = {"400"}
         wheelScrollLines = <Myns::QVariant (int)> = {"3"}
         globalStrut = <Myns::QVariant (QSize)> = {"(0, 0)"}
         startDragTime = <Myns::QVariant (int)> = {"500"}
         startDragDistance = <Myns::QVariant (int)> = {"10"}
         styleSheet = <Myns::QVariant (QString)> = {""}
         autoSipEnabled = <Myns::QVariant (bool)> = {"true"}
      ],"<10 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp ss
ss =
   <Myns::QString> = {"Hello"}
Change-Id: I6e4714a5cfe34c38917500d114ad9a70d20cff39
Reviewed-by: Christian Stenger <christian.stenger@digia.com>
Reviewed-by: hjk <hjk121@nokiamail.com>
											
										 
											2014-06-13 17:45:34 +02:00
										 |  |  |                     value = self.hexdecode(value) | 
					
						
							| 
									
										
										
										
											2015-12-11 13:28:21 +01:00
										 |  |  |                 elif self.currentValue.encoding == "utf16": | 
					
						
							| 
									
										
											  
											
												Debugger: Make dumpers somewhat work in command line GDB
With
    python sys.path.insert(1, '/data/dev/creator/share/qtcreator/debugger/')
    python from gdbbridge import *
in .gdbinit there's a new "GDB command", called "pp".
With code like
    int main(int argc, char *argv[])
    {
        QString ss = "Hello";
        QApplication app(argc, argv);
        app.setObjectName(ss);
        // break here
    }
the 'pp' command can be used as follows:
(gdb) pp app
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = <Myns::QObjectList> = {"<3 items>"}
      [properties] = "<>0 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp app [properties],[children]
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = [
         <Myns::QObject> = {""}
         <Myns::QObject> = {""}
         <Myns::QObject> = {"fusion"}
      ],<Myns::QObjectList> = {"<3 items>"}
      [properties] = [
         windowIcon = <Myns::QVariant (QIcon)> = {""}
         cursorFlashTime = <Myns::QVariant (int)> = {"1000"}
         doubleClickInterval = <Myns::QVariant (int)> = {"400"}
         keyboardInputInterval = <Myns::QVariant (int)> = {"400"}
         wheelScrollLines = <Myns::QVariant (int)> = {"3"}
         globalStrut = <Myns::QVariant (QSize)> = {"(0, 0)"}
         startDragTime = <Myns::QVariant (int)> = {"500"}
         startDragDistance = <Myns::QVariant (int)> = {"10"}
         styleSheet = <Myns::QVariant (QString)> = {""}
         autoSipEnabled = <Myns::QVariant (bool)> = {"true"}
      ],"<10 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp ss
ss =
   <Myns::QString> = {"Hello"}
Change-Id: I6e4714a5cfe34c38917500d114ad9a70d20cff39
Reviewed-by: Christian Stenger <christian.stenger@digia.com>
Reviewed-by: hjk <hjk121@nokiamail.com>
											
										 
											2014-06-13 17:45:34 +02:00
										 |  |  |                     b = bytes.fromhex(value) | 
					
						
							|  |  |  |                     value = codecs.decode(b, 'utf-16') | 
					
						
							|  |  |  |                 self.put('"%s"' % value) | 
					
						
							|  |  |  |                 if self.currentValue.elided: | 
					
						
							|  |  |  |                     self.put('...') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if self.currentType.value: | 
					
						
							|  |  |  |                 self.put('}') | 
					
						
							|  |  |  |         except: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  |         if not self.currentAddress is None: | 
					
						
							|  |  |  |             self.put(self.currentAddress) | 
					
						
							|  |  |  |         self.currentIName = item.savedIName | 
					
						
							|  |  |  |         self.currentValue = item.savedValue | 
					
						
							|  |  |  |         self.currentType = item.savedType | 
					
						
							|  |  |  |         self.currentAddress = item.savedCurrentAddress | 
					
						
							|  |  |  |         return True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def putNewline(self): | 
					
						
							|  |  |  |         self.output += '\n' + '   ' * self.indent | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def put(self, line): | 
					
						
							|  |  |  |         if self.output.endswith('\n'): | 
					
						
							|  |  |  |             self.output = self.output[0:-1] | 
					
						
							|  |  |  |         self.output += line | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def putNumChild(self, numchild): | 
					
						
							|  |  |  |         pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def putBaseClassName(self, name): | 
					
						
							|  |  |  |         pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def putOriginalAddress(self, value): | 
					
						
							|  |  |  |         pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def putAddressRange(self, base, step): | 
					
						
							|  |  |  |         return True | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |     def fetchVariables(self, args): | 
					
						
							| 
									
										
										
										
											2015-04-15 12:38:11 +02:00
										 |  |  |         args['fancy'] = 1 | 
					
						
							| 
									
										
										
										
											2015-10-27 15:50:41 +01:00
										 |  |  |         args['passexception'] = 1 | 
					
						
							| 
									
										
										
										
											2015-04-15 12:38:11 +02:00
										 |  |  |         args['autoderef'] = 1 | 
					
						
							| 
									
										
										
										
											2015-12-16 14:13:44 +01:00
										 |  |  |         args['qobjectnames'] = 1 | 
					
						
							| 
									
										
										
										
											2015-04-15 12:38:11 +02:00
										 |  |  |         name = args['varlist'] | 
					
						
							|  |  |  |         self.prepare(args) | 
					
						
							| 
									
										
											  
											
												Debugger: Make dumpers somewhat work in command line GDB
With
    python sys.path.insert(1, '/data/dev/creator/share/qtcreator/debugger/')
    python from gdbbridge import *
in .gdbinit there's a new "GDB command", called "pp".
With code like
    int main(int argc, char *argv[])
    {
        QString ss = "Hello";
        QApplication app(argc, argv);
        app.setObjectName(ss);
        // break here
    }
the 'pp' command can be used as follows:
(gdb) pp app
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = <Myns::QObjectList> = {"<3 items>"}
      [properties] = "<>0 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp app [properties],[children]
app =
   [
      <Myns::QGuiApplication> = {"Hello"}
      staticMetaObject = <Myns::QMetaObject> = {""}
      [parent] = <Myns::QObject *> = {"0x0"}
      [children] = [
         <Myns::QObject> = {""}
         <Myns::QObject> = {""}
         <Myns::QObject> = {"fusion"}
      ],<Myns::QObjectList> = {"<3 items>"}
      [properties] = [
         windowIcon = <Myns::QVariant (QIcon)> = {""}
         cursorFlashTime = <Myns::QVariant (int)> = {"1000"}
         doubleClickInterval = <Myns::QVariant (int)> = {"400"}
         keyboardInputInterval = <Myns::QVariant (int)> = {"400"}
         wheelScrollLines = <Myns::QVariant (int)> = {"3"}
         globalStrut = <Myns::QVariant (QSize)> = {"(0, 0)"}
         startDragTime = <Myns::QVariant (int)> = {"500"}
         startDragDistance = <Myns::QVariant (int)> = {"10"}
         styleSheet = <Myns::QVariant (QString)> = {""}
         autoSipEnabled = <Myns::QVariant (bool)> = {"true"}
      ],"<10 items>"
      [methods] = "<6 items>"
      [signals] = "<1 items>"
   ],<Myns::QApplication> = {"Hello"}
(gdb) pp ss
ss =
   <Myns::QString> = {"Hello"}
Change-Id: I6e4714a5cfe34c38917500d114ad9a70d20cff39
Reviewed-by: Christian Stenger <christian.stenger@digia.com>
Reviewed-by: hjk <hjk121@nokiamail.com>
											
										 
											2014-06-13 17:45:34 +02:00
										 |  |  |         self.output = name + ' = ' | 
					
						
							|  |  |  |         frame = gdb.selected_frame() | 
					
						
							|  |  |  |         value = frame.read_var(name) | 
					
						
							|  |  |  |         with TopLevelItem(self, name): | 
					
						
							|  |  |  |             self.putItem(value) | 
					
						
							|  |  |  |         return self.output | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-30 12:38:29 +01:00
										 |  |  | # Global instance. | 
					
						
							| 
									
										
										
										
											2015-09-25 08:45:20 +02:00
										 |  |  | #if gdb.parameter('height') is None: | 
					
						
							|  |  |  | theDumper = Dumper() | 
					
						
							|  |  |  | #else: | 
					
						
							|  |  |  | #    import codecs | 
					
						
							|  |  |  | #    theDumper = CliDumper() | 
					
						
							| 
									
										
										
										
											2013-10-30 12:38:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-11 17:51:15 +01:00
										 |  |  | ###################################################################### | 
					
						
							| 
									
										
										
										
											2013-10-30 12:38:29 +01:00
										 |  |  | # | 
					
						
							|  |  |  | # ThreadNames Command | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | ####################################################################### | 
					
						
							| 
									
										
										
										
											2013-06-06 18:28:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | def threadnames(arg): | 
					
						
							| 
									
										
										
										
											2013-10-30 12:38:29 +01:00
										 |  |  |     return theDumper.threadnames(int(arg)) | 
					
						
							| 
									
										
										
										
											2013-05-15 15:42:55 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | registerCommand("threadnames", threadnames) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-22 12:05:00 +01:00
										 |  |  | ####################################################################### | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # Native Mixed | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | ####################################################################### | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-14 13:26:22 +02:00
										 |  |  | class InterpreterMessageBreakpoint(gdb.Breakpoint): | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |     def __init__(self): | 
					
						
							| 
									
										
										
										
											2015-10-14 13:26:22 +02:00
										 |  |  |         spec = "qt_qmlDebugMessageAvailable" | 
					
						
							|  |  |  |         super(InterpreterMessageBreakpoint, self).\ | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |             __init__(spec, gdb.BP_BREAKPOINT, internal=True) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def stop(self): | 
					
						
							| 
									
										
										
										
											2015-10-09 15:00:20 +02:00
										 |  |  |         print("Interpreter event received.") | 
					
						
							| 
									
										
										
										
											2015-10-14 13:26:22 +02:00
										 |  |  |         return theDumper.handleInterpreterMessage() | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-14 13:26:22 +02:00
										 |  |  | InterpreterMessageBreakpoint() |