| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  | ############################################################################ | 
					
						
							|  |  |  | # | 
					
						
							| 
									
										
										
										
											2016-01-15 14:53:55 +01:00
										 |  |  | # Copyright (C) 2016 The Qt Company Ltd. | 
					
						
							|  |  |  | # Contact: https://www.qt.io/licensing/ | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  | # | 
					
						
							|  |  |  | # 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 | 
					
						
							| 
									
										
										
										
											2016-01-15 14:53:55 +01:00
										 |  |  | # 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-09-11 21:35:39 +02:00
										 |  |  | # | 
					
						
							| 
									
										
										
										
											2016-01-15 14:53:55 +01:00
										 |  |  | ############################################################################ | 
					
						
							| 
									
										
										
										
											2013-04-11 17:06:17 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | import inspect | 
					
						
							|  |  |  | import os | 
					
						
							| 
									
										
										
										
											2014-02-10 17:38:58 +01:00
										 |  |  | import platform | 
					
						
							| 
									
										
										
										
											2013-10-21 12:02:57 +02:00
										 |  |  | import re | 
					
						
							| 
									
										
										
										
											2013-05-13 16:04:00 +02:00
										 |  |  | import sys | 
					
						
							| 
									
										
										
										
											2013-10-21 12:02:57 +02:00
										 |  |  | import threading | 
					
						
							| 
									
										
										
										
											2015-01-30 12:36:04 +01:00
										 |  |  | import lldb | 
					
						
							| 
									
										
										
										
											2013-05-16 15:09:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-13 15:19:56 +02:00
										 |  |  | from contextlib import contextmanager | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-13 10:02:35 +01:00
										 |  |  | sys.path.insert(1, os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))) | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-13 15:19:56 +02:00
										 |  |  | # Simplify development of this module by reloading deps | 
					
						
							|  |  |  | if 'dumper' in sys.modules: | 
					
						
							|  |  |  |     reload(sys.modules['dumper']) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  | from dumper import * | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-11 17:06:17 +02:00
										 |  |  | ####################################################################### | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # Helpers | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | ####################################################################### | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-14 15:15:09 +02:00
										 |  |  | qqWatchpointOffset = 10000 | 
					
						
							| 
									
										
										
										
											2013-05-15 15:30:42 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  | def fileNameAsString(file): | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  |     return str(file) if file.IsValid() else '' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-11 17:06:17 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-07 16:43:20 +02:00
										 |  |  | def check(exp): | 
					
						
							|  |  |  |     if not exp: | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |         raise RuntimeError('Check failed') | 
					
						
							| 
									
										
										
										
											2013-05-07 16:43:20 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  | class Dumper(DumperBase): | 
					
						
							| 
									
										
										
										
											2017-05-13 15:19:56 +02:00
										 |  |  |     def __init__(self, debugger = None): | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |         DumperBase.__init__(self) | 
					
						
							| 
									
										
										
										
											2016-04-13 18:19:45 +02:00
										 |  |  |         lldb.theDumper = self | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-07 12:23:35 +02:00
										 |  |  |         self.isLldb = True | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |         self.typeCache = {} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-19 12:08:25 +01:00
										 |  |  |         self.outputLock = threading.Lock() | 
					
						
							| 
									
										
										
										
											2017-05-13 15:19:56 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if debugger: | 
					
						
							|  |  |  |             # Re-use existing debugger | 
					
						
							|  |  |  |             self.debugger = debugger | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.debugger = lldb.SBDebugger.Create() | 
					
						
							|  |  |  |             #self.debugger.SetLoggingCallback(loggingCallback) | 
					
						
							|  |  |  |             #def loggingCallback(args): | 
					
						
							|  |  |  |             #    s = args.strip() | 
					
						
							|  |  |  |             #    s = s.replace('"', "'") | 
					
						
							|  |  |  |             #    sys.stdout.write('log="%s"@\n' % s) | 
					
						
							|  |  |  |             #Same as: self.debugger.HandleCommand('log enable lldb dyld step') | 
					
						
							|  |  |  |             #self.debugger.EnableLog('lldb', ['dyld', 'step', 'process', 'state', | 
					
						
							|  |  |  |             #    'thread', 'events', | 
					
						
							|  |  |  |             #    'communication', 'unwind', 'commands']) | 
					
						
							|  |  |  |             #self.debugger.EnableLog('lldb', ['all']) | 
					
						
							|  |  |  |             self.debugger.Initialize() | 
					
						
							|  |  |  |             self.debugger.HandleCommand('settings set auto-confirm on') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # FIXME: warn('DISABLING DEFAULT FORMATTERS') | 
					
						
							|  |  |  |             # It doesn't work at all with 179.5 and we have some bad | 
					
						
							|  |  |  |             # interaction in 300 | 
					
						
							|  |  |  |             # if not hasattr(lldb.SBType, 'GetCanonicalType'): # 'Test' for 179.5 | 
					
						
							|  |  |  |             #self.debugger.HandleCommand('type category delete gnu-libstdc++') | 
					
						
							|  |  |  |             #self.debugger.HandleCommand('type category delete libcxx') | 
					
						
							|  |  |  |             #self.debugger.HandleCommand('type category delete default') | 
					
						
							|  |  |  |             self.debugger.DeleteCategory('gnu-libstdc++') | 
					
						
							|  |  |  |             self.debugger.DeleteCategory('libcxx') | 
					
						
							|  |  |  |             self.debugger.DeleteCategory('default') | 
					
						
							|  |  |  |             self.debugger.DeleteCategory('cplusplus') | 
					
						
							|  |  |  |             #for i in range(self.debugger.GetNumCategories()): | 
					
						
							|  |  |  |             #    self.debugger.GetCategoryAtIndex(i).SetEnabled(False) | 
					
						
							| 
									
										
										
										
											2013-11-01 14:18:10 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  |         self.process = None | 
					
						
							|  |  |  |         self.target = None | 
					
						
							|  |  |  |         self.eventState = lldb.eStateInvalid | 
					
						
							| 
									
										
										
										
											2016-10-07 12:23:57 +02:00
										 |  |  |         self.runEngineAttempted = False | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-22 14:30:36 +02:00
										 |  |  |         self.executable_ = None | 
					
						
							| 
									
										
										
										
											2013-10-01 02:30:12 +02:00
										 |  |  |         self.startMode_ = None | 
					
						
							|  |  |  |         self.processArgs_ = None | 
					
						
							|  |  |  |         self.attachPid_ = None | 
					
						
							| 
									
										
										
										
											2015-12-08 16:58:20 +01:00
										 |  |  |         self.dyldImageSuffix = None | 
					
						
							|  |  |  |         self.dyldLibraryPath = None | 
					
						
							|  |  |  |         self.dyldFrameworkPath = None | 
					
						
							| 
									
										
										
										
											2013-10-01 02:30:12 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-29 15:38:49 +02:00
										 |  |  |         self.isShuttingDown_ = False | 
					
						
							| 
									
										
										
										
											2013-06-24 17:40:00 +02:00
										 |  |  |         self.isInterrupting_ = False | 
					
						
							| 
									
										
										
										
											2015-10-09 15:00:20 +02:00
										 |  |  |         self.interpreterBreakpointResolvers = [] | 
					
						
							| 
									
										
										
										
											2013-05-17 13:53:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-13 10:02:35 +01:00
										 |  |  |         self.report('lldbversion=\"%s\"' % lldb.SBDebugger.GetVersionString()) | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |         self.reportState('enginesetupok') | 
					
						
							| 
									
										
										
										
											2016-08-02 14:50:54 +02:00
										 |  |  |         self.debuggerCommandInProgress = False | 
					
						
							| 
									
										
										
										
											2015-02-13 10:02:35 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |     def fromNativeFrameValue(self, nativeValue): | 
					
						
							|  |  |  |         return self.fromNativeValue(nativeValue) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-06 08:54:43 +02:00
										 |  |  |     def fromNativeValue(self, nativeValue): | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |         self.check(isinstance(nativeValue, lldb.SBValue)) | 
					
						
							| 
									
										
										
										
											2016-09-26 14:29:16 +02:00
										 |  |  |         nativeType = nativeValue.GetType() | 
					
						
							| 
									
										
										
										
											2017-08-15 15:17:12 +02:00
										 |  |  |         typeName = nativeType.GetName() | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |         code = nativeType.GetTypeClass() | 
					
						
							| 
									
										
										
										
											2017-05-15 16:54:07 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-15 15:17:12 +02:00
										 |  |  |         # Display the result of GetSummary() for Core Foundation string | 
					
						
							|  |  |  |         # and string-like types. | 
					
						
							|  |  |  |         summary = None | 
					
						
							|  |  |  |         if self.useFancy: | 
					
						
							|  |  |  |             if (typeName.startswith('CF') | 
					
						
							|  |  |  |                     or typeName.startswith('__CF') | 
					
						
							|  |  |  |                     or typeName.startswith('NS') | 
					
						
							|  |  |  |                     or typeName.startswith('__NSCF')): | 
					
						
							|  |  |  |                 if code == lldb.eTypeClassPointer: | 
					
						
							|  |  |  |                     summary = nativeValue.Dereference().GetSummary() | 
					
						
							|  |  |  |                 elif code == lldb.eTypeClassReference: | 
					
						
							|  |  |  |                     summary = nativeValue.Dereference().GetSummary() | 
					
						
							|  |  |  |                 else: | 
					
						
							|  |  |  |                     summary = nativeValue.GetSummary() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         nativeValue.SetPreferSyntheticValue(False) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |         if code == lldb.eTypeClassReference: | 
					
						
							|  |  |  |             nativeTargetType = nativeType.GetDereferencedType() | 
					
						
							|  |  |  |             if not nativeTargetType.IsPointerType(): | 
					
						
							|  |  |  |                 nativeTargetType = nativeTargetType.GetUnqualifiedType() | 
					
						
							|  |  |  |             targetType = self.fromNativeType(nativeTargetType) | 
					
						
							|  |  |  |             val = self.createReferenceValue(nativeValue.GetValueAsUnsigned(), targetType) | 
					
						
							|  |  |  |             val.laddress = nativeValue.AddressOf().GetValueAsUnsigned() | 
					
						
							|  |  |  |             #warn('CREATED REF: %s' % val) | 
					
						
							| 
									
										
										
										
											2017-05-15 16:54:07 +02:00
										 |  |  |         elif code == lldb.eTypeClassPointer: | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |             nativeTargetType = nativeType.GetPointeeType() | 
					
						
							|  |  |  |             if not nativeTargetType.IsPointerType(): | 
					
						
							|  |  |  |                 nativeTargetType = nativeTargetType.GetUnqualifiedType() | 
					
						
							|  |  |  |             targetType = self.fromNativeType(nativeTargetType) | 
					
						
							|  |  |  |             val = self.createPointerValue(nativeValue.GetValueAsUnsigned(), targetType) | 
					
						
							|  |  |  |             #warn('CREATED PTR 1: %s' % val) | 
					
						
							|  |  |  |             val.laddress = nativeValue.AddressOf().GetValueAsUnsigned() | 
					
						
							|  |  |  |             #warn('CREATED PTR 2: %s' % val) | 
					
						
							| 
									
										
										
										
											2017-05-15 16:54:07 +02:00
										 |  |  |         elif code == lldb.eTypeClassTypedef: | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |             nativeTargetType = nativeType.GetUnqualifiedType() | 
					
						
							|  |  |  |             if hasattr(nativeTargetType, 'GetCanonicalType'): | 
					
						
							|  |  |  |                  nativeTargetType = nativeTargetType.GetCanonicalType() | 
					
						
							|  |  |  |             val = self.fromNativeValue(nativeValue.Cast(nativeTargetType)) | 
					
						
							|  |  |  |             val.type = self.fromNativeType(nativeType) | 
					
						
							|  |  |  |             #warn('CREATED TYPEDEF: %s' % val) | 
					
						
							| 
									
										
										
										
											2017-05-15 16:54:07 +02:00
										 |  |  |         else: | 
					
						
							|  |  |  |             val = self.Value(self) | 
					
						
							|  |  |  |             address = nativeValue.GetLoadAddress() | 
					
						
							|  |  |  |             if not address is None: | 
					
						
							|  |  |  |                 val.laddress = address | 
					
						
							|  |  |  |             if True: | 
					
						
							|  |  |  |                 data = nativeValue.GetData() | 
					
						
							|  |  |  |                 error = lldb.SBError() | 
					
						
							|  |  |  |                 size = nativeValue.GetType().GetByteSize() | 
					
						
							|  |  |  |                 if size > 1: | 
					
						
							|  |  |  |                     # 0 happens regularly e.g. for cross-shared-object types. | 
					
						
							|  |  |  |                     # 1 happens on Linux e.g. for QObject uses outside of QtCore. | 
					
						
							|  |  |  |                     try: | 
					
						
							|  |  |  |                         val.ldata = data.ReadRawData(error, 0, size) | 
					
						
							|  |  |  |                     except: | 
					
						
							|  |  |  |                         pass | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-15 16:54:07 +02:00
										 |  |  |             val.type = self.fromNativeType(nativeType) | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-15 16:54:07 +02:00
										 |  |  |             if code == lldb.eTypeClassEnumeration: | 
					
						
							|  |  |  |                 intval = nativeValue.GetValueAsSigned() | 
					
						
							|  |  |  |                 if hasattr(nativeType, 'get_enum_members_array'): | 
					
						
							|  |  |  |                     for enumMember in nativeType.get_enum_members_array(): | 
					
						
							|  |  |  |                         # Even when asking for signed we get unsigned with LLDB 3.8. | 
					
						
							|  |  |  |                         diff = enumMember.GetValueAsSigned() - intval | 
					
						
							|  |  |  |                         mask = (1 << nativeType.GetByteSize() * 8) - 1 | 
					
						
							|  |  |  |                         if diff & mask == 0: | 
					
						
							|  |  |  |                             path = nativeType.GetName().split('::') | 
					
						
							|  |  |  |                             path[-1] = enumMember.GetName() | 
					
						
							|  |  |  |                             val.ldisplay = '%s (%d)' % ('::'.join(path), intval) | 
					
						
							|  |  |  |                 val.ldisplay = '%d' % intval | 
					
						
							|  |  |  |             elif code in (lldb.eTypeClassComplexInteger, lldb.eTypeClassComplexFloat): | 
					
						
							|  |  |  |                 val.ldisplay = str(nativeValue.GetValue()) | 
					
						
							|  |  |  |             #elif code == lldb.eTypeClassArray: | 
					
						
							|  |  |  |             #    if hasattr(nativeType, 'GetArrayElementType'): # New in 3.8(?) / 350.x | 
					
						
							|  |  |  |             #        val.type.ltarget = self.fromNativeType(nativeType.GetArrayElementType()) | 
					
						
							|  |  |  |             #    else: | 
					
						
							|  |  |  |             #        fields = nativeType.get_fields_array() | 
					
						
							|  |  |  |             #        if len(fields): | 
					
						
							|  |  |  |             #            val.type.ltarget = self.fromNativeType(fields[0]) | 
					
						
							|  |  |  |             #elif code == lldb.eTypeClassVector: | 
					
						
							|  |  |  |             #    val.type.ltarget = self.fromNativeType(nativeType.GetVectorElementType()) | 
					
						
							| 
									
										
										
										
											2016-11-01 09:50:31 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-15 15:17:12 +02:00
										 |  |  |         val.summary = summary | 
					
						
							| 
									
										
										
										
											2017-05-15 16:54:07 +02:00
										 |  |  |         val.lIsInScope = nativeValue.IsInScope() | 
					
						
							| 
									
										
										
										
											2016-11-01 09:50:31 +01:00
										 |  |  |         val.name = nativeValue.GetName() | 
					
						
							| 
									
										
										
										
											2016-09-06 08:54:43 +02:00
										 |  |  |         return val | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-01 09:50:31 +01:00
										 |  |  |     def nativeStructAlignment(self, nativeType): | 
					
						
							|  |  |  |         def handleItem(nativeFieldType, align): | 
					
						
							|  |  |  |             a = self.fromNativeType(nativeFieldType).alignment() | 
					
						
							|  |  |  |             return a if a > align else align | 
					
						
							|  |  |  |         align = 1 | 
					
						
							|  |  |  |         for i in range(nativeType.GetNumberOfDirectBaseClasses()): | 
					
						
							|  |  |  |             base = nativeType.GetDirectBaseClassAtIndex(i) | 
					
						
							|  |  |  |             align = handleItem(base.GetType(), align) | 
					
						
							|  |  |  |         for i in range(nativeType.GetNumberOfFields()): | 
					
						
							|  |  |  |             child = nativeType.GetFieldAtIndex(i) | 
					
						
							|  |  |  |             align = handleItem(child.GetType(), align) | 
					
						
							|  |  |  |         return align | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-08 16:37:52 +01:00
										 |  |  |     def listMembers(self, value, nativeType): | 
					
						
							| 
									
										
										
										
											2016-11-07 08:57:26 +01:00
										 |  |  |         #warn("ADDR: 0x%x" % self.fakeAddress) | 
					
						
							|  |  |  |         fakeAddress = self.fakeAddress if value.laddress is None else value.laddress | 
					
						
							|  |  |  |         sbaddr = lldb.SBAddress(fakeAddress, self.target) | 
					
						
							|  |  |  |         fakeValue = self.target.CreateValueFromAddress('x', sbaddr, nativeType) | 
					
						
							|  |  |  |         fakeValue.SetPreferSyntheticValue(False) | 
					
						
							| 
									
										
										
										
											2016-11-01 09:50:31 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         baseNames = {} | 
					
						
							|  |  |  |         for i in range(nativeType.GetNumberOfDirectBaseClasses()): | 
					
						
							|  |  |  |             base = nativeType.GetDirectBaseClassAtIndex(i) | 
					
						
							|  |  |  |             baseNames[base.GetName()] = i | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         fieldBits = {} | 
					
						
							|  |  |  |         for f in nativeType.get_fields_array(): | 
					
						
							|  |  |  |             bitsize = f.GetBitfieldSizeInBits() | 
					
						
							|  |  |  |             if bitsize == 0: | 
					
						
							|  |  |  |                 bitsize = f.GetType().GetByteSize() * 8 | 
					
						
							|  |  |  |             bitpos = f.GetOffsetInBits() | 
					
						
							|  |  |  |             # Correction for some bitfields. Size 0 can occur for | 
					
						
							|  |  |  |             # types without debug information. | 
					
						
							|  |  |  |             if bitsize > 0: | 
					
						
							|  |  |  |                 #bitpos = bitpos % bitsize | 
					
						
							|  |  |  |                 bitpos = bitpos % 8 # Reported type is always wrapping type! | 
					
						
							| 
									
										
										
										
											2016-11-15 11:56:18 +01:00
										 |  |  |             fieldBits[f.name] = (bitsize, bitpos, f.IsBitfield()) | 
					
						
							| 
									
										
										
										
											2016-11-01 09:50:31 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # Normal members and non-empty base classes. | 
					
						
							| 
									
										
										
										
											2017-03-08 16:37:52 +01:00
										 |  |  |         anonNumber = 0 | 
					
						
							| 
									
										
										
										
											2016-11-07 08:57:26 +01:00
										 |  |  |         for i in range(fakeValue.GetNumChildren()): | 
					
						
							|  |  |  |             nativeField = fakeValue.GetChildAtIndex(i) | 
					
						
							|  |  |  |             nativeField.SetPreferSyntheticValue(False) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-08 16:37:52 +01:00
										 |  |  |             fieldName = nativeField.GetName() | 
					
						
							| 
									
										
										
										
											2016-11-07 08:57:26 +01:00
										 |  |  |             nativeFieldType = nativeField.GetType() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-08 16:37:52 +01:00
										 |  |  |             if fieldName in fieldBits: | 
					
						
							|  |  |  |                 (fieldBitsize, fieldBitpos, isBitfield) = fieldBits[fieldName] | 
					
						
							| 
									
										
										
										
											2016-11-07 08:57:26 +01:00
										 |  |  |             else: | 
					
						
							| 
									
										
										
										
											2017-03-08 16:37:52 +01:00
										 |  |  |                 fieldBitsize = nativeFieldType.GetByteSize() * 8 | 
					
						
							|  |  |  |                 fieldBitpost = None | 
					
						
							| 
									
										
										
										
											2016-11-15 11:56:18 +01:00
										 |  |  |                 isBitfield = False | 
					
						
							| 
									
										
										
										
											2016-11-07 08:57:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-25 11:35:31 +01:00
										 |  |  |             if isBitfield: # Bit fields | 
					
						
							| 
									
										
										
										
											2017-06-02 15:04:40 +03:00
										 |  |  |                 fieldType = self.createBitfieldType( | 
					
						
							|  |  |  |                     self.createType(self.typeName(nativeFieldType)), fieldBitsize) | 
					
						
							| 
									
										
										
										
											2017-03-08 16:37:52 +01:00
										 |  |  |                 yield self.Field(self, name=fieldName, type=fieldType, | 
					
						
							|  |  |  |                                  bitsize=fieldBitsize, bitpos=fieldBitpos) | 
					
						
							| 
									
										
										
										
											2016-11-25 11:35:31 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-08 16:37:52 +01:00
										 |  |  |             elif fieldName is None: # Anon members | 
					
						
							|  |  |  |                 anonNumber += 1 | 
					
						
							|  |  |  |                 fieldName = '#%s' % anonNumber | 
					
						
							| 
									
										
										
										
											2016-11-07 08:57:26 +01:00
										 |  |  |                 fakeMember = fakeValue.GetChildAtIndex(i) | 
					
						
							|  |  |  |                 fakeMemberAddress = fakeMember.GetLoadAddress() | 
					
						
							|  |  |  |                 offset = fakeMemberAddress - fakeAddress | 
					
						
							| 
									
										
										
										
											2017-03-08 16:37:52 +01:00
										 |  |  |                 yield self.Field(self, name=fieldName, type=self.fromNativeType(nativeFieldType), | 
					
						
							|  |  |  |                                  bitsize=fieldBitsize, bitpos=8*offset) | 
					
						
							| 
									
										
										
										
											2016-11-07 08:57:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-08 16:37:52 +01:00
										 |  |  |             elif fieldName in baseNames:  # Simple bases | 
					
						
							| 
									
										
										
										
											2016-11-25 11:35:31 +01:00
										 |  |  |                 member = self.fromNativeValue(fakeValue.GetChildAtIndex(i)) | 
					
						
							|  |  |  |                 member.isBaseClass = True | 
					
						
							|  |  |  |                 yield member | 
					
						
							| 
									
										
										
										
											2016-11-07 08:57:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-25 11:35:31 +01:00
										 |  |  |             else: # Normal named members | 
					
						
							|  |  |  |                 member = self.fromNativeValue(fakeValue.GetChildAtIndex(i)) | 
					
						
							|  |  |  |                 member.name = nativeField.GetName() | 
					
						
							|  |  |  |                 yield member | 
					
						
							| 
									
										
										
										
											2016-11-01 09:50:31 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # Empty bases are not covered above. | 
					
						
							|  |  |  |         for i in range(nativeType.GetNumberOfDirectBaseClasses()): | 
					
						
							|  |  |  |             fieldObj = nativeType.GetDirectBaseClassAtIndex(i) | 
					
						
							|  |  |  |             fieldType = fieldObj.GetType() | 
					
						
							|  |  |  |             if fieldType.GetNumberOfFields() == 0: | 
					
						
							|  |  |  |                 if fieldType.GetNumberOfDirectBaseClasses() == 0: | 
					
						
							|  |  |  |                     member = self.Value(self) | 
					
						
							|  |  |  |                     fieldName = fieldObj.GetName() | 
					
						
							|  |  |  |                     member.type = self.fromNativeType(fieldType) | 
					
						
							|  |  |  |                     member.name = fieldName | 
					
						
							|  |  |  |                     member.fields = [] | 
					
						
							| 
									
										
										
										
											2016-11-18 18:07:11 +01:00
										 |  |  |                     if False: | 
					
						
							|  |  |  |                         # This would be correct if we came here only for | 
					
						
							|  |  |  |                         # truly empty base classes. Alas, we don't, see below. | 
					
						
							|  |  |  |                         member.ldata = bytes() | 
					
						
							|  |  |  |                         member.lbitsize = fieldType.GetByteSize() * 8 | 
					
						
							|  |  |  |                     else: | 
					
						
							|  |  |  |                         # This is a hack. LLDB 3.8 reports declared but not defined | 
					
						
							|  |  |  |                         # types as having no fields and(!) size == 1. At least | 
					
						
							|  |  |  |                         # for the common case of a single base class we can | 
					
						
							|  |  |  |                         # fake the contents by using the whole derived object's | 
					
						
							|  |  |  |                         # data as base class data. | 
					
						
							|  |  |  |                         data = fakeValue.GetData() | 
					
						
							|  |  |  |                         size = nativeType.GetByteSize() | 
					
						
							|  |  |  |                         member.lbitsize = size * 8 | 
					
						
							|  |  |  |                         error = lldb.SBError() | 
					
						
							|  |  |  |                         member.laddress = value.laddress | 
					
						
							|  |  |  |                         member.ldata = data.ReadRawData(error, 0, size) | 
					
						
							| 
									
										
										
										
											2016-11-01 09:50:31 +01:00
										 |  |  |                     member.isBaseClass = True | 
					
						
							|  |  |  |                     member.ltype = self.fromNativeType(fieldType) | 
					
						
							|  |  |  |                     member.name = fieldName | 
					
						
							|  |  |  |                     yield member | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |     def ptrSize(self): | 
					
						
							|  |  |  |         result = self.target.GetAddressByteSize() | 
					
						
							|  |  |  |         self.ptrSize = lambda: result | 
					
						
							|  |  |  |         return result | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-06 08:54:43 +02:00
										 |  |  |     def fromNativeType(self, nativeType): | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |         self.check(isinstance(nativeType, lldb.SBType)) | 
					
						
							| 
									
										
										
										
											2016-09-06 08:54:43 +02:00
										 |  |  |         code = nativeType.GetTypeClass() | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-01 09:50:31 +01:00
										 |  |  |         # eTypeClassInvalid           = (0u), | 
					
						
							|  |  |  |         # eTypeClassArray             = (1u << 0), | 
					
						
							|  |  |  |         # eTypeClassBlockPointer      = (1u << 1), | 
					
						
							|  |  |  |         # eTypeClassBuiltin           = (1u << 2), | 
					
						
							|  |  |  |         # eTypeClassClass             = (1u << 3), | 
					
						
							|  |  |  |         # eTypeClassComplexFloat      = (1u << 4), | 
					
						
							|  |  |  |         # eTypeClassComplexInteger    = (1u << 5), | 
					
						
							|  |  |  |         # eTypeClassEnumeration       = (1u << 6), | 
					
						
							|  |  |  |         # eTypeClassFunction          = (1u << 7), | 
					
						
							|  |  |  |         # eTypeClassMemberPointer     = (1u << 8), | 
					
						
							|  |  |  |         # eTypeClassObjCObject        = (1u << 9), | 
					
						
							|  |  |  |         # eTypeClassObjCInterface     = (1u << 10), | 
					
						
							|  |  |  |         # eTypeClassObjCObjectPointer = (1u << 11), | 
					
						
							|  |  |  |         # eTypeClassPointer           = (1u << 12), | 
					
						
							|  |  |  |         # eTypeClassReference         = (1u << 13), | 
					
						
							|  |  |  |         # eTypeClassStruct            = (1u << 14), | 
					
						
							|  |  |  |         # eTypeClassTypedef           = (1u << 15), | 
					
						
							|  |  |  |         # eTypeClassUnion             = (1u << 16), | 
					
						
							|  |  |  |         # eTypeClassVector            = (1u << 17), | 
					
						
							|  |  |  |         # // Define the last type class as the MSBit of a 32 bit value | 
					
						
							|  |  |  |         # eTypeClassOther             = (1u << 31), | 
					
						
							|  |  |  |         # // Define a mask that can be used for any type when finding types | 
					
						
							|  |  |  |         # eTypeClassAny               = (0xffffffffu) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |         #warn('CURRENT: %s' % self.typeData.keys()) | 
					
						
							|  |  |  |         #warn('FROM NATIVE TYPE: %s' % nativeType.GetName()) | 
					
						
							|  |  |  |         if code == lldb.eTypeClassInvalid: | 
					
						
							|  |  |  |             return None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if code == lldb.eTypeClassBuiltin: | 
					
						
							|  |  |  |             nativeType = nativeType.GetUnqualifiedType() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if code == lldb.eTypeClassPointer: | 
					
						
							|  |  |  |             #warn('PTR') | 
					
						
							|  |  |  |             nativeTargetType = nativeType.GetPointeeType() | 
					
						
							|  |  |  |             if not nativeTargetType.IsPointerType(): | 
					
						
							|  |  |  |                 nativeTargetType = nativeTargetType.GetUnqualifiedType() | 
					
						
							|  |  |  |             #warn('PTR: %s' % nativeTargetType.name) | 
					
						
							|  |  |  |             return self.createPointerType(self.fromNativeType(nativeTargetType)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if code == lldb.eTypeClassReference: | 
					
						
							|  |  |  |             #warn('REF') | 
					
						
							|  |  |  |             nativeTargetType = nativeType.GetDereferencedType() | 
					
						
							|  |  |  |             if not nativeTargetType.IsPointerType(): | 
					
						
							|  |  |  |                 nativeTargetType = nativeTargetType.GetUnqualifiedType() | 
					
						
							|  |  |  |             #warn('REF: %s' % nativeTargetType.name) | 
					
						
							|  |  |  |             return self.createReferenceType(self.fromNativeType(nativeTargetType)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-01 09:50:31 +01:00
										 |  |  |         if code == lldb.eTypeClassTypedef: | 
					
						
							|  |  |  |             #warn('TYPEDEF') | 
					
						
							|  |  |  |             nativeTargetType = nativeType.GetUnqualifiedType() | 
					
						
							|  |  |  |             if hasattr(nativeTargetType, 'GetCanonicalType'): | 
					
						
							|  |  |  |                  nativeTargetType = nativeTargetType.GetCanonicalType() | 
					
						
							|  |  |  |             targetType = self.fromNativeType(nativeTargetType) | 
					
						
							|  |  |  |             return self.createTypedefedType(targetType, nativeType.GetName()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         nativeType = nativeType.GetUnqualifiedType() | 
					
						
							| 
									
										
										
										
											2016-11-07 08:57:26 +01:00
										 |  |  |         typeName = self.typeName(nativeType) | 
					
						
							| 
									
										
										
										
											2016-11-01 09:50:31 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |         if code in (lldb.eTypeClassArray, lldb.eTypeClassVector): | 
					
						
							|  |  |  |             #warn('ARRAY: %s' % nativeType.GetName()) | 
					
						
							|  |  |  |             if hasattr(nativeType, 'GetArrayElementType'): # New in 3.8(?) / 350.x | 
					
						
							|  |  |  |                 nativeTargetType = nativeType.GetArrayElementType() | 
					
						
							|  |  |  |                 if not nativeTargetType.IsValid(): | 
					
						
							|  |  |  |                     if hasattr(nativeType, 'GetVectorElementType'): # New in 3.8(?) / 350.x | 
					
						
							|  |  |  |                         #warn('BAD: %s ' % nativeTargetType.get_fields_array()) | 
					
						
							|  |  |  |                         nativeTargetType = nativeType.GetVectorElementType() | 
					
						
							| 
									
										
										
										
											2016-11-01 09:50:31 +01:00
										 |  |  |                 count = nativeType.GetByteSize() // nativeTargetType.GetByteSize() | 
					
						
							|  |  |  |                 targetTypeName = nativeTargetType.GetName() | 
					
						
							|  |  |  |                 if targetTypeName.startswith('(anon'): | 
					
						
							|  |  |  |                     typeName = nativeType.GetName() | 
					
						
							|  |  |  |                     pos1 = typeName.rfind('[') | 
					
						
							|  |  |  |                     targetTypeName = typeName[0:pos1].strip() | 
					
						
							|  |  |  |                 #warn("TARGET TYPENAME: %s" % targetTypeName) | 
					
						
							|  |  |  |                 targetType = self.fromNativeType(nativeTargetType) | 
					
						
							|  |  |  |                 tdata = targetType.typeData().copy() | 
					
						
							|  |  |  |                 tdata.name = targetTypeName | 
					
						
							|  |  |  |                 targetType.typeData = lambda : tdata | 
					
						
							|  |  |  |                 return self.createArrayType(targetType, count) | 
					
						
							|  |  |  |             if hasattr(nativeType, 'GetVectorElementType'): # New in 3.8(?) / 350.x | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |                 nativeTargetType = nativeType.GetVectorElementType() | 
					
						
							| 
									
										
										
										
											2016-11-01 09:50:31 +01:00
										 |  |  |                 count = nativeType.GetByteSize() // nativeTargetType.GetByteSize() | 
					
						
							|  |  |  |                 targetType = self.fromNativeType(nativeTargetType) | 
					
						
							|  |  |  |                 return self.createArrayType(targetType, count) | 
					
						
							|  |  |  |             return self.createType(nativeType.GetName()) | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         typeId = self.nativeTypeId(nativeType) | 
					
						
							|  |  |  |         res = self.typeData.get(typeId, None) | 
					
						
							|  |  |  |         if res is None: | 
					
						
							|  |  |  |             #  # This strips typedefs for pointers. We don't want that. | 
					
						
							|  |  |  |             #  typeobj.nativeType = nativeType.GetUnqualifiedType() | 
					
						
							|  |  |  |             tdata = self.TypeData(self) | 
					
						
							|  |  |  |             tdata.typeId = typeId | 
					
						
							| 
									
										
										
										
											2016-11-01 09:50:31 +01:00
										 |  |  |             tdata.name = typeName | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |             tdata.lbitsize = nativeType.GetByteSize() * 8 | 
					
						
							| 
									
										
										
										
											2016-09-19 12:05:16 +02:00
										 |  |  |             if code == lldb.eTypeClassBuiltin: | 
					
						
							| 
									
										
										
										
											2016-11-01 09:50:31 +01:00
										 |  |  |                 if isFloatingPointTypeName(typeName): | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |                     tdata.code = TypeCodeFloat | 
					
						
							| 
									
										
										
										
											2016-11-01 09:50:31 +01:00
										 |  |  |                 elif isIntegralTypeName(typeName): | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |                     tdata.code = TypeCodeIntegral | 
					
						
							| 
									
										
										
										
											2016-11-01 09:50:31 +01:00
										 |  |  |                 elif typeName == 'void': | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |                     tdata.code = TypeCodeVoid | 
					
						
							| 
									
										
										
										
											2016-09-19 12:05:16 +02:00
										 |  |  |                 else: | 
					
						
							| 
									
										
										
										
											2016-11-01 09:50:31 +01:00
										 |  |  |                     warn('UNKNOWN TYPE KEY: %s: %s' % (typeName, code)) | 
					
						
							|  |  |  |             elif code == lldb.eTypeClassEnumeration: | 
					
						
							|  |  |  |                 tdata.code = TypeCodeEnum | 
					
						
							| 
									
										
										
										
											2017-02-27 14:29:07 +01:00
										 |  |  |                 tdata.enumDisplay = lambda intval, addr : \ | 
					
						
							| 
									
										
										
										
											2016-11-01 09:50:31 +01:00
										 |  |  |                     self.nativeTypeEnumDisplay(nativeType, intval) | 
					
						
							|  |  |  |             elif code in (lldb.eTypeClassComplexInteger, lldb.eTypeClassComplexFloat): | 
					
						
							|  |  |  |                 tdata.code = TypeCodeComplex | 
					
						
							|  |  |  |             elif code in (lldb.eTypeClassClass, lldb.eTypeClassStruct, lldb.eTypeClassUnion): | 
					
						
							|  |  |  |                 tdata.code = TypeCodeStruct | 
					
						
							|  |  |  |                 tdata.lalignment = lambda : \ | 
					
						
							|  |  |  |                     self.nativeStructAlignment(nativeType) | 
					
						
							|  |  |  |                 tdata.lfields = lambda value : \ | 
					
						
							| 
									
										
										
										
											2017-03-08 16:37:52 +01:00
										 |  |  |                     self.listMembers(value, nativeType) | 
					
						
							| 
									
										
										
										
											2016-11-01 09:50:31 +01:00
										 |  |  |                 tdata.templateArguments = self.listTemplateParametersHelper(nativeType) | 
					
						
							|  |  |  |             elif code == lldb.eTypeClassFunction: | 
					
						
							|  |  |  |                 tdata.code = TypeCodeFunction, | 
					
						
							|  |  |  |             elif code == lldb.eTypeClassMemberPointer: | 
					
						
							|  |  |  |                 tdata.code = TypeCodeMemberPointer | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |             self.registerType(typeId, tdata) # Fix up fields and template args | 
					
						
							|  |  |  |         #    warn('CREATE TYPE: %s' % typeId) | 
					
						
							|  |  |  |         #else: | 
					
						
							|  |  |  |         #    warn('REUSE TYPE: %s' % typeId) | 
					
						
							|  |  |  |         return self.Type(self, typeId) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def listTemplateParametersHelper(self, nativeType): | 
					
						
							|  |  |  |         stringArgs = self.listTemplateParameters(nativeType.GetName()) | 
					
						
							|  |  |  |         n = nativeType.GetNumberOfTemplateArguments() | 
					
						
							|  |  |  |         if n != len(stringArgs): | 
					
						
							|  |  |  |             # Something wrong in the debug info. | 
					
						
							|  |  |  |             # Should work in theory, doesn't work in practice. | 
					
						
							|  |  |  |             # Items like std::allocator<std::pair<unsigned int const, float> report 0 | 
					
						
							|  |  |  |             # for nativeType.GetNumberOfTemplateArguments() with LLDB 3.8 | 
					
						
							|  |  |  |             return stringArgs | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         targs = [] | 
					
						
							|  |  |  |         for i in range(nativeType.GetNumberOfTemplateArguments()): | 
					
						
							|  |  |  |             kind = nativeType.GetTemplateArgumentKind(i) | 
					
						
							|  |  |  |             # eTemplateArgumentKindNull = 0, | 
					
						
							|  |  |  |             # eTemplateArgumentKindType, | 
					
						
							|  |  |  |             # eTemplateArgumentKindDeclaration, | 
					
						
							|  |  |  |             # eTemplateArgumentKindIntegral, | 
					
						
							|  |  |  |             # eTemplateArgumentKindTemplate, | 
					
						
							|  |  |  |             # eTemplateArgumentKindTemplateExpansion, | 
					
						
							|  |  |  |             # eTemplateArgumentKindExpression, | 
					
						
							|  |  |  |             # eTemplateArgumentKindPack | 
					
						
							|  |  |  |             if kind == lldb.eTemplateArgumentKindType: | 
					
						
							|  |  |  |                 innerType = nativeType.GetTemplateArgumentType(i).GetUnqualifiedType().GetCanonicalType() | 
					
						
							|  |  |  |                 targs.append(self.fromNativeType(innerType)) | 
					
						
							|  |  |  |             #elif kind == lldb.eTemplateArgumentKindIntegral: | 
					
						
							|  |  |  |             #   innerType = nativeType.GetTemplateArgumentType(i).GetUnqualifiedType().GetCanonicalType() | 
					
						
							|  |  |  |             #   #warn('INNER TYP: %s' % innerType) | 
					
						
							|  |  |  |             #   basicType = innerType.GetBasicType() | 
					
						
							|  |  |  |             #   #warn('IBASIC TYP: %s' % basicType) | 
					
						
							|  |  |  |             #   inner = self.extractTemplateArgument(nativeType.GetName(), i) | 
					
						
							|  |  |  |             #   exp = '(%s)%s' % (innerType.GetName(), inner) | 
					
						
							|  |  |  |             #   #warn('EXP : %s' % exp) | 
					
						
							|  |  |  |             #   val = self.nativeParseAndEvaluate('(%s)%s' % (innerType.GetName(), inner)) | 
					
						
							|  |  |  |             #   # Clang writes 'int' and '0xfffffff' into the debug info | 
					
						
							|  |  |  |             #   # LLDB manages to read a value of 0xfffffff... | 
					
						
							|  |  |  |             #   #if basicType == lldb.eBasicTypeInt: | 
					
						
							|  |  |  |             #   value = val.GetValueAsUnsigned() | 
					
						
							|  |  |  |             #   if value >= 0x8000000: | 
					
						
							|  |  |  |             #       value -= 0x100000000 | 
					
						
							|  |  |  |             #   #warn('KIND: %s' % kind) | 
					
						
							|  |  |  |             #   targs.append(value) | 
					
						
							| 
									
										
										
										
											2016-09-19 12:05:16 +02:00
										 |  |  |             else: | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |                 #warn('UNHANDLED TEMPLATE TYPE : %s' % kind) | 
					
						
							|  |  |  |                 targs.append(stringArgs[i]) # Best we can do. | 
					
						
							|  |  |  |         #warn('TARGS: %s %s' % (nativeType.GetName(), [str(x) for x in  targs])) | 
					
						
							|  |  |  |         return targs | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-07 08:57:26 +01:00
										 |  |  |     def typeName(self, nativeType): | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |         if hasattr(nativeType, 'GetDisplayTypeName'): | 
					
						
							| 
									
										
										
										
											2016-11-07 08:57:26 +01:00
										 |  |  |             return nativeType.GetDisplayTypeName()  # Xcode 6 (lldb-320) | 
					
						
							|  |  |  |         return nativeType.GetName()             # Xcode 5 (lldb-310) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def nativeTypeId(self, nativeType): | 
					
						
							|  |  |  |         name = self.typeName(nativeType) | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |         if name is None or len(name) == 0: | 
					
						
							|  |  |  |             c = '0' | 
					
						
							|  |  |  |         elif name == '(anonymous struct)' and nativeType.GetTypeClass() == lldb.eTypeClassStruct: | 
					
						
							|  |  |  |             c = 's' | 
					
						
							|  |  |  |         elif name == '(anonymous struct)' and nativeType.GetTypeClass() == lldb.eTypeClassUnion: | 
					
						
							|  |  |  |             c = 'u' | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             return name | 
					
						
							|  |  |  |         fields = nativeType.get_fields_array() | 
					
						
							|  |  |  |         typeId = c + ''.join(['{%s:%s}' % (f.name, self.nativeTypeId(f.GetType())) for f in fields]) | 
					
						
							|  |  |  |         #warn('NATIVE TYPE ID FOR %s IS %s' % (name, typeId)) | 
					
						
							|  |  |  |         return typeId | 
					
						
							| 
									
										
										
										
											2016-09-06 08:54:43 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-15 12:31:28 +02:00
										 |  |  |     def nativeTypeEnumDisplay(self, nativeType, intval): | 
					
						
							|  |  |  |         if hasattr(nativeType, 'get_enum_members_array'): | 
					
						
							|  |  |  |             for enumMember in nativeType.get_enum_members_array(): | 
					
						
							|  |  |  |                 # Even when asking for signed we get unsigned with LLDB 3.8. | 
					
						
							|  |  |  |                 diff = enumMember.GetValueAsSigned() - intval | 
					
						
							|  |  |  |                 mask = (1 << nativeType.GetByteSize() * 8) - 1 | 
					
						
							|  |  |  |                 if diff & mask == 0: | 
					
						
							|  |  |  |                     path = nativeType.GetName().split('::') | 
					
						
							|  |  |  |                     path[-1] = enumMember.GetName() | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |                     return '%s (%d)' % ('::'.join(path), intval) | 
					
						
							|  |  |  |         return '%d' % intval | 
					
						
							| 
									
										
										
										
											2016-09-15 12:31:28 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-26 14:29:16 +02:00
										 |  |  |     def nativeDynamicTypeName(self, address, baseType): | 
					
						
							|  |  |  |         return None # FIXME: Seems sufficient, no idea why. | 
					
						
							|  |  |  |         addr = self.target.ResolveLoadAddress(address) | 
					
						
							|  |  |  |         ctx = self.target.ResolveSymbolContextForAddress(addr, 0) | 
					
						
							|  |  |  |         sym = ctx.GetSymbol() | 
					
						
							|  |  |  |         return sym.GetName() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-04 14:15:14 +01:00
										 |  |  |     def stateName(self, s): | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             # See db.StateType | 
					
						
							|  |  |  |             return ( | 
					
						
							|  |  |  |                 'invalid', | 
					
						
							|  |  |  |                 'unloaded',  # Process is object is valid, but not currently loaded | 
					
						
							|  |  |  |                 'connected', # Process is connected to remote debug services, | 
					
						
							|  |  |  |                              #  but not launched or attached to anything yet | 
					
						
							|  |  |  |                 'attaching', # Process is currently trying to attach | 
					
						
							|  |  |  |                 'launching', # Process is in the process of launching | 
					
						
							|  |  |  |                 'stopped',   # Process or thread is stopped and can be examined. | 
					
						
							|  |  |  |                 'running',   # Process or thread is running and can't be examined. | 
					
						
							|  |  |  |                 'stepping',  # Process or thread is in the process of stepping | 
					
						
							|  |  |  |                              #  and can not be examined. | 
					
						
							|  |  |  |                 'crashed',   # Process or thread has crashed and can be examined. | 
					
						
							|  |  |  |                 'detached',  # Process has been detached and can't be examined. | 
					
						
							|  |  |  |                 'exited',    # Process has exited and can't be examined. | 
					
						
							|  |  |  |                 'suspended'  # Process or thread is in a suspended state as far | 
					
						
							|  |  |  |                 )[s] | 
					
						
							|  |  |  |         except: | 
					
						
							|  |  |  |             return 'unknown(%s)' % s | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def stopReason(self, s): | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             return ( | 
					
						
							|  |  |  |                 'invalid', | 
					
						
							|  |  |  |                 'none', | 
					
						
							|  |  |  |                 'trace', | 
					
						
							|  |  |  |                 'breakpoint', | 
					
						
							|  |  |  |                 'watchpoint', | 
					
						
							|  |  |  |                 'signal', | 
					
						
							|  |  |  |                 'exception', | 
					
						
							|  |  |  |                 'exec', | 
					
						
							|  |  |  |                 'plancomplete', | 
					
						
							|  |  |  |                 'threadexiting', | 
					
						
							|  |  |  |                 'instrumentation', | 
					
						
							|  |  |  |                 )[s] | 
					
						
							|  |  |  |         except: | 
					
						
							|  |  |  |             return 'unknown(%s)' % s | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-10 20:01:35 +01:00
										 |  |  |     def enumExpression(self, enumType, enumValue): | 
					
						
							|  |  |  |         ns = self.qtNamespace() | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |         return ns + 'Qt::' + enumType + '(' \ | 
					
						
							|  |  |  |             + ns + 'Qt::' + enumType + '::' + enumValue + ')' | 
					
						
							| 
									
										
										
										
											2014-01-10 20:01:35 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-06 08:54:43 +02:00
										 |  |  |     def callHelper(self, rettype, value, func, args): | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |         # args is a tuple. | 
					
						
							|  |  |  |         arg = ','.join(args) | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |         #warn('PRECALL: %s -> %s(%s)' % (value.address(), func, arg)) | 
					
						
							| 
									
										
										
										
											2016-09-06 08:54:43 +02:00
										 |  |  |         typename = value.type.name | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |         exp = '((%s*)0x%x)->%s(%s)' % (typename, value.address(), func, arg) | 
					
						
							|  |  |  |         #warn('CALL: %s' % exp) | 
					
						
							| 
									
										
										
										
											2016-09-06 08:54:43 +02:00
										 |  |  |         result = self.currentContextValue.CreateValueFromExpression('', exp) | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |         #warn('  -> %s' % result) | 
					
						
							| 
									
										
										
										
											2016-09-06 08:54:43 +02:00
										 |  |  |         return self.fromNativeValue(result) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def pokeValue(self, typeName, *args): | 
					
						
							| 
									
										
										
										
											2014-01-22 16:25:39 +01:00
										 |  |  |         thread = self.currentThread() | 
					
						
							|  |  |  |         frame = thread.GetFrameAtIndex(0) | 
					
						
							|  |  |  |         inner = ','.join(args) | 
					
						
							| 
									
										
										
										
											2016-09-06 08:54:43 +02:00
										 |  |  |         value = frame.EvaluateExpression(typeName + '{' + inner + '}') | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |         #self.warn('  TYPE: %s' % value.type) | 
					
						
							|  |  |  |         #self.warn('  ADDR: 0x%x' % value.address) | 
					
						
							|  |  |  |         #self.warn('  VALUE: %s' % value) | 
					
						
							| 
									
										
										
										
											2014-01-22 16:25:39 +01:00
										 |  |  |         return value | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |     def nativeParseAndEvaluate(self, exp): | 
					
						
							| 
									
										
										
										
											2013-10-23 12:51:11 +02:00
										 |  |  |         thread = self.currentThread() | 
					
						
							|  |  |  |         frame = thread.GetFrameAtIndex(0) | 
					
						
							| 
									
										
										
										
											2016-09-06 08:54:43 +02:00
										 |  |  |         val = frame.EvaluateExpression(exp) | 
					
						
							|  |  |  |         #options = lldb.SBExpressionOptions() | 
					
						
							|  |  |  |         #val = self.target.EvaluateExpression(exp, options) | 
					
						
							|  |  |  |         err = val.GetError() | 
					
						
							|  |  |  |         if err.Fail(): | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |             #warn('FAILING TO EVAL: %s' % exp) | 
					
						
							| 
									
										
										
										
											2016-09-06 08:54:43 +02:00
										 |  |  |             return None | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |         #warn('NO ERROR.') | 
					
						
							|  |  |  |         #warn('EVAL: %s -> %s' % (exp, val.IsValid())) | 
					
						
							|  |  |  |         return val | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def parseAndEvaluate(self, exp): | 
					
						
							|  |  |  |         val = self.nativeParseAndEvaluate(exp) | 
					
						
							|  |  |  |         return None if val is None else self.fromNativeValue(val) | 
					
						
							| 
									
										
										
										
											2016-09-06 08:54:43 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-01 18:11:57 +02:00
										 |  |  |     def isWindowsTarget(self): | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def isQnxTarget(self): | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def isArmArchitecture(self): | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-06 13:36:02 +02:00
										 |  |  |     def isMsvcTarget(self): | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-09 13:25:17 +01:00
										 |  |  |     def qtVersionAndNamespace(self): | 
					
						
							| 
									
										
										
										
											2014-03-12 18:04:51 +01:00
										 |  |  |         for func in self.target.FindFunctions('qVersion'): | 
					
						
							|  |  |  |             name = func.GetSymbol().GetName() | 
					
						
							| 
									
										
										
										
											2014-03-19 12:16:43 +01:00
										 |  |  |             if name.endswith('()'): | 
					
						
							|  |  |  |                 name = name[:-2] | 
					
						
							| 
									
										
										
										
											2014-03-12 18:04:51 +01:00
										 |  |  |             if name.count(':') > 2: | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-19 12:16:43 +01:00
										 |  |  |             qtNamespace = name[:name.find('qVersion')] | 
					
						
							|  |  |  |             self.qtNamespace = lambda: qtNamespace | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-04 15:37:55 +02:00
										 |  |  |             options = lldb.SBExpressionOptions() | 
					
						
							|  |  |  |             res = self.target.EvaluateExpression(name + '()', options) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if not res.IsValid() or not res.GetType().IsPointerType(): | 
					
						
							|  |  |  |                 exp = '((const char*())%s)()' % name | 
					
						
							|  |  |  |                 res = self.target.EvaluateExpression(exp, options) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if not res.IsValid() or not res.GetType().IsPointerType(): | 
					
						
							|  |  |  |                 exp = '((const char*())_Z8qVersionv)()' | 
					
						
							|  |  |  |                 res = self.target.EvaluateExpression(exp, options) | 
					
						
							| 
									
										
										
										
											2014-03-12 18:04:51 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-04 15:37:55 +02:00
										 |  |  |             if not res.IsValid() or not res.GetType().IsPointerType(): | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             version = str(res) | 
					
						
							| 
									
										
										
										
											2014-03-12 18:04:51 +01:00
										 |  |  |             if version.count('.') != 2: | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-19 12:16:43 +01:00
										 |  |  |             version.replace("'", '"') # Both seem possible | 
					
						
							|  |  |  |             version = version[version.find('"')+1:version.rfind('"')] | 
					
						
							| 
									
										
										
										
											2014-03-12 18:04:51 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |             (major, minor, patch) = version.split('.') | 
					
						
							|  |  |  |             qtVersion = 0x10000 * int(major) + 0x100 * int(minor) + int(patch) | 
					
						
							|  |  |  |             self.qtVersion = lambda: qtVersion | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-01 09:22:53 +01:00
										 |  |  |             funcs = self.target.FindFunctions('QObject::customEvent') | 
					
						
							|  |  |  |             if len(funcs): | 
					
						
							|  |  |  |                 symbol = funcs[0].GetSymbol() | 
					
						
							|  |  |  |                 self.qtCustomEventFunc = symbol.GetStartAddress().GetLoadAddress(self.target) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-02 09:06:05 +01:00
										 |  |  |             funcs = self.target.FindFunctions('QObject::property') | 
					
						
							|  |  |  |             if len(funcs): | 
					
						
							|  |  |  |                 symbol = funcs[0].GetSymbol() | 
					
						
							|  |  |  |                 self.qtPropertyFunc = symbol.GetStartAddress().GetLoadAddress(self.target) | 
					
						
							| 
									
										
										
										
											2014-03-12 18:04:51 +01:00
										 |  |  |             return (qtNamespace, qtVersion) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return ('', 0x50200) | 
					
						
							| 
									
										
										
										
											2014-01-09 13:25:17 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def qtNamespace(self): | 
					
						
							| 
									
										
										
										
											2014-03-12 18:04:51 +01:00
										 |  |  |         return self.qtVersionAndNamespace()[0] | 
					
						
							| 
									
										
										
										
											2014-01-09 13:25:17 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def qtVersion(self): | 
					
						
							| 
									
										
										
										
											2014-01-09 16:23:17 +01:00
										 |  |  |         self.qtVersionAndNamespace() | 
					
						
							| 
									
										
										
										
											2014-03-12 18:04:51 +01:00
										 |  |  |         return self.qtVersionAndNamespace()[1] | 
					
						
							| 
									
										
										
										
											2013-06-27 10:42:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  |     def handleCommand(self, command): | 
					
						
							|  |  |  |         result = lldb.SBCommandReturnObject() | 
					
						
							|  |  |  |         self.debugger.GetCommandInterpreter().HandleCommand(command, result) | 
					
						
							|  |  |  |         success = result.Succeeded() | 
					
						
							|  |  |  |         if success: | 
					
						
							|  |  |  |             self.report('output="%s"' % result.GetOutput()) | 
					
						
							| 
									
										
										
										
											2013-04-10 13:55:15 +02:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  |             self.report('error="%s"' % result.GetError()) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-16 14:23:53 +01:00
										 |  |  |     def canonicalTypeName(self, name): | 
					
						
							|  |  |  |         return re.sub('\\bconst\\b', '', name).replace(' ', '') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-12 12:47:24 +01:00
										 |  |  |     def removeTypePrefix(self, name): | 
					
						
							|  |  |  |         return re.sub('^(struct|class|union|enum|typedef) ', '', name) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-06 08:54:43 +02:00
										 |  |  |     def lookupNativeType(self, name): | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |         #warn('LOOKUP TYPE NAME: %s' % name) | 
					
						
							|  |  |  |         typeobj = self.typeCache.get(name) | 
					
						
							|  |  |  |         if not typeobj is None: | 
					
						
							|  |  |  |             #warn('CACHED: %s' % name) | 
					
						
							|  |  |  |             return typeobj | 
					
						
							| 
									
										
										
										
											2014-01-16 14:23:53 +01:00
										 |  |  |         typeobj = self.target.FindFirstType(name) | 
					
						
							|  |  |  |         if typeobj.IsValid(): | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |             #warn('VALID FIRST : %s' % typeobj) | 
					
						
							|  |  |  |             self.typeCache[name] = typeobj | 
					
						
							| 
									
										
										
										
											2014-01-16 14:23:53 +01:00
										 |  |  |             return typeobj | 
					
						
							| 
									
										
										
										
											2017-01-12 12:47:24 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # FindFirstType has a bug (in lldb) that if there are two types with the same base name | 
					
						
							|  |  |  |         # but different scope name (e.g. inside different classes) and the searched for type name | 
					
						
							|  |  |  |         # would be returned as the second result in a call to FindTypes, FindFirstType would return | 
					
						
							|  |  |  |         # an empty result. | 
					
						
							|  |  |  |         # Therefore an additional call to FindTypes is done as a fallback. | 
					
						
							|  |  |  |         # Note that specifying a prefix like enum or typedef or class will make the call fail to | 
					
						
							|  |  |  |         # find the type, thus the prefix is stripped. | 
					
						
							|  |  |  |         nonPrefixedName = self.canonicalTypeName(self.removeTypePrefix(name)) | 
					
						
							|  |  |  |         typeobjlist = self.target.FindTypes(nonPrefixedName) | 
					
						
							|  |  |  |         if typeobjlist.IsValid(): | 
					
						
							|  |  |  |             for typeobj in typeobjlist: | 
					
						
							|  |  |  |                 n = self.canonicalTypeName(self.removeTypePrefix(typeobj.GetDisplayTypeName())) | 
					
						
							|  |  |  |                 if n == nonPrefixedName: | 
					
						
							|  |  |  |                     #warn('FOUND TYPE USING FindTypes : %s' % typeobj) | 
					
						
							|  |  |  |                     self.typeCache[name] = typeobj | 
					
						
							|  |  |  |                     return typeobj | 
					
						
							| 
									
										
										
										
											2014-12-01 12:17:56 +01:00
										 |  |  |         if name.endswith('*'): | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |             #warn('RECURSE PTR') | 
					
						
							|  |  |  |             typeobj = self.lookupNativeType(name[:-1].strip()) | 
					
						
							|  |  |  |             if typeobj is not None: | 
					
						
							|  |  |  |                 #warn('RECURSE RESULT X: %s' % typeobj) | 
					
						
							|  |  |  |                 self.fromNativeType(typeobj.GetPointerType()) | 
					
						
							|  |  |  |                 #warn('RECURSE RESULT: %s' % typeobj.GetPointerType()) | 
					
						
							| 
									
										
										
										
											2014-12-01 12:17:56 +01:00
										 |  |  |                 return typeobj.GetPointerType() | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             #typeobj = self.target.FindFirstType(name[:-1].strip()) | 
					
						
							|  |  |  |             #if typeobj.IsValid(): | 
					
						
							|  |  |  |             #    self.typeCache[name] = typeobj.GetPointerType() | 
					
						
							|  |  |  |             #    return typeobj.GetPointerType() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if name.endswith(' const'): | 
					
						
							|  |  |  |             #warn('LOOKUP END CONST') | 
					
						
							|  |  |  |             typeobj = self.lookupNativeType(name[:-6]) | 
					
						
							|  |  |  |             if typeobj is not None: | 
					
						
							|  |  |  |                 return typeobj | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if name.startswith('const '): | 
					
						
							|  |  |  |             #warn('LOOKUP START CONST') | 
					
						
							|  |  |  |             typeobj = self.lookupNativeType(name[6:]) | 
					
						
							|  |  |  |             if typeobj is not None: | 
					
						
							|  |  |  |                 return typeobj | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-01 12:17:56 +01:00
										 |  |  |         needle = self.canonicalTypeName(name) | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |         #warn('NEEDLE: %s ' % needle) | 
					
						
							| 
									
										
										
										
											2017-01-12 12:47:24 +01:00
										 |  |  |         warn('Searching for type %s across all target modules, this could be very slow' % name) | 
					
						
							| 
									
										
										
										
											2014-12-01 12:17:56 +01:00
										 |  |  |         for i in xrange(self.target.GetNumModules()): | 
					
						
							|  |  |  |             module = self.target.GetModuleAtIndex(i) | 
					
						
							|  |  |  |             # SBModule.GetType is new somewhere after early 300.x | 
					
						
							|  |  |  |             # So this may fail. | 
					
						
							|  |  |  |             for t in module.GetTypes(): | 
					
						
							|  |  |  |                 n = self.canonicalTypeName(t.GetName()) | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |                 #warn('N: %s' % n) | 
					
						
							| 
									
										
										
										
											2014-12-01 12:17:56 +01:00
										 |  |  |                 if n == needle: | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |                     #warn('FOUND TYPE DIRECT 2: %s ' % t) | 
					
						
							|  |  |  |                     self.typeCache[name] = t | 
					
						
							| 
									
										
										
										
											2014-12-01 12:17:56 +01:00
										 |  |  |                     return t | 
					
						
							|  |  |  |                 if n == needle + '*': | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |                     res = t.GetPointeeType() | 
					
						
							|  |  |  |                     self.typeCache[name] = res | 
					
						
							|  |  |  |                     x = self.fromNativeType(res)  # Register under both names | 
					
						
							|  |  |  |                     self.registerTypeAlias(x.typeId, name) | 
					
						
							|  |  |  |                     #warn('FOUND TYPE BY POINTER: %s ' % res.name) | 
					
						
							|  |  |  |                     return res | 
					
						
							| 
									
										
										
										
											2014-12-01 12:17:56 +01:00
										 |  |  |                 if n == needle + '&': | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |                     res = t.GetDereferencedType().GetUnqualifiedType() | 
					
						
							|  |  |  |                     self.typeCache[name] = res | 
					
						
							|  |  |  |                     x = self.fromNativeType(res)  # Register under both names | 
					
						
							|  |  |  |                     self.registerTypeAlias(x.typeId, name) | 
					
						
							|  |  |  |                     #warn('FOUND TYPE BY REFERENCE: %s ' % res.name) | 
					
						
							|  |  |  |                     return res | 
					
						
							|  |  |  |         #warn('NOT FOUND: %s ' % needle) | 
					
						
							| 
									
										
										
										
											2014-01-16 14:23:53 +01:00
										 |  |  |         return None | 
					
						
							| 
									
										
										
										
											2013-05-08 16:20:03 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-07 12:34:10 +02:00
										 |  |  |     def setupInferior(self, args): | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  |         error = lldb.SBError() | 
					
						
							| 
									
										
										
										
											2013-10-01 02:30:12 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.executable_ = args['executable'] | 
					
						
							| 
									
										
										
										
											2015-10-27 15:50:41 +01:00
										 |  |  |         self.startMode_ = args.get('startmode', 1) | 
					
						
							|  |  |  |         self.breakOnMain_ = args.get('breakonmain', 0) | 
					
						
							|  |  |  |         self.useTerminal_ = args.get('useterminal', 0) | 
					
						
							|  |  |  |         self.processArgs_ = args.get('processargs', []) | 
					
						
							| 
									
										
										
										
											2016-05-11 12:15:37 +02:00
										 |  |  |         self.processArgs_ = list(map(lambda x: self.hexdecode(x), self.processArgs_)) | 
					
						
							| 
									
										
										
										
											2016-12-06 15:39:05 +01:00
										 |  |  |         self.environment_ = args.get('environment', []) | 
					
						
							|  |  |  |         self.environment_ = list(map(lambda x: self.hexdecode(x), self.environment_)) | 
					
						
							| 
									
										
										
										
											2015-10-27 15:50:41 +01:00
										 |  |  |         self.attachPid_ = args.get('attachpid', 0) | 
					
						
							|  |  |  |         self.sysRoot_ = args.get('sysroot', '') | 
					
						
							|  |  |  |         self.remoteChannel_ = args.get('remotechannel', '') | 
					
						
							| 
									
										
										
										
											2013-10-31 10:07:28 +01:00
										 |  |  |         self.platform_ = args.get('platform', '') | 
					
						
							| 
									
										
										
										
											2015-10-09 15:00:20 +02:00
										 |  |  |         self.nativeMixed = int(args.get('nativemixed', 0)) | 
					
						
							| 
									
										
										
										
											2016-09-26 13:47:19 +02:00
										 |  |  |         self.workingDirectory_ = args.get('workingdirectory', '') | 
					
						
							|  |  |  |         if self.workingDirectory_ == '': | 
					
						
							| 
									
										
										
										
											2017-04-07 13:23:01 +02:00
										 |  |  |             try: | 
					
						
							|  |  |  |                 self.workingDirectory_ = os.getcwd() | 
					
						
							|  |  |  |             except: # Could have been deleted in the mean time. | 
					
						
							|  |  |  |                 pass | 
					
						
							| 
									
										
										
										
											2013-10-01 02:30:12 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-04 14:25:59 +01:00
										 |  |  |         self.ignoreStops = 0 | 
					
						
							| 
									
										
										
										
											2015-02-27 11:56:03 +01:00
										 |  |  |         self.silentStops = 0 | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |         if platform.system() == 'Linux': | 
					
						
							| 
									
										
										
										
											2015-02-27 11:56:03 +01:00
										 |  |  |             if self.startMode_ == AttachCore: | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 if self.useTerminal_: | 
					
						
							|  |  |  |                     self.ignoreStops = 2 | 
					
						
							|  |  |  |                 else: | 
					
						
							|  |  |  |                     self.silentStops = 1 | 
					
						
							| 
									
										
										
										
											2014-03-03 16:59:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-27 16:56:51 +01:00
										 |  |  |         else: | 
					
						
							|  |  |  |             if self.useTerminal_: | 
					
						
							|  |  |  |                 self.ignoreStops = 1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-31 10:07:28 +01:00
										 |  |  |         if self.platform_: | 
					
						
							|  |  |  |             self.debugger.SetCurrentPlatform(self.platform_) | 
					
						
							| 
									
										
										
										
											2013-12-10 12:53:20 +01:00
										 |  |  |         # sysroot has to be set *after* the platform | 
					
						
							|  |  |  |         if self.sysRoot_: | 
					
						
							|  |  |  |             self.debugger.SetCurrentPlatformSDKRoot(self.sysRoot_) | 
					
						
							| 
									
										
										
										
											2014-02-04 18:36:32 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if os.path.isfile(self.executable_): | 
					
						
							|  |  |  |             self.target = self.debugger.CreateTarget(self.executable_, None, None, True, error) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.target = self.debugger.CreateTarget(None, None, None, True, error) | 
					
						
							| 
									
										
										
										
											2013-05-29 14:55:57 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-09 15:00:20 +02:00
										 |  |  |         if self.nativeMixed: | 
					
						
							|  |  |  |             self.interpreterEventBreakpoint = \ | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |                 self.target.BreakpointCreateByName('qt_qmlDebugMessageAvailable') | 
					
						
							| 
									
										
										
										
											2015-10-09 15:00:20 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |         state = 1 if self.target.IsValid() else 0 | 
					
						
							| 
									
										
										
										
											2016-10-07 12:23:35 +02:00
										 |  |  |         self.reportResult('success="%s",msg="%s",exe="%s"' | 
					
						
							|  |  |  |             % (state, error, self.executable_), args) | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-27 11:56:03 +01:00
										 |  |  |     def runEngine(self, args): | 
					
						
							| 
									
										
										
										
											2016-10-07 12:23:57 +02:00
										 |  |  |         if self.runEngineAttempted: | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  |         self.runEngineAttempted = True | 
					
						
							| 
									
										
										
										
											2015-02-27 11:56:03 +01:00
										 |  |  |         self.prepare(args) | 
					
						
							| 
									
										
										
										
											2013-05-31 15:27:54 +02:00
										 |  |  |         s = threading.Thread(target=self.loop, args=[]) | 
					
						
							|  |  |  |         s.start() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-27 11:56:03 +01:00
										 |  |  |     def prepare(self, args): | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  |         error = lldb.SBError() | 
					
						
							| 
									
										
										
										
											2013-05-31 15:27:54 +02:00
										 |  |  |         listener = self.debugger.GetListener() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-01 02:30:12 +02:00
										 |  |  |         if self.attachPid_ > 0: | 
					
						
							|  |  |  |             attachInfo = lldb.SBAttachInfo(self.attachPid_) | 
					
						
							|  |  |  |             self.process = self.target.Attach(attachInfo, error) | 
					
						
							| 
									
										
										
										
											2013-10-31 10:07:28 +01:00
										 |  |  |             if not error.Success(): | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |                 self.reportState('inferiorrunfailed') | 
					
						
							| 
									
										
										
										
											2013-10-29 22:25:41 +01:00
										 |  |  |                 return | 
					
						
							|  |  |  |             self.report('pid="%s"' % self.process.GetProcessID()) | 
					
						
							| 
									
										
										
										
											2014-03-19 12:12:24 +01:00
										 |  |  |             # Even if it stops it seems that LLDB assumes it is running | 
					
						
							|  |  |  |             # and later detects that it did stop after all, so it is be | 
					
						
							| 
									
										
										
										
											2016-09-14 14:31:27 +02:00
										 |  |  |             # better to mirror that and wait for the spontaneous stop | 
					
						
							|  |  |  |             if self.process and self.process.GetState() == lldb.eStateStopped: | 
					
						
							|  |  |  |                 # lldb stops the process after attaching. This happens before the | 
					
						
							|  |  |  |                 # eventloop starts. Relay the correct state back. | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |                 self.reportState('enginerunandinferiorstopok') | 
					
						
							| 
									
										
										
										
											2016-09-14 14:31:27 +02:00
										 |  |  |             else: | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |                 self.reportState('enginerunandinferiorrunok') | 
					
						
							| 
									
										
										
										
											2014-07-01 12:30:38 +02:00
										 |  |  |         elif self.startMode_ == AttachToRemoteServer or self.startMode_ == AttachToRemoteProcess: | 
					
						
							| 
									
										
										
										
											2013-10-29 22:25:41 +01:00
										 |  |  |             self.process = self.target.ConnectRemote( | 
					
						
							| 
									
										
										
										
											2014-06-02 17:05:52 +02:00
										 |  |  |                 self.debugger.GetListener(), | 
					
						
							|  |  |  |                 self.remoteChannel_, None, error) | 
					
						
							| 
									
										
										
										
											2013-10-31 10:07:28 +01:00
										 |  |  |             if not error.Success(): | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |                 self.report(self.describeError(error)) | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |                 self.reportState('enginerunfailed') | 
					
						
							| 
									
										
										
										
											2013-10-31 10:07:28 +01:00
										 |  |  |                 return | 
					
						
							| 
									
										
										
										
											2014-03-19 12:12:24 +01:00
										 |  |  |             # Even if it stops it seems that LLDB assumes it is running | 
					
						
							|  |  |  |             # and later detects that it did stop after all, so it is be | 
					
						
							|  |  |  |             # better to mirror that and wait for the spontaneous stop. | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |             self.reportState('enginerunandinferiorrunok') | 
					
						
							| 
									
										
										
										
											2015-02-27 11:56:03 +01:00
										 |  |  |         elif self.startMode_ == AttachCore: | 
					
						
							|  |  |  |             coreFile = args.get('coreFile', ''); | 
					
						
							|  |  |  |             self.process = self.target.LoadCore(coreFile) | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |             self.reportState('enginerunokandinferiorunrunnable') | 
					
						
							| 
									
										
										
										
											2013-10-01 02:30:12 +02:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2014-02-04 13:32:17 +01:00
										 |  |  |             launchInfo = lldb.SBLaunchInfo(self.processArgs_) | 
					
						
							| 
									
										
										
										
											2016-09-26 13:47:19 +02:00
										 |  |  |             launchInfo.SetWorkingDirectory(self.workingDirectory_) | 
					
						
							| 
									
										
										
										
											2016-12-06 15:39:05 +01:00
										 |  |  |             launchInfo.SetEnvironmentEntries(self.environment_, False) | 
					
						
							| 
									
										
										
										
											2014-02-28 13:03:21 +01:00
										 |  |  |             if self.breakOnMain_: | 
					
						
							|  |  |  |                 self.createBreakpointAtMain() | 
					
						
							| 
									
										
										
										
											2013-10-01 02:30:12 +02:00
										 |  |  |             self.process = self.target.Launch(launchInfo, error) | 
					
						
							| 
									
										
										
										
											2013-11-01 11:32:04 +01:00
										 |  |  |             if not error.Success(): | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |                 self.report(self.describeError(error)) | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |                 self.reportState('enginerunfailed') | 
					
						
							| 
									
										
										
										
											2013-10-29 22:25:41 +01:00
										 |  |  |                 return | 
					
						
							|  |  |  |             self.report('pid="%s"' % self.process.GetProcessID()) | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |             self.reportState('enginerunandinferiorrunok') | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-22 17:55:20 +02:00
										 |  |  |     def loop(self): | 
					
						
							| 
									
										
										
										
											2013-05-31 15:27:54 +02:00
										 |  |  |         event = lldb.SBEvent() | 
					
						
							| 
									
										
										
										
											2014-09-22 17:55:20 +02:00
										 |  |  |         listener = self.debugger.GetListener() | 
					
						
							| 
									
										
										
										
											2013-05-31 15:27:54 +02:00
										 |  |  |         while True: | 
					
						
							|  |  |  |             if listener.WaitForEvent(10000000, event): | 
					
						
							|  |  |  |                 self.handleEvent(event) | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 warn('TIMEOUT') | 
					
						
							| 
									
										
										
										
											2013-05-13 16:04:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-07 08:46:51 +02:00
										 |  |  |     def describeError(self, error): | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  |         desc = lldb.SBStream() | 
					
						
							|  |  |  |         error.GetDescription(desc) | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |         result = 'success="%s",' % int(error.Success()) | 
					
						
							|  |  |  |         result += 'error={type="%s"' % error.GetType() | 
					
						
							|  |  |  |         if error.GetType(): | 
					
						
							|  |  |  |             result += ',status="%s"' % error.GetCString() | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  |         result += ',code="%s"' % error.GetError() | 
					
						
							|  |  |  |         result += ',desc="%s"}' % desc.GetData() | 
					
						
							| 
									
										
										
										
											2013-05-07 08:46:51 +02:00
										 |  |  |         return result | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |     def describeStatus(self, status): | 
					
						
							|  |  |  |         return 'status="%s",' % status | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def describeLocation(self, frame): | 
					
						
							|  |  |  |         if int(frame.pc) == 0xffffffffffffffff: | 
					
						
							|  |  |  |             return '' | 
					
						
							| 
									
										
										
										
											2015-10-09 15:00:20 +02:00
										 |  |  |         fileName = fileNameAsString(frame.line_entry.file) | 
					
						
							|  |  |  |         function = frame.GetFunctionName() | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |         line = frame.line_entry.line | 
					
						
							| 
									
										
										
										
											2015-10-09 15:00:20 +02:00
										 |  |  |         return 'location={file="%s",line="%s",address="%s",function="%s"}' \ | 
					
						
							|  |  |  |             % (fileName, line, frame.pc, function) | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def currentThread(self): | 
					
						
							| 
									
										
										
										
											2014-01-29 11:43:11 +01:00
										 |  |  |         return None if self.process is None else self.process.GetSelectedThread() | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def currentFrame(self): | 
					
						
							| 
									
										
										
										
											2014-01-29 11:43:11 +01:00
										 |  |  |         thread = self.currentThread() | 
					
						
							|  |  |  |         return None if thread is None else thread.GetSelectedFrame() | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-11 15:27:24 +01:00
										 |  |  |     def firstStoppedThread(self): | 
					
						
							|  |  |  |         for i in xrange(0, self.process.GetNumThreads()): | 
					
						
							|  |  |  |             thread = self.process.GetThreadAtIndex(i) | 
					
						
							| 
									
										
										
										
											2013-12-02 10:37:16 +01:00
										 |  |  |             reason = thread.GetStopReason() | 
					
						
							|  |  |  |             if (reason == lldb.eStopReasonBreakpoint or | 
					
						
							|  |  |  |                     reason == lldb.eStopReasonException or | 
					
						
							|  |  |  |                     reason == lldb.eStopReasonPlanComplete or | 
					
						
							|  |  |  |                     reason == lldb.eStopReasonSignal or | 
					
						
							|  |  |  |                     reason == lldb.eStopReasonWatchpoint): | 
					
						
							| 
									
										
										
										
											2013-11-11 15:27:24 +01:00
										 |  |  |                 return thread | 
					
						
							|  |  |  |         return None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |     def fetchThreads(self, args): | 
					
						
							|  |  |  |         result = 'threads=[' | 
					
						
							| 
									
										
										
										
											2013-05-22 12:06:56 +02:00
										 |  |  |         for i in xrange(0, self.process.GetNumThreads()): | 
					
						
							| 
									
										
										
										
											2013-05-02 14:57:06 +02:00
										 |  |  |             thread = self.process.GetThreadAtIndex(i) | 
					
						
							| 
									
										
										
										
											2015-02-04 14:15:14 +01:00
										 |  |  |             if thread.is_stopped: | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |                 state = 'stopped' | 
					
						
							| 
									
										
										
										
											2015-02-04 14:15:14 +01:00
										 |  |  |             elif thread.is_suspended: | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |                 state = 'suspended' | 
					
						
							| 
									
										
										
										
											2015-02-04 14:15:14 +01:00
										 |  |  |             else: | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |                 state = 'unknown' | 
					
						
							| 
									
										
										
										
											2015-02-04 14:15:14 +01:00
										 |  |  |             reason = thread.GetStopReason() | 
					
						
							| 
									
										
										
										
											2013-05-22 12:06:56 +02:00
										 |  |  |             result += '{id="%d"' % thread.GetThreadID() | 
					
						
							|  |  |  |             result += ',index="%s"' % i | 
					
						
							| 
									
										
										
										
											2013-05-29 16:59:16 +02:00
										 |  |  |             result += ',details="%s"' % thread.GetQueueName() | 
					
						
							| 
									
										
										
										
											2015-02-04 14:15:14 +01:00
										 |  |  |             result += ',stop-reason="%s"' % self.stopReason(thread.GetStopReason()) | 
					
						
							|  |  |  |             result += ',state="%s"' % state | 
					
						
							| 
									
										
										
										
											2013-05-02 14:57:06 +02:00
										 |  |  |             result += ',name="%s"' % thread.GetName() | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  |             result += ',frame={' | 
					
						
							|  |  |  |             frame = thread.GetFrameAtIndex(0) | 
					
						
							|  |  |  |             result += 'pc="0x%x"' % frame.pc | 
					
						
							|  |  |  |             result += ',addr="0x%x"' % frame.pc | 
					
						
							|  |  |  |             result += ',fp="0x%x"' % frame.fp | 
					
						
							| 
									
										
										
										
											2013-05-29 16:59:16 +02:00
										 |  |  |             result += ',func="%s"' % frame.GetFunctionName() | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  |             result += ',line="%s"' % frame.line_entry.line | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |             result += ',fullname="%s"' % fileNameAsString(frame.line_entry.file) | 
					
						
							|  |  |  |             result += ',file="%s"' % fileNameAsString(frame.line_entry.file) | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  |             result += '}},' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |         result += '],current-thread-id="%s"' % self.currentThread().id | 
					
						
							|  |  |  |         self.reportResult(result, args) | 
					
						
							| 
									
										
										
										
											2015-03-25 16:34:03 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-11 15:27:24 +01:00
										 |  |  |     def firstUsableFrame(self, thread): | 
					
						
							| 
									
										
										
										
											2013-07-02 15:43:29 +02:00
										 |  |  |         for i in xrange(10): | 
					
						
							| 
									
										
										
										
											2013-06-14 10:03:00 +02:00
										 |  |  |             frame = thread.GetFrameAtIndex(i) | 
					
						
							|  |  |  |             lineEntry = frame.GetLineEntry() | 
					
						
							|  |  |  |             line = lineEntry.GetLine() | 
					
						
							|  |  |  |             if line != 0: | 
					
						
							|  |  |  |                 return i | 
					
						
							|  |  |  |         return None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |     def fetchStack(self, args): | 
					
						
							| 
									
										
										
										
											2013-11-05 16:12:31 +01:00
										 |  |  |         if not self.process: | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |             self.reportResult('msg="No process"', args) | 
					
						
							| 
									
										
										
										
											2013-11-05 16:12:31 +01:00
										 |  |  |             return | 
					
						
							|  |  |  |         thread = self.currentThread() | 
					
						
							|  |  |  |         if not thread: | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |             self.reportResult('msg="No thread"', args) | 
					
						
							| 
									
										
										
										
											2013-11-05 16:12:31 +01:00
										 |  |  |             return | 
					
						
							| 
									
										
										
										
											2014-02-03 13:47:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |         isNativeMixed = int(args.get('nativemixed', 0)) | 
					
						
							| 
									
										
										
										
											2014-02-03 13:47:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-05 14:19:32 +01:00
										 |  |  |         limit = args.get('stacklimit', -1) | 
					
						
							|  |  |  |         (n, isLimited) = (limit, True) if limit > 0 else (thread.GetNumFrames(), False) | 
					
						
							| 
									
										
										
										
											2015-02-04 17:21:55 +01:00
										 |  |  |         self.currentCallContext = None | 
					
						
							| 
									
										
										
										
											2014-03-06 12:04:47 +01:00
										 |  |  |         result = 'stack={current-thread="%s"' % thread.GetThreadID() | 
					
						
							| 
									
										
										
										
											2013-11-05 16:12:31 +01:00
										 |  |  |         result += ',frames=[' | 
					
						
							|  |  |  |         for i in xrange(n): | 
					
						
							|  |  |  |             frame = thread.GetFrameAtIndex(i) | 
					
						
							| 
									
										
										
										
											2014-02-03 13:47:26 +01:00
										 |  |  |             if not frame.IsValid(): | 
					
						
							|  |  |  |                 isLimited = False | 
					
						
							|  |  |  |                 break | 
					
						
							| 
									
										
										
										
											2015-02-04 13:29:42 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-05 16:12:31 +01:00
										 |  |  |             lineEntry = frame.GetLineEntry() | 
					
						
							| 
									
										
										
										
											2015-02-04 13:29:42 +01:00
										 |  |  |             lineNumber = lineEntry.GetLine() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             pc = frame.GetPC() | 
					
						
							|  |  |  |             level = frame.idx | 
					
						
							|  |  |  |             addr = frame.GetPCAddress().GetLoadAddress(self.target) | 
					
						
							| 
									
										
										
										
											2015-10-09 15:00:20 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-04 13:29:42 +01:00
										 |  |  |             functionName = frame.GetFunctionName() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |             if isNativeMixed and functionName == '::qt_qmlDebugMessageAvailable()': | 
					
						
							| 
									
										
										
										
											2015-10-09 15:00:20 +02:00
										 |  |  |                 interpreterStack = self.extractInterpreterStack() | 
					
						
							|  |  |  |                 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) | 
					
						
							|  |  |  |                     result += ('frame={function="%s",file="%s",' | 
					
						
							|  |  |  |                              'line="%s",language="%s",context="%s"}' | 
					
						
							|  |  |  |                         % (function, fileName, lineNumber, language, context)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             fileName = fileNameAsString(lineEntry.file) | 
					
						
							| 
									
										
										
										
											2015-02-04 13:29:42 +01:00
										 |  |  |             result += '{pc="0x%x"' % pc | 
					
						
							|  |  |  |             result += ',level="%d"' % level | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |             result += ',address="0x%x"' % addr | 
					
						
							|  |  |  |             result += ',function="%s"' % functionName | 
					
						
							| 
									
										
										
										
											2015-02-04 13:29:42 +01:00
										 |  |  |             result += ',line="%d"' % lineNumber | 
					
						
							| 
									
										
										
										
											2015-10-08 16:19:57 +02:00
										 |  |  |             result += ',file="%s"},' % fileName | 
					
						
							| 
									
										
										
										
											2014-02-03 13:47:26 +01:00
										 |  |  |         result += ']' | 
					
						
							|  |  |  |         result += ',hasmore="%d"' % isLimited | 
					
						
							|  |  |  |         result += ',limit="%d"' % limit | 
					
						
							|  |  |  |         result += '}' | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |         self.reportResult(result, args) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def reportResult(self, result, args): | 
					
						
							|  |  |  |         self.report('result={token="%s",%s}' % (args.get("token", 0), result)) | 
					
						
							| 
									
										
										
										
											2015-02-24 11:33:25 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-05 10:41:16 +01:00
										 |  |  |     def reportToken(self, args): | 
					
						
							|  |  |  |         if "token" in args: | 
					
						
							|  |  |  |             # Unusual syntax intended, to support the double-click in left | 
					
						
							|  |  |  |             # logview pane feature. | 
					
						
							|  |  |  |             self.report('token(\"%s\")' % args["token"]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-22 10:20:01 +02:00
										 |  |  |     def readRawMemory(self, address, size): | 
					
						
							| 
									
										
										
										
											2013-05-22 14:30:36 +02:00
										 |  |  |         if size == 0: | 
					
						
							| 
									
										
										
										
											2016-09-06 08:54:43 +02:00
										 |  |  |             return bytes() | 
					
						
							| 
									
										
										
										
											2013-05-22 14:30:36 +02:00
										 |  |  |         error = lldb.SBError() | 
					
						
							| 
									
										
										
										
											2016-09-06 08:54:43 +02:00
										 |  |  |         #warn("READ: %s %s" % (address, size)) | 
					
						
							|  |  |  |         res = self.process.ReadMemory(address, size, error) | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |         if res is None or len(res) != size: | 
					
						
							|  |  |  |             # Using code in e.g. readToFirstZero relies on exceptions. | 
					
						
							|  |  |  |             raise RuntimeError("Unreadable %s bytes at 0x%x" % (size, address)) | 
					
						
							| 
									
										
										
										
											2016-09-06 08:54:43 +02:00
										 |  |  |         return res | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-07 08:40:43 +01:00
										 |  |  |     def findStaticMetaObject(self, type): | 
					
						
							|  |  |  |         symbolName = self.mangleName(type.name + '::staticMetaObject') | 
					
						
							| 
									
										
										
										
											2016-07-22 10:20:01 +02:00
										 |  |  |         symbol = self.target.FindFirstGlobalVariable(symbolName) | 
					
						
							| 
									
										
										
										
											2016-09-06 08:54:43 +02:00
										 |  |  |         return symbol.AddressOf().GetValueAsUnsigned() if symbol.IsValid() else 0 | 
					
						
							| 
									
										
										
										
											2014-04-11 13:20:59 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-12 13:20:21 +01:00
										 |  |  |     def findSymbol(self, symbolName): | 
					
						
							|  |  |  |         return self.target.FindFirstGlobalVariable(symbolName) | 
					
						
							| 
									
										
										
										
											2013-07-03 13:32:19 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-22 14:01:07 +01:00
										 |  |  |     def warn(self, msg): | 
					
						
							| 
									
										
										
										
											2014-09-22 18:00:06 +02:00
										 |  |  |         self.put('{name="%s",value="",type="",numchild="0"},' % msg) | 
					
						
							| 
									
										
										
										
											2014-01-22 14:01:07 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-09 15:00:20 +02:00
										 |  |  |     def fetchVariables(self, args): | 
					
						
							|  |  |  |         (ok, res) = self.tryFetchInterpreterVariables(args) | 
					
						
							|  |  |  |         if ok: | 
					
						
							|  |  |  |             self.reportResult(res, args) | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-07 12:23:35 +02:00
										 |  |  |         self.setVariableFetchingOptions(args) | 
					
						
							| 
									
										
										
										
											2014-03-19 12:08:25 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-07 08:57:26 +01:00
										 |  |  |         anyModule = self.target.GetModuleAtIndex(0) | 
					
						
							|  |  |  |         anySymbol = anyModule.GetSymbolAtIndex(0) | 
					
						
							|  |  |  |         self.fakeAddress = int(anySymbol.GetStartAddress()) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-29 11:43:11 +01:00
										 |  |  |         frame = self.currentFrame() | 
					
						
							|  |  |  |         if frame is None: | 
					
						
							| 
									
										
										
										
											2015-10-09 15:00:20 +02:00
										 |  |  |             self.reportResult('error="No frame"', args) | 
					
						
							| 
									
										
										
										
											2014-01-29 11:43:11 +01:00
										 |  |  |             return | 
					
						
							| 
									
										
										
										
											2015-03-26 13:03:38 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-09 15:00:20 +02:00
										 |  |  |         self.output = '' | 
					
						
							| 
									
										
										
										
											2016-10-07 12:23:35 +02:00
										 |  |  |         isPartial = len(self.partialVariable) > 0 | 
					
						
							| 
									
										
										
										
											2015-03-26 13:03:38 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-30 15:35:52 +02:00
										 |  |  |         self.currentIName = 'local' | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |         self.put('data=[') | 
					
						
							| 
									
										
										
										
											2013-05-30 15:35:52 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-04 19:32:24 +01:00
										 |  |  |         with SubItem(self, '[statics]'): | 
					
						
							|  |  |  |             self.put('iname="%s",' % self.currentIName) | 
					
						
							|  |  |  |             self.putEmptyValue() | 
					
						
							|  |  |  |             self.putNumChild(1) | 
					
						
							|  |  |  |             if self.isExpanded(): | 
					
						
							|  |  |  |                 with Children(self): | 
					
						
							|  |  |  |                     statics = frame.GetVariables(False, False, True, False) | 
					
						
							|  |  |  |                     if len(statics): | 
					
						
							|  |  |  |                         for i in xrange(len(statics)): | 
					
						
							|  |  |  |                             staticVar = statics[i] | 
					
						
							| 
									
										
										
										
											2016-09-26 14:29:16 +02:00
										 |  |  |                             staticVar.SetPreferSyntheticValue(False) | 
					
						
							| 
									
										
										
										
											2014-02-04 19:32:24 +01:00
										 |  |  |                             typename = staticVar.GetType().GetName() | 
					
						
							|  |  |  |                             name = staticVar.GetName() | 
					
						
							|  |  |  |                             with SubItem(self, i): | 
					
						
							|  |  |  |                                 self.put('name="%s",' % name) | 
					
						
							|  |  |  |                                 self.put('iname="%s",' % self.currentIName) | 
					
						
							| 
									
										
										
										
											2016-09-06 08:54:43 +02:00
										 |  |  |                                 self.putItem(self.fromNativeValue(staticVar)) | 
					
						
							| 
									
										
										
										
											2014-02-04 19:32:24 +01:00
										 |  |  |                     else: | 
					
						
							|  |  |  |                         with SubItem(self, "None"): | 
					
						
							|  |  |  |                             self.putEmptyValue() | 
					
						
							|  |  |  |                             self.putNumChild(0) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-20 11:52:06 +02:00
										 |  |  |         # FIXME: Implement shortcut for partial updates. | 
					
						
							|  |  |  |         #if isPartial: | 
					
						
							|  |  |  |         #    values = [frame.FindVariable(partialVariable)] | 
					
						
							|  |  |  |         #else: | 
					
						
							|  |  |  |         if True: | 
					
						
							|  |  |  |             values = list(frame.GetVariables(True, True, False, False)) | 
					
						
							|  |  |  |             values.reverse() # To get shadowed vars numbered backwards. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         variables = [] | 
					
						
							|  |  |  |         for val in values: | 
					
						
							| 
									
										
										
										
											2016-09-26 14:29:16 +02:00
										 |  |  |             val.SetPreferSyntheticValue(False) | 
					
						
							| 
									
										
										
										
											2016-09-20 11:52:06 +02:00
										 |  |  |             if not val.IsValid(): | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             self.currentContextValue = val | 
					
						
							|  |  |  |             name = val.GetName() | 
					
						
							|  |  |  |             if name is None: | 
					
						
							|  |  |  |                 # This can happen for unnamed function parameters with | 
					
						
							|  |  |  |                 # default values:  void foo(int = 0) | 
					
						
							|  |  |  |                 continue | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |             value = self.fromNativeFrameValue(val) | 
					
						
							| 
									
										
										
										
											2016-09-20 11:52:06 +02:00
										 |  |  |             variables.append(value) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.handleLocals(variables) | 
					
						
							| 
									
										
										
										
											2015-03-26 13:03:38 +01:00
										 |  |  |         self.handleWatches(args) | 
					
						
							| 
									
										
										
										
											2013-05-30 15:35:52 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |         self.put('],partial="%d"' % isPartial) | 
					
						
							| 
									
										
										
										
											2015-10-09 15:00:20 +02:00
										 |  |  |         self.reportResult(self.output, args) | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |     def fetchRegisters(self, args = None): | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  |         if self.process is None: | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |             result = 'process="none"' | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  |         else: | 
					
						
							|  |  |  |             frame = self.currentFrame() | 
					
						
							| 
									
										
										
										
											2014-01-29 11:43:11 +01:00
										 |  |  |             if frame: | 
					
						
							|  |  |  |                 result = 'registers=[' | 
					
						
							|  |  |  |                 for group in frame.GetRegisters(): | 
					
						
							|  |  |  |                     for reg in group: | 
					
						
							| 
									
										
										
										
											2015-08-27 13:38:41 +02:00
										 |  |  |                         value = ''.join(["%02x" % x for x in reg.GetData().uint8s]) | 
					
						
							| 
									
										
										
										
											2014-01-29 11:43:11 +01:00
										 |  |  |                         result += '{name="%s"' % reg.GetName() | 
					
						
							| 
									
										
										
										
											2015-08-27 13:38:41 +02:00
										 |  |  |                         result += ',value="0x%s"' % value | 
					
						
							| 
									
										
										
										
											2014-12-17 13:14:29 +01:00
										 |  |  |                         result += ',size="%s"' % reg.GetByteSize() | 
					
						
							| 
									
										
										
										
											2014-01-29 11:43:11 +01:00
										 |  |  |                         result += ',type="%s"},' % reg.GetType() | 
					
						
							|  |  |  |                 result += ']' | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |         self.reportResult(result, args) | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-25 13:48:55 +02:00
										 |  |  |     def setRegister(self, args): | 
					
						
							|  |  |  |         name = args["name"] | 
					
						
							|  |  |  |         value = args["value"] | 
					
						
							|  |  |  |         result = lldb.SBCommandReturnObject() | 
					
						
							| 
									
										
										
										
											2015-08-27 13:38:41 +02:00
										 |  |  |         interp = self.debugger.GetCommandInterpreter() | 
					
						
							|  |  |  |         interp.HandleCommand("register write %s %s" % (name, value), result) | 
					
						
							| 
									
										
										
										
											2015-08-25 13:48:55 +02:00
										 |  |  |         success = result.Succeeded() | 
					
						
							|  |  |  |         if success: | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |             self.reportResult('output="%s"' % result.GetOutput(), args) | 
					
						
							| 
									
										
										
										
											2015-08-27 13:38:41 +02:00
										 |  |  |             return | 
					
						
							|  |  |  |         # Try again with  register write xmm0 "{0x00 ... 0x02}" syntax: | 
					
						
							|  |  |  |         vec = ' '.join(["0x" + value[i:i+2] for i in range(2, len(value), 2)]) | 
					
						
							|  |  |  |         success = interp.HandleCommand('register write %s "{%s}"' % (name, vec), result) | 
					
						
							|  |  |  |         if success: | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |             self.reportResult('output="%s"' % result.GetOutput(), args) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.reportResult('error="%s"' % result.GetError(), args) | 
					
						
							| 
									
										
										
										
											2015-08-25 13:48:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  |     def report(self, stuff): | 
					
						
							| 
									
										
										
										
											2014-03-19 12:08:25 +01:00
										 |  |  |         with self.outputLock: | 
					
						
							| 
									
										
										
										
											2015-01-30 12:36:04 +01:00
										 |  |  |             sys.stdout.write("@\n" + stuff + "@\n") | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |     def reportState(self, state): | 
					
						
							|  |  |  |         self.report('state="%s"' % state) | 
					
						
							| 
									
										
										
										
											2014-02-06 16:47:07 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |     def interruptInferior(self, args): | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  |         if self.process is None: | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |             self.reportResult('status="No process to interrupt",success="0"', args) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.isInterrupting_ = True | 
					
						
							|  |  |  |             error = self.process.Stop() | 
					
						
							| 
									
										
										
										
											2015-10-09 15:00:20 +02:00
										 |  |  |             self.reportResult(self.describeError(error), args) | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |     def detachInferior(self, args): | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  |         if self.process is None: | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |             self.reportResult('status="No process to detach from."', args) | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  |         else: | 
					
						
							|  |  |  |             error = self.process.Detach() | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |             self.reportResult(self.describeError(error), args) | 
					
						
							| 
									
										
										
										
											2013-04-10 13:55:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |     def continueInferior(self, args): | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  |         if self.process is None: | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |             self.reportResult('status="No process to continue."', args) | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |             # Can fail when attaching to GDBserver. | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  |             error = self.process.Continue() | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |             self.reportResult(self.describeError(error), args) | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |     def quitDebugger(self, args): | 
					
						
							| 
									
										
										
										
											2014-03-19 12:12:24 +01:00
										 |  |  |         self.reportState("inferiorshutdownrequested") | 
					
						
							| 
									
										
										
										
											2013-06-24 17:40:00 +02:00
										 |  |  |         self.process.Kill() | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |         self.reportResult('', args) | 
					
						
							| 
									
										
										
										
											2013-06-24 17:40:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  |     def handleEvent(self, event): | 
					
						
							|  |  |  |         out = lldb.SBStream() | 
					
						
							|  |  |  |         event.GetDescription(out) | 
					
						
							| 
									
										
										
										
											2013-05-02 14:31:35 +02:00
										 |  |  |         #warn("EVENT: %s" % event) | 
					
						
							| 
									
										
										
										
											2015-01-23 17:54:00 +01:00
										 |  |  |         eventType = event.GetType() | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  |         msg = lldb.SBEvent.GetCStringFromEvent(event) | 
					
						
							|  |  |  |         flavor = event.GetDataFlavor() | 
					
						
							| 
									
										
										
										
											2013-05-02 14:31:35 +02:00
										 |  |  |         state = lldb.SBProcess.GetStateFromEvent(event) | 
					
						
							| 
									
										
										
										
											2015-02-04 13:29:42 +01:00
										 |  |  |         bp = lldb.SBBreakpoint.GetBreakpointFromEvent(event) | 
					
						
							| 
									
										
										
										
											2016-09-06 08:54:43 +02:00
										 |  |  |         skipEventReporting = self.debuggerCommandInProgress \ | 
					
						
							|  |  |  |             and eventType in (lldb.SBProcess.eBroadcastBitSTDOUT, lldb.SBProcess.eBroadcastBitSTDERR) | 
					
						
							| 
									
										
										
										
											2015-02-04 13:29:42 +01:00
										 |  |  |         self.report('event={type="%s",data="%s",msg="%s",flavor="%s",state="%s",bp="%s"}' | 
					
						
							| 
									
										
										
										
											2015-02-04 14:15:14 +01:00
										 |  |  |             % (eventType, out.GetData(), msg, flavor, self.stateName(state), bp)) | 
					
						
							| 
									
										
										
										
											2013-05-02 14:31:35 +02:00
										 |  |  |         if state != self.eventState: | 
					
						
							| 
									
										
										
										
											2016-08-02 14:50:54 +02:00
										 |  |  |             if not skipEventReporting: | 
					
						
							|  |  |  |                 self.eventState = state | 
					
						
							| 
									
										
										
										
											2013-05-22 14:30:36 +02:00
										 |  |  |             if state == lldb.eStateExited: | 
					
						
							| 
									
										
										
										
											2017-09-19 12:37:56 +02:00
										 |  |  |                 if not self.isShuttingDown_: | 
					
						
							| 
									
										
										
										
											2014-03-19 12:12:24 +01:00
										 |  |  |                     self.reportState("inferiorexited") | 
					
						
							| 
									
										
										
										
											2013-05-29 15:38:49 +02:00
										 |  |  |                 self.report('exited={status="%s",desc="%s"}' | 
					
						
							| 
									
										
										
										
											2013-05-22 14:30:36 +02:00
										 |  |  |                     % (self.process.GetExitStatus(), self.process.GetExitDescription())) | 
					
						
							| 
									
										
										
										
											2013-06-24 17:40:00 +02:00
										 |  |  |             elif state == lldb.eStateStopped: | 
					
						
							| 
									
										
										
										
											2015-02-04 13:29:42 +01:00
										 |  |  |                 stoppedThread = self.firstStoppedThread() | 
					
						
							|  |  |  |                 if stoppedThread: | 
					
						
							|  |  |  |                     #self.report("STOPPED THREAD: %s" % stoppedThread) | 
					
						
							|  |  |  |                     frame = stoppedThread.GetFrameAtIndex(0) | 
					
						
							|  |  |  |                     #self.report("FRAME: %s" % frame) | 
					
						
							|  |  |  |                     function = frame.GetFunction() | 
					
						
							| 
									
										
										
										
											2015-10-09 15:00:20 +02:00
										 |  |  |                     functionName = function.GetName() | 
					
						
							|  |  |  |                     if functionName == "::qt_qmlDebugConnectorOpen()": | 
					
						
							|  |  |  |                         self.report("RESOLVER HIT") | 
					
						
							|  |  |  |                         for resolver in self.interpreterBreakpointResolvers: | 
					
						
							|  |  |  |                             resolver() | 
					
						
							|  |  |  |                         self.report("AUTO-CONTINUE AFTER RESOLVING") | 
					
						
							|  |  |  |                         self.reportState("inferiorstopok") | 
					
						
							| 
									
										
										
										
											2015-02-04 13:29:42 +01:00
										 |  |  |                         self.process.Continue(); | 
					
						
							|  |  |  |                         return | 
					
						
							| 
									
										
										
										
											2015-10-14 13:26:22 +02:00
										 |  |  |                     if functionName == "::qt_qmlDebugMessageAvailable()": | 
					
						
							|  |  |  |                         self.report("ASYNC MESSAGE FROM SERVICE") | 
					
						
							|  |  |  |                         res = self.handleInterpreterMessage() | 
					
						
							| 
									
										
										
										
											2015-10-09 15:00:20 +02:00
										 |  |  |                         if not res: | 
					
						
							|  |  |  |                             self.report("EVENT NEEDS NO STOP") | 
					
						
							|  |  |  |                             self.reportState("stopped") | 
					
						
							|  |  |  |                             self.process.Continue(); | 
					
						
							|  |  |  |                             return | 
					
						
							| 
									
										
										
										
											2013-06-24 17:40:00 +02:00
										 |  |  |                 if self.isInterrupting_: | 
					
						
							|  |  |  |                     self.isInterrupting_ = False | 
					
						
							| 
									
										
										
										
											2017-09-19 12:37:56 +02:00
										 |  |  |                     self.reportState("inferiorstopok") | 
					
						
							| 
									
										
										
										
											2014-03-03 16:59:56 +01:00
										 |  |  |                 elif self.ignoreStops > 0: | 
					
						
							|  |  |  |                     self.ignoreStops -= 1 | 
					
						
							|  |  |  |                     self.process.Continue() | 
					
						
							| 
									
										
										
										
											2015-02-27 11:56:03 +01:00
										 |  |  |                 elif self.silentStops > 0: | 
					
						
							|  |  |  |                     self.silentStops -= 1 | 
					
						
							| 
									
										
										
										
											2013-06-24 17:40:00 +02:00
										 |  |  |                 else: | 
					
						
							| 
									
										
										
										
											2014-03-19 12:12:24 +01:00
										 |  |  |                     self.reportState("stopped") | 
					
						
							| 
									
										
										
										
											2013-06-24 17:40:00 +02:00
										 |  |  |             else: | 
					
						
							| 
									
										
										
										
											2016-08-02 14:50:54 +02:00
										 |  |  |                 if not skipEventReporting: | 
					
						
							|  |  |  |                     self.reportState(self.stateName(state)) | 
					
						
							| 
									
										
										
										
											2015-01-23 17:54:00 +01:00
										 |  |  |         if eventType == lldb.SBProcess.eBroadcastBitStateChanged: # 1 | 
					
						
							| 
									
										
										
										
											2013-06-14 10:03:00 +02:00
										 |  |  |             state = self.process.GetState() | 
					
						
							|  |  |  |             if state == lldb.eStateStopped: | 
					
						
							| 
									
										
										
										
											2013-11-11 15:27:24 +01:00
										 |  |  |                 stoppedThread = self.firstStoppedThread() | 
					
						
							|  |  |  |                 if stoppedThread: | 
					
						
							|  |  |  |                     self.process.SetSelectedThread(stoppedThread) | 
					
						
							| 
									
										
										
										
											2015-01-23 17:54:00 +01:00
										 |  |  |         elif eventType == lldb.SBProcess.eBroadcastBitInterrupt: # 2 | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  |             pass | 
					
						
							| 
									
										
										
										
											2015-01-23 17:54:00 +01:00
										 |  |  |         elif eventType == lldb.SBProcess.eBroadcastBitSTDOUT: | 
					
						
							| 
									
										
										
										
											2013-05-29 12:14:49 +02:00
										 |  |  |             # FIXME: Size? | 
					
						
							|  |  |  |             msg = self.process.GetSTDOUT(1024) | 
					
						
							| 
									
										
										
										
											2016-04-05 15:20:54 +02:00
										 |  |  |             if msg is not None: | 
					
						
							|  |  |  |                 self.report('output={channel="stdout",data="%s"}' % self.hexencode(msg)) | 
					
						
							| 
									
										
										
										
											2015-01-23 17:54:00 +01:00
										 |  |  |         elif eventType == lldb.SBProcess.eBroadcastBitSTDERR: | 
					
						
							| 
									
										
										
										
											2013-05-29 12:14:49 +02:00
										 |  |  |             msg = self.process.GetSTDERR(1024) | 
					
						
							| 
									
										
										
										
											2016-04-05 15:20:54 +02:00
										 |  |  |             if msg is not None: | 
					
						
							|  |  |  |                 self.report('output={channel="stderr",data="%s"}' % self.hexencode(msg)) | 
					
						
							| 
									
										
										
										
											2015-01-23 17:54:00 +01:00
										 |  |  |         elif eventType == lldb.SBProcess.eBroadcastBitProfileData: | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-05 19:06:24 +01:00
										 |  |  |     def describeBreakpoint(self, bp): | 
					
						
							| 
									
										
										
										
											2013-06-14 15:15:09 +02:00
										 |  |  |         isWatch = isinstance(bp, lldb.SBWatchpoint) | 
					
						
							|  |  |  |         if isWatch: | 
					
						
							|  |  |  |             result  = 'lldbid="%s"' % (qqWatchpointOffset + bp.GetID()) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             result  = 'lldbid="%s"' % bp.GetID() | 
					
						
							| 
									
										
										
										
											2016-01-06 13:16:37 +01:00
										 |  |  |         result += ',valid="%s"' % (1 if bp.IsValid() else 0) | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  |         result += ',hitcount="%s"' % bp.GetHitCount() | 
					
						
							| 
									
										
										
										
											2016-01-06 13:16:37 +01:00
										 |  |  |         if bp.IsValid(): | 
					
						
							|  |  |  |             if isinstance(bp, lldb.SBBreakpoint): | 
					
						
							|  |  |  |                 result += ',threadid="%s"' % bp.GetThreadID() | 
					
						
							|  |  |  |                 result += ',oneshot="%s"' % (1 if bp.IsOneShot() else 0) | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |         cond = bp.GetCondition() | 
					
						
							|  |  |  |         result += ',condition="%s"' % self.hexencode("" if cond is None else cond) | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  |         result += ',enabled="%s"' % (1 if bp.IsEnabled() else 0) | 
					
						
							|  |  |  |         result += ',valid="%s"' % (1 if bp.IsValid() else 0) | 
					
						
							|  |  |  |         result += ',ignorecount="%s"' % bp.GetIgnoreCount() | 
					
						
							| 
									
										
										
										
											2016-01-06 13:16:37 +01:00
										 |  |  |         if bp.IsValid() and isinstance(bp, lldb.SBBreakpoint): | 
					
						
							|  |  |  |             result += ',locations=[' | 
					
						
							|  |  |  |             lineEntry = None | 
					
						
							|  |  |  |             for i in xrange(bp.GetNumLocations()): | 
					
						
							|  |  |  |                 loc = bp.GetLocationAtIndex(i) | 
					
						
							|  |  |  |                 addr = loc.GetAddress() | 
					
						
							|  |  |  |                 lineEntry = addr.GetLineEntry() | 
					
						
							|  |  |  |                 result += '{locid="%s"' % loc.GetID() | 
					
						
							|  |  |  |                 result += ',function="%s"' % addr.GetFunction().GetName() | 
					
						
							|  |  |  |                 result += ',enabled="%s"' % (1 if loc.IsEnabled() else 0) | 
					
						
							|  |  |  |                 result += ',resolved="%s"' % (1 if loc.IsResolved() else 0) | 
					
						
							|  |  |  |                 result += ',valid="%s"' % (1 if loc.IsValid() else 0) | 
					
						
							|  |  |  |                 result += ',ignorecount="%s"' % loc.GetIgnoreCount() | 
					
						
							|  |  |  |                 result += ',file="%s"' % lineEntry.GetFileSpec() | 
					
						
							|  |  |  |                 result += ',line="%s"' % lineEntry.GetLine() | 
					
						
							|  |  |  |                 result += ',addr="%s"},' % addr.GetFileAddress() | 
					
						
							|  |  |  |             result += ']' | 
					
						
							|  |  |  |             if lineEntry is not None: | 
					
						
							|  |  |  |                 result += ',file="%s"' % lineEntry.GetFileSpec() | 
					
						
							|  |  |  |                 result += ',line="%s"' % lineEntry.GetLine() | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  |         return result | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-28 13:03:21 +01:00
										 |  |  |     def createBreakpointAtMain(self): | 
					
						
							|  |  |  |         return self.target.BreakpointCreateByName( | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |             'main', self.target.GetExecutable().GetFilename()) | 
					
						
							| 
									
										
										
										
											2014-02-28 13:03:21 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-02 13:48:33 +01:00
										 |  |  |     def insertBreakpoint(self, args): | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |         bpType = args['type'] | 
					
						
							| 
									
										
										
										
											2015-02-04 13:29:42 +01:00
										 |  |  |         if bpType == BreakpointByFileAndLine: | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |             fileName = args['file'] | 
					
						
							|  |  |  |             if fileName.endswith('.js') or fileName.endswith('.qml'): | 
					
						
							| 
									
										
										
										
											2015-10-14 13:26:22 +02:00
										 |  |  |                 self.insertInterpreterBreakpoint(args) | 
					
						
							| 
									
										
										
										
											2015-02-04 13:29:42 +01:00
										 |  |  |                 return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |         extra = '' | 
					
						
							| 
									
										
										
										
											2015-02-02 13:48:33 +01:00
										 |  |  |         more = True | 
					
						
							| 
									
										
										
										
											2013-05-16 17:37:41 +02:00
										 |  |  |         if bpType == BreakpointByFileAndLine: | 
					
						
							| 
									
										
										
										
											2014-03-05 19:06:24 +01:00
										 |  |  |             bp = self.target.BreakpointCreateByLocation( | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |                 str(args['file']), int(args['line'])) | 
					
						
							| 
									
										
										
										
											2013-05-16 17:37:41 +02:00
										 |  |  |         elif bpType == BreakpointByFunction: | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |             bp = self.target.BreakpointCreateByName(args['function']) | 
					
						
							| 
									
										
										
										
											2013-06-14 15:15:09 +02:00
										 |  |  |         elif bpType == BreakpointByAddress: | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |             bp = self.target.BreakpointCreateByAddress(args['address']) | 
					
						
							| 
									
										
										
										
											2013-05-16 17:37:41 +02:00
										 |  |  |         elif bpType == BreakpointAtMain: | 
					
						
							| 
									
										
										
										
											2014-03-05 19:06:24 +01:00
										 |  |  |             bp = self.createBreakpointAtMain() | 
					
						
							| 
									
										
										
										
											2013-06-13 18:22:44 +02:00
										 |  |  |         elif bpType == BreakpointAtThrow: | 
					
						
							| 
									
										
										
										
											2014-03-05 19:06:24 +01:00
										 |  |  |             bp = self.target.BreakpointCreateForException( | 
					
						
							| 
									
										
										
										
											2013-06-13 18:22:44 +02:00
										 |  |  |                 lldb.eLanguageTypeC_plus_plus, False, True) | 
					
						
							|  |  |  |         elif bpType == BreakpointAtCatch: | 
					
						
							| 
									
										
										
										
											2014-03-05 19:06:24 +01:00
										 |  |  |             bp = self.target.BreakpointCreateForException( | 
					
						
							| 
									
										
										
										
											2013-06-13 18:22:44 +02:00
										 |  |  |                 lldb.eLanguageTypeC_plus_plus, True, False) | 
					
						
							| 
									
										
										
										
											2013-06-14 15:15:09 +02:00
										 |  |  |         elif bpType == WatchpointAtAddress: | 
					
						
							|  |  |  |             error = lldb.SBError() | 
					
						
							| 
									
										
										
										
											2016-01-06 13:16:37 +01:00
										 |  |  |             # This might yield bp.IsValid() == False and | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |             # error.desc == 'process is not alive'. | 
					
						
							|  |  |  |             bp = self.target.WatchAddress(args['address'], 4, False, True, error) | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |             extra = self.describeError(error) | 
					
						
							| 
									
										
										
										
											2013-06-14 15:15:09 +02:00
										 |  |  |         elif bpType == WatchpointAtExpression: | 
					
						
							|  |  |  |             # FIXME: Top level-only for now. | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 frame = self.currentFrame() | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |                 value = frame.FindVariable(args['expression']) | 
					
						
							| 
									
										
										
										
											2013-06-14 15:15:09 +02:00
										 |  |  |                 error = lldb.SBError() | 
					
						
							| 
									
										
										
										
											2014-03-05 19:06:24 +01:00
										 |  |  |                 bp = self.target.WatchAddress(value.GetLoadAddress(), | 
					
						
							| 
									
										
										
										
											2013-06-14 15:15:09 +02:00
										 |  |  |                     value.GetByteSize(), False, True, error) | 
					
						
							|  |  |  |             except: | 
					
						
							| 
									
										
										
										
											2015-02-02 13:48:33 +01:00
										 |  |  |                 bp = self.target.BreakpointCreateByName(None) | 
					
						
							| 
									
										
										
										
											2013-05-16 17:37:41 +02:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2014-02-06 17:50:21 +01:00
										 |  |  |             # This leaves the unhandled breakpoint in a (harmless) | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |             # 'pending' state. | 
					
						
							| 
									
										
										
										
											2015-02-02 13:48:33 +01:00
										 |  |  |             bp = self.target.BreakpointCreateByName(None) | 
					
						
							|  |  |  |             more = False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-06 13:16:37 +01:00
										 |  |  |         if more and bp.IsValid(): | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |             bp.SetIgnoreCount(int(args['ignorecount'])) | 
					
						
							|  |  |  |             bp.SetCondition(self.hexdecode(args['condition'])) | 
					
						
							|  |  |  |             bp.SetEnabled(bool(args['enabled'])) | 
					
						
							| 
									
										
										
										
											2016-04-13 18:19:45 +02:00
										 |  |  |             bp.SetScriptCallbackBody('\n'.join([ | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |                 'def foo(frame = frame, bp_loc = bp_loc, dict = internal_dict):', | 
					
						
							|  |  |  |                 '  ' + self.hexdecode(args['command']).replace('\n', '\n  '), | 
					
						
							|  |  |  |                 'from cStringIO import StringIO', | 
					
						
							|  |  |  |                 'origout = sys.stdout', | 
					
						
							|  |  |  |                 'sys.stdout = StringIO()', | 
					
						
							|  |  |  |                 'result = foo()', | 
					
						
							|  |  |  |                 'd = lldb.theDumper', | 
					
						
							|  |  |  |                 'output = d.hexencode(sys.stdout.getvalue())', | 
					
						
							|  |  |  |                 'sys.stdout = origout', | 
					
						
							| 
									
										
										
										
											2016-11-17 12:17:14 +01:00
										 |  |  |                 'd.report("output={channel=\"stderr\",data=\" + output + \"}")', | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |                 'if result is False:', | 
					
						
							|  |  |  |                 '  d.reportState("continueafternextstop")', | 
					
						
							|  |  |  |                 'return True' | 
					
						
							| 
									
										
										
										
											2016-04-13 18:19:45 +02:00
										 |  |  |             ])) | 
					
						
							| 
									
										
										
										
											2016-01-06 13:16:37 +01:00
										 |  |  |             if isinstance(bp, lldb.SBBreakpoint): | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |                 bp.SetOneShot(bool(args['oneshot'])) | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |         self.reportResult(self.describeBreakpoint(bp) + extra, args) | 
					
						
							| 
									
										
										
										
											2013-05-16 17:37:41 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def changeBreakpoint(self, args): | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |         lldbId = int(args['lldbid']) | 
					
						
							| 
									
										
										
										
											2015-02-02 13:48:33 +01:00
										 |  |  |         if lldbId > qqWatchpointOffset: | 
					
						
							|  |  |  |             bp = self.target.FindWatchpointByID(lldbId) | 
					
						
							| 
									
										
										
										
											2013-06-14 15:15:09 +02:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2015-02-02 13:48:33 +01:00
										 |  |  |             bp = self.target.FindBreakpointByID(lldbId) | 
					
						
							| 
									
										
										
										
											2016-01-06 13:16:37 +01:00
										 |  |  |         if bp.IsValid(): | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |             bp.SetIgnoreCount(int(args['ignorecount'])) | 
					
						
							|  |  |  |             bp.SetCondition(self.hexdecode(args['condition'])) | 
					
						
							|  |  |  |             bp.SetEnabled(bool(args['enabled'])) | 
					
						
							| 
									
										
										
										
											2016-01-06 13:16:37 +01:00
										 |  |  |             if isinstance(bp, lldb.SBBreakpoint): | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |                 bp.SetOneShot(bool(args['oneshot'])) | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |         self.reportResult(self.describeBreakpoint(bp), args) | 
					
						
							| 
									
										
										
										
											2013-05-16 17:37:41 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def removeBreakpoint(self, args): | 
					
						
							| 
									
										
										
										
											2015-02-02 13:48:33 +01:00
										 |  |  |         lldbId = int(args['lldbid']) | 
					
						
							|  |  |  |         if lldbId > qqWatchpointOffset: | 
					
						
							|  |  |  |             res = self.target.DeleteWatchpoint(lldbId - qqWatchpointOffset) | 
					
						
							|  |  |  |         res = self.target.BreakpointDelete(lldbId) | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |         self.reportResult('success="%s"' % int(res), args) | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |     def fetchModules(self, args): | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  |         result = 'modules=[' | 
					
						
							| 
									
										
										
										
											2013-05-22 14:30:36 +02:00
										 |  |  |         for i in xrange(self.target.GetNumModules()): | 
					
						
							|  |  |  |             module = self.target.GetModuleAtIndex(i) | 
					
						
							| 
									
										
										
										
											2013-05-29 16:06:07 +02:00
										 |  |  |             result += '{file="%s"' % module.file.fullpath | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  |             result += ',name="%s"' % module.file.basename | 
					
						
							| 
									
										
										
										
											2013-05-07 11:39:31 +02:00
										 |  |  |             result += ',addrsize="%s"' % module.addr_size | 
					
						
							|  |  |  |             result += ',triple="%s"' % module.triple | 
					
						
							|  |  |  |             #result += ',sections={' | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  |             #for section in module.sections: | 
					
						
							|  |  |  |             #    result += '[name="%s"' % section.name | 
					
						
							|  |  |  |             #    result += ',addr="%s"' % section.addr | 
					
						
							| 
									
										
										
										
											2013-05-07 11:39:31 +02:00
										 |  |  |             #    result += ',size="%s"],' % section.size | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  |             #result += '}' | 
					
						
							|  |  |  |             result += '},' | 
					
						
							|  |  |  |         result += ']' | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |         self.reportResult(result, args) | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |     def fetchSymbols(self, args): | 
					
						
							| 
									
										
										
										
											2013-05-07 12:34:10 +02:00
										 |  |  |         moduleName = args['module'] | 
					
						
							| 
									
										
										
										
											2013-05-07 11:39:31 +02:00
										 |  |  |         #file = lldb.SBFileSpec(moduleName) | 
					
						
							|  |  |  |         #module = self.target.FindModule(file) | 
					
						
							| 
									
										
										
										
											2013-05-22 14:30:36 +02:00
										 |  |  |         for i in xrange(self.target.GetNumModules()): | 
					
						
							|  |  |  |             module = self.target.GetModuleAtIndex(i) | 
					
						
							| 
									
										
										
										
											2013-05-29 16:24:17 +02:00
										 |  |  |             if module.file.fullpath == moduleName: | 
					
						
							| 
									
										
										
										
											2013-05-07 11:39:31 +02:00
										 |  |  |                 break | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |         result = 'symbols={valid="%s"' % module.IsValid() | 
					
						
							| 
									
										
										
										
											2013-05-07 11:39:31 +02:00
										 |  |  |         result += ',sections="%s"' % module.GetNumSections() | 
					
						
							|  |  |  |         result += ',symbols=[' | 
					
						
							|  |  |  |         for symbol in module.symbols: | 
					
						
							|  |  |  |             startAddress = symbol.GetStartAddress().GetLoadAddress(self.target) | 
					
						
							|  |  |  |             endAddress = symbol.GetEndAddress().GetLoadAddress(self.target) | 
					
						
							|  |  |  |             result += '{type="%s"' % symbol.GetType() | 
					
						
							|  |  |  |             result += ',name="%s"' % symbol.GetName() | 
					
						
							|  |  |  |             result += ',address="0x%x"' % startAddress | 
					
						
							|  |  |  |             result += ',demangled="%s"' % symbol.GetMangledName() | 
					
						
							|  |  |  |             result += ',size="%s"' % (endAddress - startAddress) | 
					
						
							|  |  |  |             result += '},' | 
					
						
							|  |  |  |         result += ']}' | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |         self.reportResult(result, args) | 
					
						
							| 
									
										
										
										
											2013-05-07 11:39:31 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |     def executeNext(self, args): | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  |         self.currentThread().StepOver() | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |         self.reportResult('', args) | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |     def executeNextI(self, args): | 
					
						
							| 
									
										
										
										
											2013-05-24 08:32:12 +02:00
										 |  |  |         self.currentThread().StepInstruction(lldb.eOnlyThisThread) | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |         self.reportResult('', args) | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |     def executeStep(self, args): | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  |         self.currentThread().StepInto() | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |         self.reportResult('', args) | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |     def shutdownInferior(self, args): | 
					
						
							| 
									
										
										
										
											2013-05-29 15:38:49 +02:00
										 |  |  |         self.isShuttingDown_ = True | 
					
						
							| 
									
										
										
										
											2014-06-02 16:45:12 +02:00
										 |  |  |         if self.process is None: | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |             self.reportState('inferiorshutdownok') | 
					
						
							| 
									
										
										
										
											2014-06-02 16:45:12 +02:00
										 |  |  |         else: | 
					
						
							|  |  |  |             state = self.process.GetState() | 
					
						
							|  |  |  |             if state == lldb.eStateStopped: | 
					
						
							|  |  |  |                 self.process.Kill() | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |             self.reportState('inferiorshutdownok') | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |         self.reportResult('', args) | 
					
						
							| 
									
										
										
										
											2013-05-29 15:38:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |     def quit(self, args): | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |         self.reportState('engineshutdownok') | 
					
						
							| 
									
										
										
										
											2013-05-29 15:38:49 +02:00
										 |  |  |         self.process.Kill() | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |         self.reportResult('', args) | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |     def executeStepI(self, args): | 
					
						
							| 
									
										
										
										
											2013-05-24 08:32:12 +02:00
										 |  |  |         self.currentThread().StepInstruction(lldb.eOnlyThisThread) | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |         self.reportResult('', args) | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-05 10:41:16 +01:00
										 |  |  |     def executeStepOut(self, args = {}): | 
					
						
							| 
									
										
										
										
											2013-05-24 08:32:12 +02:00
										 |  |  |         self.currentThread().StepOut() | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |         self.reportResult('', args) | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-06 16:47:07 +01:00
										 |  |  |     def executeRunToLocation(self, args): | 
					
						
							| 
									
										
										
										
											2015-03-05 10:41:16 +01:00
										 |  |  |         self.reportToken(args) | 
					
						
							| 
									
										
										
										
											2014-02-06 16:47:07 +01:00
										 |  |  |         addr = args.get('address', 0) | 
					
						
							|  |  |  |         if addr: | 
					
						
							| 
									
										
										
										
											2015-08-10 13:25:30 +02:00
										 |  |  |             # Does not seem to hit anything on Linux: | 
					
						
							|  |  |  |             # self.currentThread().RunToAddress(addr) | 
					
						
							|  |  |  |             bp = self.target.BreakpointCreateByAddress(addr) | 
					
						
							|  |  |  |             if bp.GetNumLocations() == 0: | 
					
						
							|  |  |  |                 self.target.BreakpointDelete(bp.GetID()) | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |                 self.reportResult(self.describeStatus('No target location found.') | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |                     + self.describeLocation(frame), args) | 
					
						
							| 
									
										
										
										
											2015-08-10 13:25:30 +02:00
										 |  |  |                 return | 
					
						
							|  |  |  |             bp.SetOneShot(True) | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |             self.reportResult('', args) | 
					
						
							| 
									
										
										
										
											2015-08-10 13:25:30 +02:00
										 |  |  |             self.process.Continue() | 
					
						
							| 
									
										
										
										
											2014-02-06 16:47:07 +01:00
										 |  |  |         else: | 
					
						
							|  |  |  |             frame = self.currentFrame() | 
					
						
							|  |  |  |             file = args['file'] | 
					
						
							|  |  |  |             line = int(args['line']) | 
					
						
							|  |  |  |             error = self.currentThread().StepOverUntil(frame, lldb.SBFileSpec(file), line) | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |             self.reportResult(self.describeError(error), args) | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |             self.reportState('running') | 
					
						
							|  |  |  |             self.reportState('stopped') | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-06 15:40:23 +01:00
										 |  |  |     def executeJumpToLocation(self, args): | 
					
						
							| 
									
										
										
										
											2015-03-05 10:41:16 +01:00
										 |  |  |         self.reportToken(args) | 
					
						
							| 
									
										
										
										
											2014-02-05 17:03:51 +01:00
										 |  |  |         frame = self.currentFrame() | 
					
						
							|  |  |  |         if not frame: | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |             self.reportResult(self.describeStatus('No frame available.'), args) | 
					
						
							| 
									
										
										
										
											2014-02-05 17:03:51 +01:00
										 |  |  |             return | 
					
						
							| 
									
										
										
										
											2014-02-06 15:40:23 +01:00
										 |  |  |         addr = args.get('address', 0) | 
					
						
							|  |  |  |         if addr: | 
					
						
							|  |  |  |             bp = self.target.BreakpointCreateByAddress(addr) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             bp = self.target.BreakpointCreateByLocation( | 
					
						
							|  |  |  |                         str(args['file']), int(args['line'])) | 
					
						
							| 
									
										
										
										
											2014-02-05 17:03:51 +01:00
										 |  |  |         if bp.GetNumLocations() == 0: | 
					
						
							|  |  |  |             self.target.BreakpointDelete(bp.GetID()) | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |             status = 'No target location found.' | 
					
						
							| 
									
										
										
										
											2015-02-27 15:01:29 +01:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |             loc = bp.GetLocationAtIndex(0) | 
					
						
							|  |  |  |             self.target.BreakpointDelete(bp.GetID()) | 
					
						
							|  |  |  |             res = frame.SetPC(loc.GetLoadAddress()) | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |             status = 'Jumped.' if res else 'Cannot jump.' | 
					
						
							| 
									
										
										
										
											2017-08-11 19:05:12 +02:00
										 |  |  |         self.report(self.describeLocation(frame)) | 
					
						
							|  |  |  |         self.reportResult(self.describeStatus(status), args) | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def breakList(self): | 
					
						
							|  |  |  |         result = lldb.SBCommandReturnObject() | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |         self.debugger.GetCommandInterpreter().HandleCommand('break list', result) | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  |         self.report('success="%d",output="%s",error="%s"' | 
					
						
							|  |  |  |             % (result.Succeeded(), result.GetOutput(), result.GetError())) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-24 10:14:11 +02:00
										 |  |  |     def activateFrame(self, args): | 
					
						
							| 
									
										
										
										
											2015-09-07 12:16:05 +02:00
										 |  |  |         self.reportToken(args) | 
					
						
							| 
									
										
										
										
											2014-02-03 13:47:26 +01:00
										 |  |  |         thread = args['thread'] | 
					
						
							| 
									
										
										
										
											2013-05-24 10:14:11 +02:00
										 |  |  |         self.currentThread().SetSelectedFrame(args['index']) | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |         self.reportResult('', args) | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-29 16:24:17 +02:00
										 |  |  |     def selectThread(self, args): | 
					
						
							| 
									
										
										
										
											2015-09-07 12:16:05 +02:00
										 |  |  |         self.reportToken(args) | 
					
						
							| 
									
										
										
										
											2013-05-29 16:24:17 +02:00
										 |  |  |         self.process.SetSelectedThreadByID(args['id']) | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |         self.reportResult('', args) | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |     def fetchFullBacktrace(self, _ = None): | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |         command = 'thread backtrace all' | 
					
						
							| 
									
										
										
										
											2014-03-11 16:40:07 +01:00
										 |  |  |         result = lldb.SBCommandReturnObject() | 
					
						
							|  |  |  |         self.debugger.GetCommandInterpreter().HandleCommand(command, result) | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |         self.reportResult(self.hexencode(result.GetOutput()), {}) | 
					
						
							| 
									
										
										
										
											2014-03-11 16:40:07 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-07 16:43:20 +02:00
										 |  |  |     def executeDebuggerCommand(self, args): | 
					
						
							| 
									
										
										
										
											2016-08-02 14:50:54 +02:00
										 |  |  |         self.debuggerCommandInProgress = True | 
					
						
							| 
									
										
										
										
											2015-09-07 12:16:05 +02:00
										 |  |  |         self.reportToken(args) | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  |         result = lldb.SBCommandReturnObject() | 
					
						
							| 
									
										
										
										
											2013-05-07 16:43:20 +02:00
										 |  |  |         command = args['command'] | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  |         self.debugger.GetCommandInterpreter().HandleCommand(command, result) | 
					
						
							|  |  |  |         success = result.Succeeded() | 
					
						
							| 
									
										
										
										
											2013-05-29 15:38:49 +02:00
										 |  |  |         output = result.GetOutput() | 
					
						
							|  |  |  |         error = str(result.GetError()) | 
					
						
							| 
									
										
										
										
											2013-04-30 10:46:48 +02:00
										 |  |  |         self.report('success="%d",output="%s",error="%s"' % (success, output, error)) | 
					
						
							| 
									
										
										
										
											2016-08-02 14:50:54 +02:00
										 |  |  |         self.debuggerCommandInProgress = False | 
					
						
							| 
									
										
										
										
											2013-04-10 13:55:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |     def fetchDisassembler(self, args): | 
					
						
							| 
									
										
										
										
											2014-03-06 12:04:47 +01:00
										 |  |  |         functionName = args.get('function', '') | 
					
						
							|  |  |  |         flavor = args.get('flavor', '') | 
					
						
							|  |  |  |         function = None | 
					
						
							|  |  |  |         if len(functionName): | 
					
						
							|  |  |  |             functions = self.target.FindFunctions(functionName).functions | 
					
						
							|  |  |  |             if len(functions): | 
					
						
							|  |  |  |                 function = functions[0] | 
					
						
							|  |  |  |         if function: | 
					
						
							|  |  |  |             base = function.GetStartAddress().GetLoadAddress(self.target) | 
					
						
							|  |  |  |             instructions = function.GetInstructions(self.target) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             base = args.get('address', 0) | 
					
						
							| 
									
										
										
										
											2015-02-04 17:21:55 +01:00
										 |  |  |             if int(base) == 0xffffffffffffffff: | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |                 warn('INVALID DISASSEMBLER BASE') | 
					
						
							| 
									
										
										
										
											2015-02-04 17:21:55 +01:00
										 |  |  |                 return | 
					
						
							| 
									
										
										
										
											2014-03-06 12:04:47 +01:00
										 |  |  |             addr = lldb.SBAddress(base, self.target) | 
					
						
							|  |  |  |             instructions = self.target.ReadInstructions(addr, 100) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-28 14:35:25 +02:00
										 |  |  |         currentFile = None | 
					
						
							|  |  |  |         currentLine = None | 
					
						
							|  |  |  |         hunks = dict() | 
					
						
							|  |  |  |         sources = dict() | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |         result = 'lines=[' | 
					
						
							| 
									
										
										
										
											2014-03-06 12:04:47 +01:00
										 |  |  |         for insn in instructions: | 
					
						
							| 
									
										
										
										
											2013-05-03 17:18:07 +02:00
										 |  |  |             comment = insn.GetComment(self.target) | 
					
						
							| 
									
										
										
										
											2015-08-28 14:35:25 +02:00
										 |  |  |             addr = insn.GetAddress() | 
					
						
							|  |  |  |             loadAddr = addr.GetLoadAddress(self.target) | 
					
						
							|  |  |  |             lineEntry = addr.GetLineEntry() | 
					
						
							|  |  |  |             if lineEntry: | 
					
						
							|  |  |  |                 lineNumber = lineEntry.GetLine() | 
					
						
							|  |  |  |                 fileName = str(lineEntry.GetFileSpec()) | 
					
						
							|  |  |  |                 if lineNumber != currentLine or fileName != currentFile: | 
					
						
							|  |  |  |                     currentLine = lineNumber | 
					
						
							|  |  |  |                     currentFile = fileName | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |                     key = '%s:%s' % (fileName, lineNumber) | 
					
						
							| 
									
										
										
										
											2015-08-28 14:35:25 +02:00
										 |  |  |                     hunk = hunks.get(key, 0) + 1 | 
					
						
							|  |  |  |                     hunks[key] = hunk | 
					
						
							|  |  |  |                     source = sources.get(fileName, None) | 
					
						
							|  |  |  |                     if source is None: | 
					
						
							| 
									
										
										
										
											2016-01-19 14:11:04 +01:00
										 |  |  |                         try: | 
					
						
							|  |  |  |                             with open(fileName, 'r') as f: | 
					
						
							|  |  |  |                                 source = f.read().splitlines() | 
					
						
							|  |  |  |                                 sources[fileName] = source | 
					
						
							|  |  |  |                         except IOError as error: | 
					
						
							|  |  |  |                             # With lldb-3.8 files like /data/dev/creator-3.6/tests/ | 
					
						
							|  |  |  |                             # auto/debugger/qt_tst_dumpers_StdVector_bfNWZa/main.cpp | 
					
						
							|  |  |  |                             # with non-existent directories appear. | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |                             warn('FILE: %s  ERROR: %s' % (fileName, error)) | 
					
						
							|  |  |  |                             source = '' | 
					
						
							| 
									
										
										
										
											2015-08-28 14:35:25 +02:00
										 |  |  |                     result += '{line="%s"' % lineNumber | 
					
						
							|  |  |  |                     result += ',file="%s"' % fileName | 
					
						
							|  |  |  |                     if 0 < lineNumber and lineNumber <= len(source): | 
					
						
							| 
									
										
										
										
											2017-08-11 18:02:49 +02:00
										 |  |  |                         result += ',hexdata="%s"' % self.hexencode(source[lineNumber - 1]) | 
					
						
							| 
									
										
										
										
											2015-08-28 14:35:25 +02:00
										 |  |  |                     result += ',hunk="%s"}' % hunk | 
					
						
							|  |  |  |             result += '{address="%s"' % loadAddr | 
					
						
							| 
									
										
										
										
											2015-08-28 15:43:19 +02:00
										 |  |  |             result += ',data="%s %s"' % (insn.GetMnemonic(self.target), | 
					
						
							| 
									
										
										
										
											2013-05-13 16:04:00 +02:00
										 |  |  |                 insn.GetOperands(self.target)) | 
					
						
							| 
									
										
										
										
											2015-08-28 15:43:19 +02:00
										 |  |  |             result += ',function="%s"' % functionName | 
					
						
							| 
									
										
										
										
											2016-12-13 09:46:51 +01:00
										 |  |  |             rawData = insn.GetData(self.target).uint8s | 
					
						
							| 
									
										
										
										
											2015-08-28 15:43:19 +02:00
										 |  |  |             result += ',rawdata="%s"' % ' '.join(["%02x" % x for x in rawData]) | 
					
						
							| 
									
										
										
										
											2013-05-03 17:18:07 +02:00
										 |  |  |             if comment: | 
					
						
							| 
									
										
										
										
											2016-04-13 19:37:31 +02:00
										 |  |  |                 result += ',comment="%s"' % self.hexencode(comment) | 
					
						
							| 
									
										
										
										
											2015-08-28 14:35:25 +02:00
										 |  |  |             result += ',offset="%s"}' % (loadAddr - base) | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |         self.reportResult(result + ']', args) | 
					
						
							| 
									
										
										
										
											2013-05-03 17:18:07 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-11 21:35:39 +02:00
										 |  |  |     def fetchMemory(self, args): | 
					
						
							| 
									
										
										
										
											2013-05-07 12:34:10 +02:00
										 |  |  |         address = args['address'] | 
					
						
							|  |  |  |         length = args['length'] | 
					
						
							| 
									
										
										
										
											2013-05-07 08:46:51 +02:00
										 |  |  |         error = lldb.SBError() | 
					
						
							|  |  |  |         contents = self.process.ReadMemory(address, length, error) | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |         result = 'address="%s",' % address | 
					
						
							| 
									
										
										
										
											2013-05-07 08:46:51 +02:00
										 |  |  |         result += self.describeError(error) | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |         result += ',contents="%s"' % self.hexencode(contents) | 
					
						
							|  |  |  |         self.reportResult(result, args) | 
					
						
							| 
									
										
										
										
											2013-05-07 08:46:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-11 18:55:09 +02:00
										 |  |  |     def findValueByExpression(self, exp): | 
					
						
							|  |  |  |         # FIXME: Top level-only for now. | 
					
						
							|  |  |  |         frame = self.currentFrame() | 
					
						
							|  |  |  |         value = frame.FindVariable(exp) | 
					
						
							|  |  |  |         return value | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-30 15:35:52 +02:00
										 |  |  |     def assignValue(self, args): | 
					
						
							| 
									
										
										
										
											2015-09-07 12:16:05 +02:00
										 |  |  |         self.reportToken(args) | 
					
						
							| 
									
										
										
										
											2013-06-11 18:55:09 +02:00
										 |  |  |         error = lldb.SBError() | 
					
						
							| 
									
										
										
										
											2014-01-23 15:30:51 +01:00
										 |  |  |         exp = self.hexdecode(args['exp']) | 
					
						
							|  |  |  |         value = self.hexdecode(args['value']) | 
					
						
							| 
									
										
										
										
											2013-06-11 18:55:09 +02:00
										 |  |  |         lhs = self.findValueByExpression(exp) | 
					
						
							|  |  |  |         lhs.SetValueFromCString(value, error) | 
					
						
							| 
									
										
										
										
											2015-10-09 15:00:20 +02:00
										 |  |  |         self.reportResult(self.describeError(error), args) | 
					
						
							| 
									
										
										
										
											2013-05-30 15:35:52 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-13 09:46:51 +01:00
										 |  |  |     def watchPoint(self, args): | 
					
						
							|  |  |  |         self.reportToken(args) | 
					
						
							|  |  |  |         ns = self.qtNamespace() | 
					
						
							|  |  |  |         lenns = len(ns) | 
					
						
							|  |  |  |         funcs = self.target.FindGlobalFunctions('.*QApplication::widgetAt', 2, 1) | 
					
						
							|  |  |  |         func = funcs[1] | 
					
						
							|  |  |  |         addr = func.GetFunction().GetStartAddress().GetLoadAddress(self.target) | 
					
						
							|  |  |  |         expr = '((void*(*)(int,int))0x%x)' % addr | 
					
						
							|  |  |  |         #expr = '%sQApplication::widgetAt(%s,%s)' % (ns, args['x'], args['y']) | 
					
						
							|  |  |  |         res = self.parseAndEvaluate(expr) | 
					
						
							|  |  |  |         p = 0 if res is None else res.pointer() | 
					
						
							|  |  |  |         n = ns + 'QWidget' | 
					
						
							|  |  |  |         self.reportResult('selected="0x%x",expr="(%s*)0x%x"' % (p, n, p), args) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-04 16:27:46 +01:00
										 |  |  |     def createResolvePendingBreakpointsHookBreakpoint(self, args): | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |         bp = self.target.BreakpointCreateByName('qt_qmlDebugConnectorOpen') | 
					
						
							| 
									
										
										
										
											2015-02-04 13:29:42 +01:00
										 |  |  |         bp.SetOneShot(True) | 
					
						
							| 
									
										
										
										
											2015-10-09 15:00:20 +02:00
										 |  |  |         self.interpreterBreakpointResolvers.append( | 
					
						
							| 
									
										
										
										
											2015-10-14 13:26:22 +02:00
										 |  |  |             lambda: self.resolvePendingInterpreterBreakpoint(args)) | 
					
						
							| 
									
										
										
										
											2013-10-17 17:08:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-29 14:55:57 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-04 10:44:20 +02:00
										 |  |  | # Used in dumper auto test. | 
					
						
							| 
									
										
										
										
											2015-01-23 17:54:00 +01:00
										 |  |  | class Tester(Dumper): | 
					
						
							| 
									
										
										
										
											2015-11-10 09:23:58 +01:00
										 |  |  |     def __init__(self, binary, args): | 
					
						
							| 
									
										
										
										
											2015-01-23 17:54:00 +01:00
										 |  |  |         Dumper.__init__(self) | 
					
						
							|  |  |  |         lldb.theDumper = self | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |         self.loadDumpers({'token': 1}) | 
					
						
							| 
									
										
										
										
											2015-01-23 17:54:00 +01:00
										 |  |  |         error = lldb.SBError() | 
					
						
							| 
									
										
										
										
											2015-01-30 12:36:04 +01:00
										 |  |  |         self.target = self.debugger.CreateTarget(binary, None, None, True, error) | 
					
						
							| 
									
										
										
										
											2013-06-04 10:44:20 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-23 17:54:00 +01:00
										 |  |  |         if error.GetType(): | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |             warn('ERROR: %s' % error) | 
					
						
							| 
									
										
										
										
											2015-01-23 17:54:00 +01:00
										 |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-10 09:23:58 +01:00
										 |  |  |         s = threading.Thread(target=self.testLoop, args=(args,)) | 
					
						
							| 
									
										
										
										
											2015-01-23 17:54:00 +01:00
										 |  |  |         s.start() | 
					
						
							| 
									
										
										
										
											2015-01-30 12:36:04 +01:00
										 |  |  |         s.join(30) | 
					
						
							| 
									
										
										
										
											2013-06-04 10:44:20 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-10 09:23:58 +01:00
										 |  |  |     def testLoop(self, args): | 
					
						
							| 
									
										
										
										
											2015-01-23 17:54:00 +01:00
										 |  |  |         # Disable intermediate reporting. | 
					
						
							|  |  |  |         savedReport = self.report | 
					
						
							|  |  |  |         self.report = lambda stuff: 0 | 
					
						
							| 
									
										
										
										
											2013-06-04 10:44:20 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-23 17:54:00 +01:00
										 |  |  |         error = lldb.SBError() | 
					
						
							|  |  |  |         launchInfo = lldb.SBLaunchInfo([]) | 
					
						
							|  |  |  |         launchInfo.SetWorkingDirectory(os.getcwd()) | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |         environmentList = [key + '=' + value for key,value in os.environ.items()] | 
					
						
							| 
									
										
										
										
											2015-01-23 17:54:00 +01:00
										 |  |  |         launchInfo.SetEnvironmentEntries(environmentList, False) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.process = self.target.Launch(launchInfo, error) | 
					
						
							|  |  |  |         if error.GetType(): | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |             warn('ERROR: %s' % error) | 
					
						
							| 
									
										
										
										
											2015-01-23 17:54:00 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         event = lldb.SBEvent() | 
					
						
							|  |  |  |         listener = self.debugger.GetListener() | 
					
						
							|  |  |  |         while True: | 
					
						
							|  |  |  |             state = self.process.GetState() | 
					
						
							|  |  |  |             if listener.WaitForEvent(100, event): | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |                 #warn('EVENT: %s' % event) | 
					
						
							| 
									
										
										
										
											2015-01-23 17:54:00 +01:00
										 |  |  |                 state = lldb.SBProcess.GetStateFromEvent(event) | 
					
						
							| 
									
										
										
										
											2015-01-27 10:25:21 +01:00
										 |  |  |                 if state == lldb.eStateExited: # 10 | 
					
						
							| 
									
										
										
										
											2015-01-23 17:54:00 +01:00
										 |  |  |                     break | 
					
						
							| 
									
										
										
										
											2015-01-27 10:25:21 +01:00
										 |  |  |                 if state == lldb.eStateStopped: # 5 | 
					
						
							| 
									
										
										
										
											2015-04-14 09:06:28 +02:00
										 |  |  |                     stoppedThread = None | 
					
						
							|  |  |  |                     for i in xrange(0, self.process.GetNumThreads()): | 
					
						
							|  |  |  |                         thread = self.process.GetThreadAtIndex(i) | 
					
						
							|  |  |  |                         reason = thread.GetStopReason() | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |                         #warn('THREAD: %s REASON: %s' % (thread, reason)) | 
					
						
							| 
									
										
										
										
											2015-04-14 09:06:28 +02:00
										 |  |  |                         if (reason == lldb.eStopReasonBreakpoint or | 
					
						
							|  |  |  |                                 reason == lldb.eStopReasonException or | 
					
						
							|  |  |  |                                 reason == lldb.eStopReasonSignal): | 
					
						
							|  |  |  |                             stoppedThread = thread | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     if stoppedThread: | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |                         # This seems highly fragile and depending on the 'No-ops' in the | 
					
						
							| 
									
										
										
										
											2015-04-14 09:06:28 +02:00
										 |  |  |                         # event handling above. | 
					
						
							| 
									
										
										
										
											2015-01-27 10:25:21 +01:00
										 |  |  |                         frame = stoppedThread.GetFrameAtIndex(0) | 
					
						
							| 
									
										
										
										
											2015-04-14 09:06:28 +02:00
										 |  |  |                         line = frame.line_entry.line | 
					
						
							|  |  |  |                         if line != 0: | 
					
						
							|  |  |  |                             self.report = savedReport | 
					
						
							|  |  |  |                             self.process.SetSelectedThread(stoppedThread) | 
					
						
							| 
									
										
										
										
											2015-11-10 09:23:58 +01:00
										 |  |  |                             self.fetchVariables(args) | 
					
						
							| 
									
										
										
										
											2015-09-09 16:34:09 +02:00
										 |  |  |                             #self.describeLocation(frame) | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |                             self.report('@NS@%s@' % self.qtNamespace()) | 
					
						
							|  |  |  |                             #self.report('ENV=%s' % os.environ.items()) | 
					
						
							|  |  |  |                             #self.report('DUMPER=%s' % self.qqDumpers) | 
					
						
							| 
									
										
										
										
											2015-04-14 09:06:28 +02:00
										 |  |  |                             break | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-23 17:54:00 +01:00
										 |  |  |             else: | 
					
						
							|  |  |  |                 warn('TIMEOUT') | 
					
						
							| 
									
										
										
										
											2016-10-25 15:32:13 +02:00
										 |  |  |                 warn('Cannot determined stopped thread') | 
					
						
							| 
									
										
										
										
											2014-01-17 16:13:03 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-23 17:54:00 +01:00
										 |  |  |         lldb.SBDebugger.Destroy(self.debugger) | 
					
						
							| 
									
										
										
										
											2017-05-13 15:19:56 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | # ------------------------------ For use in LLDB ------------------------------ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from pprint import pprint | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | __module__ = sys.modules[__name__] | 
					
						
							|  |  |  | DEBUG = False if not hasattr(__module__, 'DEBUG') else DEBUG | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class LogMixin: | 
					
						
							|  |  |  |     @staticmethod | 
					
						
							|  |  |  |     def log(message = '', log_caller = False, frame = 1, args = ''): | 
					
						
							|  |  |  |         if not DEBUG: | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  |         if log_caller: | 
					
						
							|  |  |  |             message = ": " + message if len(message) else '' | 
					
						
							|  |  |  |             # FIXME: Compute based on first frame not in this class? | 
					
						
							|  |  |  |             frame = sys._getframe(frame) | 
					
						
							|  |  |  |             fn = frame.f_code.co_name | 
					
						
							|  |  |  |             localz = frame.f_locals | 
					
						
							|  |  |  |             instance = str(localz["self"]) + "." if 'self' in localz else '' | 
					
						
							|  |  |  |             message = "%s%s(%s)%s" % (instance, fn, args, message) | 
					
						
							|  |  |  |         print message | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @staticmethod | 
					
						
							|  |  |  |     def log_fn(arg_str = ''): | 
					
						
							|  |  |  |         LogMixin.log(log_caller = True, frame = 2, args = arg_str) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class DummyDebugger(object): | 
					
						
							|  |  |  |     def __getattr__(self, attr): | 
					
						
							|  |  |  |         raise AttributeError("Debugger should not be needed to create summaries") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class SummaryDumper(Dumper, LogMixin): | 
					
						
							|  |  |  |     _instance = None | 
					
						
							|  |  |  |     _lock = threading.RLock() | 
					
						
							|  |  |  |     _type_caches = {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @staticmethod | 
					
						
							|  |  |  |     def initialize(): | 
					
						
							|  |  |  |         SummaryDumper._instance = SummaryDumper() | 
					
						
							|  |  |  |         return SummaryDumper._instance | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @staticmethod | 
					
						
							|  |  |  |     @contextmanager | 
					
						
							|  |  |  |     def shared(valobj): | 
					
						
							|  |  |  |         SummaryDumper._lock.acquire() | 
					
						
							|  |  |  |         dumper = SummaryDumper._instance | 
					
						
							|  |  |  |         dumper.target = valobj.target | 
					
						
							|  |  |  |         dumper.process = valobj.process | 
					
						
							|  |  |  |         debugger_id = dumper.target.debugger.GetID() | 
					
						
							|  |  |  |         dumper.typeCache = SummaryDumper._type_caches.get(debugger_id, {}) | 
					
						
							|  |  |  |         yield dumper | 
					
						
							|  |  |  |         SummaryDumper._type_caches[debugger_id] = dumper.typeCache | 
					
						
							|  |  |  |         SummaryDumper._lock.release() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @staticmethod | 
					
						
							|  |  |  |     def warn(message): | 
					
						
							|  |  |  |         print "Qt summary warning: %s" % message | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @staticmethod | 
					
						
							|  |  |  |     def showException(message, exType, exValue, exTraceback): | 
					
						
							|  |  |  |         # FIXME: Store for later and report back in summary | 
					
						
							|  |  |  |         SummaryDumper.log("Exception during dumping: %s" % exValue) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self): | 
					
						
							|  |  |  |         DumperBase.warn = staticmethod(SummaryDumper.warn) | 
					
						
							|  |  |  |         DumperBase.showException = staticmethod(SummaryDumper.showException) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Dumper.__init__(self, DummyDebugger()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.setVariableFetchingOptions({ | 
					
						
							|  |  |  |             'fancy' : True, | 
					
						
							|  |  |  |             'qobjectnames' : True, | 
					
						
							|  |  |  |             'passexceptions' : True | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.dumpermodules = ['qttypes'] | 
					
						
							|  |  |  |         self.loadDumpers({}) | 
					
						
							|  |  |  |         self.output = '' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def report(self, stuff): | 
					
						
							|  |  |  |         return # Don't mess up lldb output | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def dump_summary(self, valobj, expanded = False): | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             from pygdbmi import gdbmiparser | 
					
						
							|  |  |  |         except ImportError: | 
					
						
							|  |  |  |             print "Qt summary provider requires the pygdbmi module, " \ | 
					
						
							|  |  |  |                     "please install using 'sudo /usr/bin/easy_install pygdbmi', " \ | 
					
						
							|  |  |  |                     "and then restart Xcode." | 
					
						
							|  |  |  |             lldb.debugger.HandleCommand('type category delete Qt') | 
					
						
							|  |  |  |             return None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         value = self.fromNativeValue(valobj) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Expand variable if we need synthetic children | 
					
						
							|  |  |  |         oldExpanded = self.expandedINames | 
					
						
							|  |  |  |         self.expandedINames = [value.name] if expanded else [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         savedOutput = self.output | 
					
						
							|  |  |  |         self.output = '' | 
					
						
							|  |  |  |         with TopLevelItem(self, value.name): | 
					
						
							|  |  |  |             self.putItem(value) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # FIXME: Hook into putField, etc to build up object instead of parsing MI | 
					
						
							|  |  |  |         response = gdbmiparser.parse_response("^ok,summary=%s" % self.output) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.output = savedOutput | 
					
						
							|  |  |  |         self.expandedINames = oldExpanded | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         summary = response["payload"]["summary"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         #print value, " --> ", | 
					
						
							|  |  |  |         #pprint(summary) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return summary | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class SummaryProvider(LogMixin): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     DEFAULT_SUMMARY = '' | 
					
						
							|  |  |  |     VOID_PTR_TYPE = None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @staticmethod | 
					
						
							|  |  |  |     def provide_summary(valobj, internal_dict, options = None): | 
					
						
							|  |  |  |         if not __name__ in internal_dict: | 
					
						
							|  |  |  |             # When disabling the import of the Qt summary providers, the | 
					
						
							|  |  |  |             # summary functions are still registered with LLDB, and we will | 
					
						
							|  |  |  |             # get callbacks to provide summaries, but at this point the child | 
					
						
							|  |  |  |             # providers are not active, so instead of providing half-baked and | 
					
						
							|  |  |  |             # confusing summaries we opt to unload all the summaries. | 
					
						
							|  |  |  |             SummaryDumper.log("Module '%s' was unloaded, removing Qt category" % __name__) | 
					
						
							|  |  |  |             lldb.debugger.HandleCommand('type category delete Qt') | 
					
						
							|  |  |  |             return SummaryProvider.DEFAULT_SUMMARY | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # FIXME: It would be nice to cache the providers, so that if a | 
					
						
							|  |  |  |         # synthetic child provider has already been created for a valobj, | 
					
						
							|  |  |  |         # we can re-use that when providing summary for the synthetic child | 
					
						
							|  |  |  |         # parent, but we lack a consistent cache key for that to work. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         provider = SummaryProvider(valobj) | 
					
						
							|  |  |  |         provider.update() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return provider.get_summary(options) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self, valobj, expand = False): | 
					
						
							|  |  |  |         # Prevent recursive evaluation during logging, etc | 
					
						
							|  |  |  |         valobj.SetPreferSyntheticValue(False) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.log_fn(valobj.path) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.valobj = valobj | 
					
						
							|  |  |  |         self.expand = expand | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if not SummaryProvider.VOID_PTR_TYPE: | 
					
						
							|  |  |  |             with SummaryDumper.shared(self.valobj) as dumper: | 
					
						
							|  |  |  |                 SummaryProvider.VOID_PTR_TYPE = dumper.lookupNativeType('void*') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __repr__(self): | 
					
						
							|  |  |  |         return "%s(%s)" % (self.__class__.__name__, repr(self.key())) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def key(self): | 
					
						
							|  |  |  |         if not hasattr(self, 'valobj'): | 
					
						
							|  |  |  |             return None | 
					
						
							|  |  |  |         return self.valobj.path | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def update(self): | 
					
						
							|  |  |  |         self.log_fn() | 
					
						
							|  |  |  |         with SummaryDumper.shared(self.valobj) as dumper: | 
					
						
							|  |  |  |             self.summary = dumper.dump_summary(self.valobj, self.expand) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def get_summary(self, options): | 
					
						
							|  |  |  |         self.log_fn() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         summary = self.summary | 
					
						
							|  |  |  |         if not summary: | 
					
						
							|  |  |  |             return '<error: could not get summary from Qt provider>' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         encoding = summary.get("valueencoded") | 
					
						
							|  |  |  |         summaryValue = summary["value"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # FIXME: Share between Creator and LLDB in the python code | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if encoding: | 
					
						
							|  |  |  |             special_encodings = { | 
					
						
							|  |  |  |                 "empty"             : "<empty>", | 
					
						
							|  |  |  |                 "minimumitemcount"  : "<at least %s items>" % summaryValue, | 
					
						
							|  |  |  |                 "undefined"         : "<undefined>", | 
					
						
							|  |  |  |                 "null"              : "<null>", | 
					
						
							|  |  |  |                 "itemcount"         : "<%s items>" % summaryValue, | 
					
						
							|  |  |  |                 "notaccessible"     : "<not accessible>", | 
					
						
							|  |  |  |                 "optimizedout"      : "<optimized out>", | 
					
						
							|  |  |  |                 "nullreference"     : "<null reference>", | 
					
						
							|  |  |  |                 "emptystructure"    : "<empty structure>", | 
					
						
							|  |  |  |                 "uninitialized"     : "<uninitialized>", | 
					
						
							|  |  |  |                 "invalid"           : "<invalid>", | 
					
						
							|  |  |  |                 "notcallable"       : "<not callable>", | 
					
						
							|  |  |  |                 "outofscope"        : "<out of scope>" | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             if encoding in special_encodings: | 
					
						
							|  |  |  |                 return special_encodings[encoding] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             text_encodings = [ | 
					
						
							|  |  |  |                 'latin1', | 
					
						
							|  |  |  |                # 'local8bit', | 
					
						
							|  |  |  |                 'utf8', | 
					
						
							|  |  |  |                 'utf16', | 
					
						
							|  |  |  |               #  'ucs4' | 
					
						
							|  |  |  |             ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if encoding in text_encodings: | 
					
						
							|  |  |  |                 try: | 
					
						
							|  |  |  |                     binaryvalue = summaryValue.decode('hex') | 
					
						
							|  |  |  |                     # LLDB expects UTF-8 | 
					
						
							|  |  |  |                     return "\"%s\"" % (binaryvalue.decode(encoding).encode('utf8')) | 
					
						
							|  |  |  |                 except: | 
					
						
							|  |  |  |                     return "<failed to decode '%s' as '%s'>" % (summaryValue, encoding) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # FIXME: Support these | 
					
						
							|  |  |  |             other_encodings = ['int', 'uint', 'float', 'juliandate', 'juliandateandmillisecondssincemidnight', | 
					
						
							|  |  |  |                 'millisecondssincemidnight', 'ipv6addressandhexscopeid', 'datetimeinternal'] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             summaryValue += " <encoding='%s'>" % encoding | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if self.valobj.value: | 
					
						
							|  |  |  |             # If we've resolved a pointer that matches what LLDB natively chose, | 
					
						
							|  |  |  |             # then use that instead of printing the values twice. FIXME, ideally | 
					
						
							|  |  |  |             # we'd have the same pointer format as LLDB uses natively. | 
					
						
							|  |  |  |             if re.sub('^0x0*', '', self.valobj.value) == re.sub('^0x0*', '', summaryValue): | 
					
						
							|  |  |  |                 return SummaryProvider.DEFAULT_SUMMARY | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return summaryValue.strip() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class SyntheticChildrenProvider(SummaryProvider): | 
					
						
							|  |  |  |     def __init__(self, valobj, dict): | 
					
						
							|  |  |  |         SummaryProvider.__init__(self, valobj, expand = True) | 
					
						
							|  |  |  |         self.summary = None | 
					
						
							|  |  |  |         self.synthetic_children = [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def num_native_children(self): | 
					
						
							|  |  |  |         return self.valobj.GetNumChildren() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def num_children(self): | 
					
						
							|  |  |  |         self.log("native: %d synthetic: %d" % | 
					
						
							|  |  |  |                 (self.num_native_children(), len(self.synthetic_children)), True) | 
					
						
							|  |  |  |         return self._num_children() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _num_children(self): | 
					
						
							|  |  |  |         return self.num_native_children() + len(self.synthetic_children) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def has_children(self): | 
					
						
							|  |  |  |         return self._num_children() > 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def get_child_index(self, name): | 
					
						
							|  |  |  |         # FIXME: Do we ever need this to return something? | 
					
						
							|  |  |  |         self.log_fn(name) | 
					
						
							|  |  |  |         return None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def get_child_at_index(self, index): | 
					
						
							|  |  |  |         self.log_fn(index) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if index < 0 or index > self._num_children(): | 
					
						
							|  |  |  |             return None | 
					
						
							|  |  |  |         if not self.valobj.IsValid() or not self.summary: | 
					
						
							|  |  |  |             return None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if index < self.num_native_children(): | 
					
						
							|  |  |  |             # Built-in children | 
					
						
							|  |  |  |             value = self.valobj.GetChildAtIndex(index) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             # Synthetic children | 
					
						
							|  |  |  |             index -= self.num_native_children() | 
					
						
							|  |  |  |             child = self.synthetic_children[index] | 
					
						
							|  |  |  |             name = child.get('name', "[%s]" % index) | 
					
						
							|  |  |  |             value = self.create_value(child, name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return value | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def create_value(self, child, name = ''): | 
					
						
							|  |  |  |         child_type = child.get('type', self.summary.get('childtype')) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         value = None | 
					
						
							|  |  |  |         if child_type: | 
					
						
							|  |  |  |             if 'address' in child: | 
					
						
							|  |  |  |                 value_type = None | 
					
						
							|  |  |  |                 with SummaryDumper.shared(self.valobj) as dumper: | 
					
						
							|  |  |  |                     value_type = dumper.lookupNativeType(child_type) | 
					
						
							|  |  |  |                 if not value_type or not value_type.IsValid(): | 
					
						
							|  |  |  |                     return None | 
					
						
							|  |  |  |                 address = int(child['address'], 16) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 # Create as void* so that the value is fully initialized before | 
					
						
							|  |  |  |                 # we trigger our own summary/child providers recursively. | 
					
						
							|  |  |  |                 value = self.valobj.synthetic_child_from_address(name, address, | 
					
						
							|  |  |  |                     SummaryProvider.VOID_PTR_TYPE).Cast(value_type) | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 self.log("Don't know how to create value for child %s" % child) | 
					
						
							|  |  |  |                 # FIXME: Figure out if we ever will hit this case, and deal with it | 
					
						
							|  |  |  |                 #value = self.valobj.synthetic_child_from_expression(name, | 
					
						
							|  |  |  |                 #    "(%s)(%s)" % (child_type, child['value'])) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             # FIXME: Find a good way to deal with synthetic values | 
					
						
							|  |  |  |             self.log("Don't know how to create value for child %s" % child) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # FIXME: Handle value type or value errors consistently | 
					
						
							|  |  |  |         return value | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def update(self): | 
					
						
							|  |  |  |         SummaryProvider.update(self) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.synthetic_children = [] | 
					
						
							|  |  |  |         if not 'children' in self.summary: | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         dereference_child = None | 
					
						
							|  |  |  |         for child in self.summary['children']: | 
					
						
							|  |  |  |             if not child or not type(child) is dict: | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # Skip base classes, they are built-in children | 
					
						
							|  |  |  |             # FIXME: Is there a better check than 'iname'? | 
					
						
							|  |  |  |             if 'iname' in child: | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             name = child.get('name') | 
					
						
							|  |  |  |             if name: | 
					
						
							|  |  |  |                 if name == '*': | 
					
						
							|  |  |  |                     # No use for this unless the built in children failed to resolve | 
					
						
							|  |  |  |                     dereference_child = child | 
					
						
							|  |  |  |                     continue | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if name.startswith('['): | 
					
						
							|  |  |  |                     # Skip pure synthetic children until we can deal with them | 
					
						
							|  |  |  |                     continue | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if name.startswith('#'): | 
					
						
							|  |  |  |                     # Skip anonymous unions, lookupNativeType doesn't handle them (yet), | 
					
						
							|  |  |  |                     # so it triggers the slow lookup path, and the union is provided as | 
					
						
							|  |  |  |                     # a native child anyways. | 
					
						
							|  |  |  |                     continue | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 # Skip native children | 
					
						
							|  |  |  |                 if self.valobj.GetChildMemberWithName(name): | 
					
						
							|  |  |  |                     continue | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             self.synthetic_children.append(child) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Xcode will sometimes fail to show the children of pointers in | 
					
						
							|  |  |  |         # the debugger UI, even if dereferencing the pointer works fine. | 
					
						
							|  |  |  |         # We fall back to the special child reported by the Qt dumper. | 
					
						
							|  |  |  |         if not self.valobj.GetNumChildren() and dereference_child: | 
					
						
							|  |  |  |            self.valobj = self.create_value(dereference_child) | 
					
						
							|  |  |  |            self.update() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def __lldb_init_module(debugger, internal_dict): | 
					
						
							|  |  |  |     # Module is being imported in an LLDB session | 
					
						
							|  |  |  |     dumper = SummaryDumper.initialize() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     type_category = 'Qt' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Concrete types | 
					
						
							|  |  |  |     summary_function = "%s.%s.%s" % (__name__, 'SummaryProvider', 'provide_summary') | 
					
						
							|  |  |  |     types = map(lambda x: x.replace('__', '::'), dumper.qqDumpers) | 
					
						
							|  |  |  |     debugger.HandleCommand("type summary add -F %s -w %s %s" \ | 
					
						
							|  |  |  |         % (summary_function, type_category, ' '.join(types))) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     regex_types = map(lambda x: "'" + x + "'", dumper.qqDumpersEx.keys()) | 
					
						
							|  |  |  |     if regex_types: | 
					
						
							|  |  |  |         debugger.HandleCommand("type summary add -x -F %s -w %s %s" \ | 
					
						
							|  |  |  |             % (summary_function, type_category, ' '.join(regex_types))) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Global catch-all for Qt classes | 
					
						
							|  |  |  |     debugger.HandleCommand("type summary add -x '^Q.*$' -F %s -w %s" \ | 
					
						
							|  |  |  |         % (summary_function, type_category)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Named summary ('frame variable foo --summary Qt') | 
					
						
							|  |  |  |     debugger.HandleCommand("type summary add --name Qt -F %s -w %s" \ | 
					
						
							|  |  |  |         % (summary_function, type_category)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Synthetic children | 
					
						
							|  |  |  |     debugger.HandleCommand("type synthetic add -x '^Q.*$' -l %s -w %s" \ | 
					
						
							|  |  |  |         % (SyntheticChildrenProvider, type_category)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     debugger.HandleCommand('type category enable %s' % type_category) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if not __name__ == 'qt': | 
					
						
							|  |  |  |         # Make available under global 'qt' name for consistency | 
					
						
							|  |  |  |         internal_dict['qt'] = internal_dict[__name__] |