]> git.saurik.com Git - apple/xnu.git/blame - lldbmacros.py
xnu-2050.22.13.tar.gz
[apple/xnu.git] / lldbmacros.py
CommitLineData
316670eb
A
1import lldb
2import re
3import getopt
4
5# Note: This module will eventually contain loads of macros. So please bear with the Macro/EndMacro comments
6
7
8# Global functions
9def findGlobal(variable):
10 return lldb.target.FindGlobalVariables(variable, 0).GetValueAtIndex(0)
11
12def findGlobalValue(variable):
13 return findGlobal(variable).GetValue()
14
15def readMemberUnsigned(variable,member):
16 return variable.GetChildMemberWithName(member).GetValueAsUnsigned(0)
17
18def readMemberSigned(variable,member):
19 return variable.GetChildMemberWithName(member).GetValueAsSigned()
20
21def readMemberString(variable,member):
22 return str(variable.GetChildMemberWithName(member).GetSummary()).strip('"')
23
24
25
26class Output :
27 """
28 An output handler for all command. Use Output.print to direct all output of macro via the handler.
29 Currently this provide capabilities
30 -o path/to/filename
31 The output of this command execution will be saved to file. Parser information or errors will
32 not be sent to file though. eg /tmp/output.txt
33 -s filter_string
34 the "filter_string" param is parsed to python regex expression and each line of output
35 will be printed/saved only if it matches the expression.
36 The command header will not be filtered in any case.
37 """
38 STDOUT =1
39 FILEOUT =2
40 FILTER =False
41
42 def __init__(self):
43 self.out = Output.STDOUT
44 self.fname=None
45 self.fhandle=None
46 self.FILTER=False
47
48 def printString(self, s):
49 """ Handler for all commands output. By default just print to stdout """
50 if self.FILTER and not self.reg.search(s): return
51 if self.out == Output.STDOUT: print s
52 elif self.out == Output.FILEOUT : self.fhandle.write(s+"\n")
53
54 def printHeader(self,s):
55 if self.out == Output.STDOUT: print s
56 elif self.out == Output.FILEOUT: self.fhandle.write(s+"\n")
57
58 def done(self):
59 """ closes any open files. report on any errors """
60 if self.fhandle != None :
61 self.fhandle.close()
62
63 def setOptions(self,args):
64 """ parse the arguments passed to the command
65 param : args => [] of <str> (typically args.split())
66 """
67 opts=()
68 try:
69 opts,args = getopt.getopt(args,'o:s:',[])
70 except getopt.GetoptError,err:
71 print str(err)
72 #continue with processing
73 for o,a in opts :
74 if o == "-o" and len(a) > 0:
75 self.fname=a.strip()
76 self.fhandle=open(self.fname,"w")
77 self.out = Output.FILEOUT
78 print "saving results in file ",str(a)
79 elif o == "-s" and len(a) > 0:
80 self.reg = re.compile(a.strip(),re.MULTILINE|re.DOTALL)
81 self.FILTER=True
82 print "showing results for regex:",a.strip()
83 else :
84 print "Error: unknown option ",o,a
85
86
87# Inteface function for showallkexts command
88def showallkexts_command(debugger, args, result, lldb_dict):
89 kext_summary_header = findGlobal("gLoadedKextSummaries")
90 result.Printf(_summarizeallkexts(kext_summary_header))
91 return None
92
93# Interface function for loaded kext summary formatter
94def showallkexts_summary(kext_summary_header, lldb_dict):
95 return "\n" + _summarizeallkexts(kext_summary_header)
96
97# Internal function for walking kext summaries
98def _summarizeallkexts(kext_summary_header):
99 summary = "ID Address Size Version Name\n"
100 summaries = kext_summary_header.GetChildMemberWithName("summaries")
101 count = int(kext_summary_header.GetChildMemberWithName("numSummaries").GetValue())
102 for i in range(0, count):
103 summary += summaries.GetChildAtIndex(i, lldb.eNoDynamicValues, True).GetSummary() + "\n"
104 return summary
105
106# Macro: memstats
107def memstats_command(debugger,args,result,lldb_dict):
108 stream = Output()
109 stream.setOptions(args.split())
110 memstats(stream)
111 stream.done()
112
113def memstats(ostream):
114 ostream.printString ( "kern_memorystatus_level: {0}".format(findGlobalValue("kern_memorystatus_level")) )
115 ostream.printString ( "vm_page_throttled_count: {0}".format(findGlobalValue("vm_page_throttled_count")) )
116 ostream.printString ( "vm_page_active_count: {0}".format(findGlobalValue("vm_page_active_count")) )
117 ostream.printString ( "vm_page_inactive_count: {0}".format(findGlobalValue("vm_page_inactive_count")) )
118 ostream.printString ( "vm_page_wire_count: {0}".format(findGlobalValue("vm_page_wire_count")) )
119 ostream.printString ( "vm_page_free_count: {0}".format(findGlobalValue("vm_page_free_count")) )
120 ostream.printString ( "vm_page_purgeable_count: {0}".format(findGlobalValue("vm_page_purgeable_count")) )
121 ostream.printString ( "vm_page_inactive_target: {0}".format(findGlobalValue("vm_page_inactive_target")) )
122 ostream.printString ( "vm_page_free_target: {0}".format(findGlobalValue("vm_page_free_target")) )
123 ostream.printString ( "insue_ptepages_count: {0}".format(findGlobalValue("inuse_ptepages_count")) )
124 ostream.printString ( "vm_page_free_reserved: {0}".format(findGlobalValue("vm_page_free_reserved")) )
125# EndMacro: memstats
126
127
128# Macro: zprint
129def zprint_command(debugger,args,result,lldb_dict):
130 stream = Output()
131 stream.setOptions(args.split())
132 _zprint(stream)
133 stream.done()
134
135def _zprint(ostream):
136 """Display info about memory zones"""
137 ostream.printHeader ( "{0: ^20s} {1: >5s} {2: >12s} {3: >12s} {4: >7s} {5: >8s} {6: >9s} {7: >8s} {8: <20s} {9} ".format('ZONE', 'COUNT', 'TOT_SZ', 'MAX_SZ', 'ELT_SZ', 'ALLOC_SZ', 'TOT_ALLOC', 'TOT_FREE', 'NAME','') )
138 format_string = '{0: >#020x} {1: >5d} {2: >12d} {3: >12d} {4: >7d} {5: >8d} {6: >9d} {7: >8d} {8: <20s} {9}'
139 zone_ptr = findGlobal("first_zone");
140
141 while zone_ptr.GetValueAsUnsigned() != 0 :
142 addr = zone_ptr.GetValueAsUnsigned()
143 count = readMemberUnsigned(zone_ptr, "count")
144 cur_size = readMemberUnsigned(zone_ptr, "cur_size")
145 max_size = readMemberUnsigned(zone_ptr, "max_size")
146 elem_size = readMemberUnsigned(zone_ptr, "elem_size")
147 alloc_size = readMemberUnsigned(zone_ptr, "alloc_size")
148 num_allocs = readMemberUnsigned(zone_ptr, "num_allocs")
149 num_frees = readMemberUnsigned(zone_ptr, "num_frees")
150 name = str(readMemberString(zone_ptr, "zone_name"))
151 markings=""
152 if str(zone_ptr.GetChildMemberWithName("exhaustible").GetValue()) == '1' : markings+="H"
153 if str(zone_ptr.GetChildMemberWithName("collectable").GetValue()) == '1' : markings+="C"
154 if str(zone_ptr.GetChildMemberWithName("expandable").GetValue()) == '1' : markings+="X"
155 if str(zone_ptr.GetChildMemberWithName("noencrypt").GetValue()) == '1' : markings+="$"
156
157 ostream.printString(format_string.format(addr, count, cur_size, max_size, elem_size, alloc_size, num_allocs, num_frees, name, markings))
158
159 zone_ptr = zone_ptr.GetChildMemberWithName("next_zone")
160 return None
161# EndMacro: zprint
162
163
164# Macro: showioalloc
165def showioalloc_command(debugger,args,result,lldb_dict):
166 stream = Output()
167 stream.setOptions(args.split())
168 _showioalloc(stream)
169 stream.done()
170
171def _showioalloc(ostream):
172 ivars_size = findGlobal("debug_ivars_size").GetValueAsUnsigned()
173 container_malloc_size = findGlobal("debug_container_malloc_size").GetValueAsUnsigned()
174 iomalloc_size = findGlobal("debug_iomalloc_size").GetValueAsUnsigned()
175 iomallocpageable_size = findGlobal("debug_iomallocpageable_size").GetValueAsUnsigned()
176
177 ostream.printString("Instance allocation = {0:#0x} = {1:d} K".format(ivars_size, (int)(ivars_size/1024)))
178 ostream.printString("Container allocation = {0:#0x} = {1:d} K".format(container_malloc_size,(int)(container_malloc_size/1024)))
179 ostream.printString("IOMalloc allocation = {0:#0x} = {1:d} K".format(iomalloc_size,(int)(iomalloc_size/1024)))
180 ostream.printString("Pageable allocation = {0:#0x} = {1:d} K".format(iomallocpageable_size,(int)(iomallocpageable_size/1024)))
181 return None
182# EndMacro: showioalloc
183
184