1# Licensed to the Apache Software Foundation (ASF) under one 2# or more contributor license agreements. See the NOTICE file 3# distributed with this work for additional information 4# regarding copyright ownership. The ASF licenses this file 5# to you under the Apache License, Version 2.0 (the 6# "License"); you may not use this file except in compliance 7# with the License. You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, 12# software distributed under the License is distributed on an 13# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14# KIND, either express or implied. See the License for the 15# specific language governing permissions and limitations 16# under the License. 17 18# to activate the AOO-LLDB helper script type the line below into LLDB 19# command script import path-to-script/lldb4aoo.py 20# or activate it automatically by adding the line to ~/.lldbinit 21 22def __lldb_init_module( dbg, dict): 23 # the list of AOO specific types 24 aoo_types = ['rtl_String', 'rtl_uString', '_ByteStringData', '_UniStringData'] 25 pimpl_types = ['rtl::OString', 'rtl::OUString', 'ByteString', 'UniString'] 26 # register a helper function for each non-trivial type 27 for t in aoo_types: 28 f = 'getinfo_for_' + t.replace( '::', '_') 29 if f in globals(): 30 dbg.HandleCommand( 'type summary add %s -v -C yes -F %s.%s' % (t,__name__,f)) 31 else: 32 print( 'AOO-LLDB helper function "%s" is not yet defined: ' 33 '"%s" types cannot be displayed properly!' % (f,t)) 34 # register a generic helper function for pimpl types 35 dbg.HandleCommand( 'type summary add -F %s.%s -v -C yes -n PIMPL %s' % ( __name__,'get_pimpl_info', ' '.join(pimpl_types))) 36 37 # add info about specific helper methods 38 # assume functions with docstrings are available for general consumption 39 helper_funcs = [v for (k,v) in globals().iteritems() if( not k.startswith('_') and callable(v) and v.__doc__)] 40 if helper_funcs: 41 print( 'Available AOO-specific helper functions:') 42 for hfunc in helper_funcs: 43 shortdesc = hfunc.__doc__.splitlines()[0] 44 print( '\t%s\t# "%s"' %(hfunc.__name__, shortdesc)) 45 print( 'Run them with:') 46 for hfunc in helper_funcs[:4]: 47 print( '\tscript %s.%s()' %(__name__, hfunc.__name__)) 48 49# some helpers for use from interactive LLDB sessions 50 51import lldb 52 53def add_breakpoints(): 54 'Setup breakpoints useful for AOO debugging' 55 dbg = lldb.debugger 56 if dbg.GetNumTargets() == 0: 57 return 58 # the list of interesting function breakpoints 59 aoo_breakfn = ['main', '__cxa_call_unexpected', 'objc_exception_throw'] 60 aoo_breakfn += ['__cxa_throw'] 61 # register breakpoints for function basenames 62 for b in aoo_breakfn: 63 dbg.HandleCommand( 'breakpoint set -b ' + b) 64 65 66# local functions for use by the AOO-type summary providers 67 68def walk_ptrchain( v): 69 info = '' 70 while v.TypeIsPointerType(): 71 n = v.GetValueAsUnsigned() 72 if n == 0: 73 info += 'NULL' 74 return (None, info) 75 info += '0x%04X-> ' % (n) 76 v = v.Dereference() 77 return (v, info) 78 79def ret_strdata_info( v, refvar, lenvar, aryvar): 80 (v, info) = walk_ptrchain( v) 81 if not v: 82 return info 83 r = v.GetChildMemberWithName( refvar).GetValueAsSigned() 84 l = v.GetChildMemberWithName( lenvar).GetValueAsSigned() 85 c = v.GetChildMemberWithName( aryvar) 86 if (r < 0) or (l < 0): 87 info += 'CORRUPT_STR={refs=%d, len=%d}' % (r,l) 88 return info 89 L = min(l,128) 90 d = c.AddressOf().GetPointeeData( 0, L) 91 if c.GetByteSize() == 1: # assume UTF-8 92 s = ''.join([chr(x) for x in d.uint8s]) 93 else: # assume UTF-16 94 s = (u''.join([unichr(x) for x in d.uint16s])).encode('utf-8') 95 info += ('{refs=%d, len=%d, str="%s"%s}' % (r, l, s.encode('string_escape'), '...'if(l!=L)else'')) 96 return info 97 98# definitions for our individual LLDB type summary providers 99 100def get_pimpl_info( valobj, dict): 101 (v, info) = walk_ptrchain( valobj) 102 p = v.GetChildAtIndex(0) 103 pname = p.GetName() 104 n = p.GetValueAsUnsigned() 105 if n == 0: 106 return '%s(%s==NULL)' % (info, pname) 107 info = '%s(%s=0x%04X)-> ' % (info, pname, n) 108 return info + p.Dereference().GetSummary() 109 110 111def getinfo_for_rtl_String( valobj, dict): 112 return ret_strdata_info( valobj, 'refCount', 'length', 'buffer') 113 114def getinfo_for_rtl_uString( valobj, dict): 115 return ret_strdata_info( valobj, 'refCount', 'length', 'buffer') 116 117def getinfo_for__ByteStringData( valobj, dict): 118 return ret_strdata_info( valobj, 'mnRefCount', 'mnLen', 'maStr') 119 120def getinfo_for__UniStringData( valobj, dict): 121 return ret_strdata_info( valobj, 'mnRefCount', 'mnLen', 'maStr') 122 123