xref: /AOO41X/main/solenv/inc/lldb4aoo.py (revision 84d1acfe0b73a4c41f0e8c9a0027753dd141a1b6)
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