15 cgitb
.enable(format
='text')
18 'KCDATA_TYPE_INVALID': 0x0,
19 'KCDATA_TYPE_STRING_DESC': 0x1,
20 'KCDATA_TYPE_UINT32_DESC': 0x2,
21 'KCDATA_TYPE_UINT64_DESC': 0x3,
22 'KCDATA_TYPE_INT32_DESC': 0x4,
23 'KCDATA_TYPE_INT64_DESC': 0x5,
24 'KCDATA_TYPE_BINDATA_DESC': 0x6,
25 'KCDATA_TYPE_ARRAY': 0x11,
26 'KCDATA_TYPE_TYPEDEFINTION': 0x12,
27 'KCDATA_TYPE_CONTAINER_BEGIN': 0x13,
28 'KCDATA_TYPE_CONTIANER_END': 0x14,
29 'KCDATA_TYPE_LIBRARY_LOADINFO': 0x30,
30 'KCDATA_TYPE_LIBRARY_LOADINFO64': 0x31,
31 'KCDATA_TYPE_TIMEBASE': 0x32,
32 #'KCDATA_TYPE_MACH_ABSOLUTE_TIME': 0x33,
33 'KCDATA_TYPE_TIMEVAL': 0x34,
34 'KCDATA_TYPE_USECS_SINCE_EPOCH': 0x35,
35 'STACKSHOT_KCCONTAINER_TASK': 0x903,
36 'STACKSHOT_KCCONTAINER_THREAD': 0x904,
37 'STACKSHOT_KCTYPE_KERN_STACKFRAME': 0x90A,
38 'STACKSHOT_KCTYPE_KERN_STACKFRAME64': 0x90B,
39 'STACKSHOT_KCTYPE_USER_STACKFRAME': 0x90C,
40 'STACKSHOT_KCTYPE_USER_STACKFRAME64': 0x90D,
41 'STACKSHOT_KCTYPE_BOOTARGS': 0x90E,
42 'STACKSHOT_KCTYPE_OSVERSION': 0x90F,
43 'STACKSHOT_KCTYPE_KERN_PAGE_SIZE': 0x910,
44 'STACKSHOT_KCTYPE_JETSAM_LEVEL': 0x911,
45 'KCDATA_TYPE_BUFFER_END': 0xF19158ED,
48 'TASK_CRASHINFO_EXTMODINFO': 0x801,
49 'TASK_CRASHINFO_BSDINFOWITHUNIQID': 0x802,
50 'TASK_CRASHINFO_TASKDYLD_INFO': 0x803,
51 'TASK_CRASHINFO_UUID': 0x804,
52 'TASK_CRASHINFO_PID': 0x805,
53 'TASK_CRASHINFO_PPID': 0x806,
54 'TASK_CRASHINFO_RUSAGE': 0x807,
55 'TASK_CRASHINFO_RUSAGE_INFO': 0x808,
56 'TASK_CRASHINFO_PROC_NAME': 0x809,
57 'TASK_CRASHINFO_PROC_STARTTIME': 0x80B,
58 'TASK_CRASHINFO_USERSTACK': 0x80C,
59 'TASK_CRASHINFO_ARGSLEN': 0x80D,
60 'TASK_CRASHINFO_EXCEPTION_CODES': 0x80E,
61 'TASK_CRASHINFO_PROC_PATH': 0x80F,
62 'TASK_CRASHINFO_PROC_CSFLAGS': 0x810,
63 'TASK_CRASHINFO_PROC_STATUS': 0x811,
64 'TASK_CRASHINFO_UID': 0x812,
65 'TASK_CRASHINFO_GID': 0x813,
66 'TASK_CRASHINFO_PROC_ARGC': 0x814,
67 'TASK_CRASHINFO_PROC_FLAGS': 0x815,
68 'TASK_CRASHINFO_CPUTYPE': 0x816,
69 'TASK_CRASHINFO_WORKQUEUEINFO': 0x817,
70 'TASK_CRASHINFO_RESPONSIBLE_PID': 0x818,
71 'TASK_CRASHINFO_DIRTY_FLAGS': 0x819,
72 'TASK_CRASHINFO_CRASHED_THREADID': 0x81A,
74 'KCDATA_BUFFER_BEGIN_CRASHINFO': 0xDEADF157,
75 'KCDATA_BUFFER_BEGIN_STACKSHOT': 0x59a25807
77 kcdata_type_def_rev
= dict((v
, k
) for k
, v
in kcdata_type_def
.iteritems())
79 KNOWN_TYPES_COLLECTION
= {}
83 return type('enum', (), args
)
85 KCSUBTYPE_TYPE
= enum(KC_ST_CHAR
=1, KC_ST_INT8
=2, KC_ST_UINT8
=3, KC_ST_INT16
=4, KC_ST_UINT16
=5, KC_ST_INT32
=6, KC_ST_UINT32
=7, KC_ST_INT64
=8, KC_ST_UINT64
=9)
88 class KCSubTypeElement(object):
89 """convert kcdata_subtype_descriptor to """
90 _unpack_formats
= (None, 'c', 'b', 'B', 'h', 'H', 'i', 'I', 'q', 'Q')
91 _ctypes
= ('Unknown', 'char', 'int8_t', 'uint8_t', 'int16_t', 'uint16_t', 'int32_t', 'uint32_t', 'int64_t', 'uint64_t')
93 def __init__(self
, st_name
, st_type
, st_size
, st_offset
=0, st_flag
=0, custom_repr
=None):
95 self
.offset
= st_offset
96 self
.type_id
= st_type
97 if st_type
<= 0 or st_type
> KCSUBTYPE_TYPE
.KC_ST_UINT64
:
98 raise ValueError("Invalid type passed %d" % st_type
)
99 self
.unpack_fmt
= KCSubTypeElement
._unpack
_formats
[self
.type_id
]
101 self
.totalsize
= st_size
103 self
.is_array_type
= False
104 self
.custom_JsonRepr
= custom_repr
105 if (st_flag
& 0x1) == 0x1:
106 self
.is_array_type
= True
107 self
.size
= st_size
& 0xffff
108 self
.count
= (st_size
>> 16) & 0xffff
109 self
.totalsize
= self
.size
* self
.count
112 def GetSizeForArray(el_count
, el_size
):
113 return ((el_count
& 0xffff) << 16) |
(el_size
& 0xffff)
116 def FromBinaryTypeData(byte_data
):
117 (st_flag
, st_type
, st_offset
, st_size
, st_name
) = struct
.unpack_from('=BBHI32s', byte_data
)
118 st_name
= st_name
.rstrip('\x00')
119 return KCSubTypeElement(st_name
, st_type
, st_size
, st_offset
, st_flag
)
122 def FromBasicCtype(st_name
, st_type
, st_offset
=0):
123 if st_type
<= 0 or st_type
> KCSUBTYPE_TYPE
.KC_ST_UINT64
:
124 raise ValueError("Invalid type passed %d" % st_type
)
125 st_size
= struct
.calcsize(KCSubTypeElement
._unpack
_formats
[st_type
])
127 retval
= KCSubTypeElement(st_name
, st_type
, st_size
, st_offset
, st_flag
, KCSubTypeElement
._get
_naked
_element
_value
)
131 def FromKCSubTypeElement(other
, name_override
=''):
132 _copy
= copy
.copy(other
)
134 _copy
.name
= name_override
140 def GetTotalSize(self
):
141 return self
.totalsize
143 def GetValueAsString(self
, base_data
, array_pos
=0):
144 return str(self
.GetValue(base_data
, array_pos
))
146 def GetValue(self
, base_data
, array_pos
=0):
147 return struct
.unpack_from(self
.unpack_fmt
, base_data
[self
.offset
+ (array_pos
* self
.size
):])[0]
150 def _get_naked_element_value(elementValue
, elementName
):
151 return json
.dumps(elementValue
)
154 if self
.is_array_type
:
155 return '[%d,%d] %s %s[%d];' % (self
.offset
, self
.totalsize
, self
.GetCTypeDesc(), self
.name
, self
.count
)
156 return '[%d,%d] %s %s;' % (self
.offset
, self
.totalsize
, self
.GetCTypeDesc(), self
.name
)
161 def GetCTypeDesc(self
):
162 return KCSubTypeElement
._ctypes
[self
.type_id
]
164 def GetStringRepr(self
, base_data
):
165 if not self
.is_array_type
:
166 return self
.GetValueAsString(base_data
)
167 if self
.type_id
== KCSUBTYPE_TYPE
.KC_ST_CHAR
:
169 if len(base_data
) < str_len
:
170 str_len
= len(base_data
)
172 for i
in range(str_len
):
173 _v
= self
.GetValue(base_data
, i
)
176 str_arr
.append(self
.GetValueAsString(base_data
, i
))
178 return '"' + ''.join(str_arr
) + '"'
179 o
= '[' + ','.join([self
.GetValueAsString(base_data
, i
) for i
in range(self
.count
)]) + ']'
182 def GetJsonRepr(self
, base_data
):
183 if self
.custom_JsonRepr
:
184 if self
.is_array_type
:
185 e_data
= [self
.GetValue(base_data
, i
) for i
in range(self
.count
)]
187 e_data
= self
.GetValue(base_data
)
188 return self
.custom_JsonRepr(e_data
, self
.name
)
189 return self
.GetStringRepr(base_data
)
192 class KCTypeDescription(object):
193 def __init__(self
, t_type_id
, t_elements
=[], t_name
='anon', custom_repr
=None):
194 self
.type_id
= t_type_id
195 self
.elements
= t_elements
198 self
.custom_JsonRepr
= custom_repr
199 for e
in self
.elements
:
200 self
.totalsize
+= e
.GetTotalSize()
202 def ValidateData(self
, base_data
):
203 if len(base_data
) >= self
.totalsize
:
214 o
= '%s {\n\t' % self.name + "\n\t".join([str(e) for e in self.elements]) + '\n};'
218 def FromKCTypeDescription(other
, t_type_id
, t_name
):
219 retval
= KCTypeDescription(t_type_id
, other
.elements
, t_name
, other
.custom_JsonRepr
)
222 def GetJsonRepr(self
, base_data
):
223 if self
.custom_JsonRepr
:
224 return self
.custom_JsonRepr([e
.GetValue(base_data
) for e
in self
.elements
])
225 o
= '{' + ", ".join(['"%s": %s' % (e.GetName(), e.GetJsonRepr(base_data)) for e in self.elements]) + '}'
229 def GetTypeNameForKey(k
):
231 if k
in KNOWN_TYPES_COLLECTION
:
232 retval
= KNOWN_TYPES_COLLECTION
[k
].GetName()
233 elif k
in kcdata_type_def_rev
:
234 retval
= kcdata_type_def_rev
[k
]
238 def GetTypeForName(n
):
240 if n
in kcdata_type_def
:
241 ret
= kcdata_type_def
[n
]
245 class KCObject(object):
248 def __init__(self
, type_code
, data
, flags
=0, field_name
=''):
249 self
.i_type
= type_code
251 self
.i_size
= len(data
)
252 self
.i_name
= field_name
254 self
.obj_collection
= []
256 self
.is_container_type
= False
257 self
.is_array_type
= False
258 self
.is_naked_type
= False
260 self
.i_name
= GetTypeNameForKey(type_code
)
264 def FromKCItem(kcitem
):
265 return KCObject(kcitem
.i_type
, kcitem
.i_data
, kcitem
.i_flags
)
267 def IsContainerType(self
):
268 return self
.is_container_type
270 def IsContainerEnd(self
):
271 if self
.i_type
in (GetTypeForName('KCDATA_TYPE_CONTIANER_END'), GetTypeForName('KCDATA_TYPE_BUFFER_END')):
275 def GetJsonRepr(self
):
276 if self
.is_array_type
:
277 return '[' + ', '.join([i
.GetJsonRepr() for i
in self
.obj_collection
]) + ']'
278 #if self.is_array_type:
279 # return '"%s" : [' % self.i_name + ', '.join([i.GetJsonRepr() for i in self.obj_collection]) + ']'
280 if self
.is_container_type
:
281 raise NotImplementedError("Containter types should not have come here")
282 if self
.i_type
in KNOWN_TYPES_COLLECTION
:
283 return KNOWN_TYPES_COLLECTION
[self
.i_type
].GetJsonRepr(self
.i_data
)
284 if self
.is_naked_type
:
285 return json
.dumps(self
.obj
)
287 raise NotImplementedError("Broken GetJsonRepr implementation")
290 if self
.i_type
== GetTypeForName('KCDATA_TYPE_CONTAINER_BEGIN'):
291 self
.is_container_type
= True
292 self
.obj
['uniqID'] = self
.i_flags
293 self
.i_name
= str(self
.obj
['uniqID'])
294 self
.obj
['typeID'] = struct
.unpack_from('I', self
.i_data
)[0]
296 elif self
.i_type
in (GetTypeForName('KCDATA_BUFFER_BEGIN_CRASHINFO'), GetTypeForName('KCDATA_BUFFER_BEGIN_STACKSHOT')):
297 self
.is_container_type
= True
298 self
.obj
['uniqID'] = self
.i_name
299 self
.obj
['typeID'] = self
.i_type
301 elif self
.i_type
== GetTypeForName('KCDATA_TYPE_CONTIANER_END'):
302 self
.obj
['uniqID'] = self
.i_flags
304 elif self
.i_type
== GetTypeForName('KCDATA_TYPE_BUFFER_END'):
307 elif self
.i_type
== GetTypeForName('KCDATA_TYPE_UINT32_DESC'):
308 self
.is_naked_type
= True
309 u_d
= struct
.unpack_from('32sI', self
.i_data
)
310 self
.i_name
= u_d
[0].strip(chr(0))
313 elif self
.i_type
== GetTypeForName('KCDATA_TYPE_UINT64_DESC'):
314 self
.is_naked_type
= True
315 u_d
= struct
.unpack_from('32sQ', self
.i_data
)
316 self
.i_name
= u_d
[0].strip(chr(0))
319 elif self
.i_type
== GetTypeForName('KCDATA_TYPE_TYPEDEFINTION'):
320 self
.is_naked_type
= True
321 u_d
= struct
.unpack_from('II32s', self
.i_data
)
322 self
.obj
['name'] = u_d
[2].strip(chr(0))
323 self
.i_name
= "typedef<%s>" % self
.obj
['name']
324 self
.obj
['typeID'] = u_d
[0]
325 self
.obj
['numOfFields'] = u_d
[1]
327 for i
in range(u_d
[1]):
328 e
= KCSubTypeElement
.FromBinaryTypeData(self
.i_data
[40+(i
*40):])
330 element_arr
.append(e
)
331 type_desc
= KCTypeDescription(u_d
[0], element_arr
, self
.obj
['name'])
332 #print str(type_desc)
333 self
.obj
['fields'] = [str(e
) for e
in element_arr
]
334 KNOWN_TYPES_COLLECTION
[type_desc
.GetTypeID()] = type_desc
336 elif self
.i_type
== GetTypeForName('KCDATA_TYPE_ARRAY'):
337 self
.is_array_type
= True
338 e_t
= (self
.i_flags
>> 32) & 0xffffffff
339 e_c
= self
.i_flags
& 0xffffffff
340 e_s
= self
.i_size
/ e_c
341 self
.obj
['typeID'] = e_t
342 self
.i_name
= GetTypeNameForKey(e_t
)
344 self
.obj
['numOfElements'] = e_c
345 self
.obj
['sizeOfElement'] = e_s
346 #populate the array here by recursive creation of KCObject
347 for _i
in range(e_c
):
348 _o
= KCObject(e_t
, self
.i_data
[(_i
* e_s
):(_i
* e_s
) + e_s
])
349 self
.obj_collection
.append(_o
)
350 elif self
.i_type
in KNOWN_TYPES_COLLECTION
:
351 self
.i_name
= KNOWN_TYPES_COLLECTION
[self
.i_type
].GetName()
352 self
.is_naked_type
= True
354 self
.is_naked_type
= True
355 #self.obj = "data of len %d" % len(self.i_data)
356 #self.obj = ''.join(["%x" % ki for ki in struct.unpack('%dB' % len(self.i_data), self.i_data)])
357 self
.obj
= base64
.b64encode(self
.i_data
)
360 class KCContainerObject(KCObject
):
361 def __init__(self
, *args
, **kwargs
):
362 KCObject
.__init
__(self
, *args
, **kwargs
)
363 self
.obj_container_dict
= {}
364 self
.obj_nested_objs
= {}
366 def GetJsonRepr(self
):
367 o
= '"%s"' % self
.obj
['uniqID'] + ' : { "typeID" : %d ,' % self
.obj
['typeID']
368 for (k
, v
) in self
.obj_container_dict
.items():
369 if v
.IsContainerType():
370 o
+= v
.GetJsonRepr() + ","
372 o
+= ' "%s" : ' % k
+ v
.GetJsonRepr() + ","
374 for (k
, v
) in self
.obj_nested_objs
.items():
375 o
+= '"%s" : {' % k + ",".join([vi.GetJsonRepr() for vi in v.values()]) + "} ,"
377 o = o.rstrip(',') + "}"
381 def AddObject(self, kco):
382 if kco.IsContainerEnd():
384 if kco.IsContainerType():
385 type_name = GetTypeNameForKey(kco.obj['typeID
'])
386 if type_name not in self.obj_nested_objs:
387 self.obj_nested_objs[type_name] = {}
388 self.obj_nested_objs[type_name][kco.i_name] = kco
390 self.obj_container_dict[kco.i_name] = kco
394 """ a basic kcdata_item type object.
396 header_size = 16 # (uint32_t + uint32_t + uint64_t)
398 def __init__(self, item_type, item_size, item_flags, item_data):
399 self.i_type = item_type
400 self.i_size = item_size
401 self.i_flags = item_flags
402 self.i_data = item_data
405 def __init__(self, barray, pos=0):
406 """ create an object by parsing data from bytes array
407 returns : obj - if data is readable
408 raises ValueError if something is not ok.
410 self.i_type = struct.unpack('I
', barray[pos:pos+4])[0] # int.from_bytes(barray[pos:pos+4])
411 self.i_size = struct.unpack('I
', barray[pos+4:pos+8])[0] # int.from_bytes(barray[pos+4:pos+8])
412 self.i_flags = struct.unpack('Q
', barray[pos+8:pos+16])[0] # int.from_bytes(barray[pos+8:pos+16])
413 self.i_data = barray[pos+16: (pos + 16 + self.i_size)]
417 return self.i_size + KCData_item.header_size
419 def GetHeaderDescription(self):
420 outs = "type: 0x%x size: 0x%x flags: 0x%x" % (self.i_type, self.i_size, self.i_flags)
421 if not self._buf_pos is None:
422 outs = "pos: 0x%x" % self._buf_pos + outs
426 return self.GetHeaderDescription()
429 def kcdata_item_iterator(filename):
432 with open(filename, "r+b") as f:
433 fmap = mmap.mmap(f.fileno(), 0)
436 while curpos < file_len:
437 item = KCData_item(fmap, curpos)
443 def _get_data_element(elementValues):
444 return json.dumps(elementValues[-1])
446 KNOWN_TYPES_COLLECTION[GetTypeForName('KCDATA_TYPE_UINT32_DESC
')] = KCTypeDescription(GetTypeForName('KCDATA_TYPE_UINT32_DESC
'), (
447 KCSubTypeElement('desc
', KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(32, 1), 0, 1),
448 KCSubTypeElement('data
', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 32, 0)
450 'KCDATA_TYPE_UINT32_DESC
',
454 KNOWN_TYPES_COLLECTION[GetTypeForName('KCDATA_TYPE_UINT64_DESC
')] = KCTypeDescription(GetTypeForName('KCDATA_TYPE_UINT64_DESC
'), (
455 KCSubTypeElement('desc
', KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(32, 1), 0, 1),
456 KCSubTypeElement('data
', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 32, 0)
458 'KCDATA_TYPE_UINT64_DESC
',
462 KNOWN_TYPES_COLLECTION[GetTypeForName('KCDATA_TYPE_TIMEBASE
')] = KCTypeDescription(GetTypeForName('KCDATA_TYPE_TIMEBASE
'), (
463 KCSubTypeElement('numerator
', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 0, 0),
464 KCSubTypeElement('denominator
', KCSUBTYPE_TYPE.KC_ST_UINT32, 8, 4, 0)
470 STACKSHOT_IO_NUM_PRIORITIES = 4
471 KNOWN_TYPES_COLLECTION[0x901] = KCTypeDescription(0x901, (
472 KCSubTypeElement.FromBasicCtype('disk_reads_count
', KCSUBTYPE_TYPE.KC_ST_UINT64, 0),
473 KCSubTypeElement.FromBasicCtype('disk_reads_size
', KCSUBTYPE_TYPE.KC_ST_UINT64, 8),
474 KCSubTypeElement.FromBasicCtype('disk_writes_count
', KCSUBTYPE_TYPE.KC_ST_UINT64, 16),
475 KCSubTypeElement.FromBasicCtype('disk_writes_size
', KCSUBTYPE_TYPE.KC_ST_UINT64, 24),
476 KCSubTypeElement('io_priority_count
', KCSUBTYPE_TYPE.KC_ST_UINT64, KCSubTypeElement.GetSizeForArray(STACKSHOT_IO_NUM_PRIORITIES, 8), 32, 1),
477 KCSubTypeElement('io_priority_size
', KCSUBTYPE_TYPE.KC_ST_UINT64, KCSubTypeElement.GetSizeForArray(STACKSHOT_IO_NUM_PRIORITIES, 8), 32 + (STACKSHOT_IO_NUM_PRIORITIES * 8), 1),
478 KCSubTypeElement.FromBasicCtype('paging_count
', KCSUBTYPE_TYPE.KC_ST_UINT64, 32 + 2 * (STACKSHOT_IO_NUM_PRIORITIES * 8)),
479 KCSubTypeElement.FromBasicCtype('paging_size
', KCSUBTYPE_TYPE.KC_ST_UINT64, 40 + 2 * (STACKSHOT_IO_NUM_PRIORITIES * 8)),
480 KCSubTypeElement.FromBasicCtype('non_paging_count
', KCSUBTYPE_TYPE.KC_ST_UINT64, 48 + 2 * (STACKSHOT_IO_NUM_PRIORITIES * 8)),
481 KCSubTypeElement.FromBasicCtype('non_paging_size
', KCSUBTYPE_TYPE.KC_ST_UINT64, 56 + 2 * (STACKSHOT_IO_NUM_PRIORITIES * 8)),
482 KCSubTypeElement.FromBasicCtype('data_count
', KCSUBTYPE_TYPE.KC_ST_UINT64, 64 + 2 * (STACKSHOT_IO_NUM_PRIORITIES * 8)),
483 KCSubTypeElement.FromBasicCtype('data_size
', KCSUBTYPE_TYPE.KC_ST_UINT64, 72 + 2 * (STACKSHOT_IO_NUM_PRIORITIES * 8)),
484 KCSubTypeElement.FromBasicCtype('metadata_count
', KCSUBTYPE_TYPE.KC_ST_UINT64, 80 + 2 * (STACKSHOT_IO_NUM_PRIORITIES * 8)),
485 KCSubTypeElement.FromBasicCtype('metadata_size
', KCSUBTYPE_TYPE.KC_ST_UINT64, 88 + 2 * (STACKSHOT_IO_NUM_PRIORITIES * 8))
490 KNOWN_TYPES_COLLECTION[0x902] = KCTypeDescription(0x902, (
491 KCSubTypeElement('snapshot_magic
', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 0, 0),
492 KCSubTypeElement('free_pages
', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 1, 0),
493 KCSubTypeElement('active_pages
', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 2, 0),
494 KCSubTypeElement('inactive_pages
', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 3, 0),
495 KCSubTypeElement('purgeable_pages
', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 4, 0),
496 KCSubTypeElement('wired_pages
', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 5, 0),
497 KCSubTypeElement('speculative_pages
', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 6, 0),
498 KCSubTypeElement('throttled_pages
', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 7, 0),
499 KCSubTypeElement('filebacked_pages
', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 8, 0),
500 KCSubTypeElement('compressions
', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 9, 0),
501 KCSubTypeElement('decompressions
', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 10, 0),
502 KCSubTypeElement('compressor_size
', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 11, 0),
503 KCSubTypeElement('busy_buffer_count
', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 4 * 12, 0),
504 KCSubTypeElement('pages_wanted
', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 13, 0),
505 KCSubTypeElement('pages_reclaimed
', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 14, 0),
506 KCSubTypeElement('pages_wanted_reclaimed_valid
', KCSUBTYPE_TYPE.KC_ST_UINT8, 1, 4 * 15, 0)
508 'mem_and_io_snapshot
'
512 KNOWN_TYPES_COLLECTION[0x905] = KCTypeDescription(0x905, (
513 KCSubTypeElement.FromBasicCtype('unique_pid
', KCSUBTYPE_TYPE.KC_ST_UINT64, 0),
514 KCSubTypeElement.FromBasicCtype('ss_flags
', KCSUBTYPE_TYPE.KC_ST_UINT64, 8),
515 KCSubTypeElement.FromBasicCtype('user_time_in_terminated_threads
', KCSUBTYPE_TYPE.KC_ST_UINT64, 16),
516 KCSubTypeElement.FromBasicCtype('system_time_in_terminated_threads
', KCSUBTYPE_TYPE.KC_ST_UINT64, 24),
517 KCSubTypeElement.FromBasicCtype('p_start_sec
', KCSUBTYPE_TYPE.KC_ST_UINT64, 32),
518 KCSubTypeElement.FromBasicCtype('task_size
', KCSUBTYPE_TYPE.KC_ST_UINT64, 40),
519 KCSubTypeElement.FromBasicCtype('task_max_resident_size
', KCSUBTYPE_TYPE.KC_ST_UINT64, 48),
520 KCSubTypeElement.FromBasicCtype('suspend_count
', KCSUBTYPE_TYPE.KC_ST_UINT32, 56),
521 KCSubTypeElement.FromBasicCtype('faults
', KCSUBTYPE_TYPE.KC_ST_UINT32, 60),
522 KCSubTypeElement.FromBasicCtype('pageins
', KCSUBTYPE_TYPE.KC_ST_UINT32, 64),
523 KCSubTypeElement.FromBasicCtype('cow_faults
', KCSUBTYPE_TYPE.KC_ST_UINT32, 68),
524 KCSubTypeElement.FromBasicCtype('was_throttled
', KCSUBTYPE_TYPE.KC_ST_UINT32, 72),
525 KCSubTypeElement.FromBasicCtype('did_throttle
', KCSUBTYPE_TYPE.KC_ST_UINT32, 76),
526 KCSubTypeElement.FromBasicCtype('latency_qos
', KCSUBTYPE_TYPE.KC_ST_UINT32, 80),
527 KCSubTypeElement.FromBasicCtype('pid
', KCSUBTYPE_TYPE.KC_ST_INT32, 84),
528 KCSubTypeElement('p_comm
', KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(32, 1), 88, 1)
533 KNOWN_TYPES_COLLECTION[0x906] = KCTypeDescription(0x906, (
534 KCSubTypeElement.FromBasicCtype('thread_id
', KCSUBTYPE_TYPE.KC_ST_UINT64, 0),
535 KCSubTypeElement.FromBasicCtype('wait_event
', KCSUBTYPE_TYPE.KC_ST_UINT64, 8),
536 KCSubTypeElement.FromBasicCtype('continuation
', KCSUBTYPE_TYPE.KC_ST_UINT64, 16),
537 KCSubTypeElement.FromBasicCtype('total_syscalls
', KCSUBTYPE_TYPE.KC_ST_UINT64, 24),
538 KCSubTypeElement.FromBasicCtype('voucher_identifier
', KCSUBTYPE_TYPE.KC_ST_UINT64, 32),
539 KCSubTypeElement.FromBasicCtype('dqserialnum
', KCSUBTYPE_TYPE.KC_ST_UINT64, 40),
540 KCSubTypeElement.FromBasicCtype('user_time
', KCSUBTYPE_TYPE.KC_ST_UINT64, 48),
541 KCSubTypeElement.FromBasicCtype('sys_time
', KCSUBTYPE_TYPE.KC_ST_UINT64, 56),
542 KCSubTypeElement.FromBasicCtype('ss_flags
', KCSUBTYPE_TYPE.KC_ST_UINT64, 64),
543 KCSubTypeElement.FromBasicCtype('last_run_time
', KCSUBTYPE_TYPE.KC_ST_UINT64, 72),
544 KCSubTypeElement.FromBasicCtype('last_made_runnable_time
', KCSUBTYPE_TYPE.KC_ST_UINT64, 80),
545 KCSubTypeElement.FromBasicCtype('state
', KCSUBTYPE_TYPE.KC_ST_UINT32, 88),
546 KCSubTypeElement.FromBasicCtype('sched_flags
', KCSUBTYPE_TYPE.KC_ST_UINT32, 92),
547 KCSubTypeElement.FromBasicCtype('base_priority
', KCSUBTYPE_TYPE.KC_ST_INT16, 96),
548 KCSubTypeElement.FromBasicCtype('sched_priority
', KCSUBTYPE_TYPE.KC_ST_INT16, 98),
549 KCSubTypeElement.FromBasicCtype('ts_eqos
', KCSUBTYPE_TYPE.KC_ST_UINT8, 100),
550 KCSubTypeElement.FromBasicCtype('ts_rqos
', KCSUBTYPE_TYPE.KC_ST_UINT8, 101),
551 KCSubTypeElement.FromBasicCtype('ts_rqos_override
', KCSUBTYPE_TYPE.KC_ST_UINT8, 102),
552 KCSubTypeElement.FromBasicCtype('io_tier
', KCSUBTYPE_TYPE.KC_ST_UINT8, 103),
557 KNOWN_TYPES_COLLECTION[0x909] = KCSubTypeElement('pth_name
', KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(64, 1), 0, 1)
560 def _get_uuid_json_data(elementValues, elementName):
561 return '"<%s>"' % ''.join("%02x" % i for i in elementValues)
563 KNOWN_TYPES_COLLECTION[GetTypeForName('KCDATA_TYPE_LIBRARY_LOADINFO64
')] = KCTypeDescription(GetTypeForName('KCDATA_TYPE_LIBRARY_LOADINFO64
'), (
564 KCSubTypeElement('loadAddress
', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0),
565 KCSubTypeElement('imageUUID
', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(16, 1), 8, 1, _get_uuid_json_data)
570 KNOWN_TYPES_COLLECTION[GetTypeForName('KCDATA_TYPE_LIBRARY_LOADINFO
')] = KCTypeDescription(GetTypeForName('KCDATA_TYPE_LIBRARY_LOADINFO
'), (
571 KCSubTypeElement('loadAddress
', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 0, 0),
572 KCSubTypeElement('imageUUID
', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(16, 1), 4, 1, _get_uuid_json_data)
577 KNOWN_TYPES_COLLECTION[0x908] = KCTypeDescription.FromKCTypeDescription(KNOWN_TYPES_COLLECTION[GetTypeForName('KCDATA_TYPE_LIBRARY_LOADINFO64
')], 0x908, 'shared_cache_dyld_info
')
579 KNOWN_TYPES_COLLECTION[0x33] = KCSubTypeElement('mach_absolute_time
', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0, KCSubTypeElement._get_naked_element_value)
580 KNOWN_TYPES_COLLECTION[0x907] = KCSubTypeElement.FromBasicCtype('donating_pids
', KCSUBTYPE_TYPE.KC_ST_INT32)
582 KNOWN_TYPES_COLLECTION[GetTypeForName('KCDATA_TYPE_USECS_SINCE_EPOCH
')] = KCSubTypeElement('usecs_since_epoch
', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0, KCSubTypeElement._get_naked_element_value)
584 KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKFRAME
')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKFRAME
'), (
585 KCSubTypeElement.FromBasicCtype('lr
', KCSUBTYPE_TYPE.KC_ST_UINT32),
586 KCSubTypeElement.FromBasicCtype('sp
', KCSUBTYPE_TYPE.KC_ST_UINT32, 4)
588 'kernel_stack_frames
'
591 KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_USER_STACKFRAME
')] = KCTypeDescription.FromKCTypeDescription(
592 KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKFRAME
')],
593 GetTypeForName('STACKSHOT_KCTYPE_USER_STACKFRAME
'),
597 KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKFRAME64
')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKFRAME64
'), (
598 KCSubTypeElement.FromBasicCtype('lr
', KCSUBTYPE_TYPE.KC_ST_UINT64),
599 KCSubTypeElement.FromBasicCtype('sp
', KCSUBTYPE_TYPE.KC_ST_UINT64, 8)
601 'kernel_stack_frames
'
604 KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_USER_STACKFRAME64
')] = KCTypeDescription.FromKCTypeDescription(
605 KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKFRAME64
')],
606 GetTypeForName('STACKSHOT_KCTYPE_USER_STACKFRAME64
'),
610 KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_OSVERSION
')] = KCSubTypeElement('osversion
', KCSUBTYPE_TYPE.KC_ST_CHAR,
611 KCSubTypeElement.GetSizeForArray(256, 1), 0, 1)
613 KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_BOOTARGS
')] = KCSubTypeElement('bootargs
', KCSUBTYPE_TYPE.KC_ST_CHAR,
614 KCSubTypeElement.GetSizeForArray(256, 1), 0, 1)
616 KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_KERN_PAGE_SIZE
')] = KCSubTypeElement('kernel_page_size
', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 0, 0, KCSubTypeElement._get_naked_element_value)
618 KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_JETSAM_LEVEL
')] = KCSubTypeElement('jetsam_level
', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 0, 0, KCSubTypeElement._get_naked_element_value)
621 #KNOWN_TYPES_COLLECTION[0x907] = KCSubTypeElement('donating_pids
', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 0, 0, KCSubTypeElement._get_naked_element_value)
622 KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_PID
')] = KCSubTypeElement('pid
', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0)
623 KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_PPID
')] = KCSubTypeElement('ppid
', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0)
624 KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_PROC_NAME
')] = KCSubTypeElement('p_comm
', KCSUBTYPE_TYPE.KC_ST_CHAR,
625 KCSubTypeElement.GetSizeForArray(32, 1), 0, 1)
626 KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_USERSTACK
')] = KCSubTypeElement('userstack_ptr
', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0)
627 KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_ARGSLEN
')] = KCSubTypeElement('p_argslen
', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0)
629 KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_PROC_PATH
')] = KCSubTypeElement('p_path
', KCSUBTYPE_TYPE.KC_ST_CHAR,
630 KCSubTypeElement.GetSizeForArray(1024, 1), 0, 1)
631 KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_PROC_CSFLAGS
')] = KCSubTypeElement('p_csflags
', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0)
632 KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_UID
')] = KCSubTypeElement('uid
', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0)
633 KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_GID
')] = KCSubTypeElement('gid
', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0)
634 KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_PROC_ARGC
')] = KCSubTypeElement('argc
', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0)
635 KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_PROC_FLAGS
')] = KCSubTypeElement('p_flags
', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0)
636 KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_CPUTYPE
')] = KCSubTypeElement('cputype
', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0)
637 KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_RESPONSIBLE_PID
')] = KCSubTypeElement('responsible_pid
', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0)
638 KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_DIRTY_FLAGS
')] = KCSubTypeElement('dirty_flags
', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0)
639 KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_CRASHED_THREADID
')] = KCSubTypeElement('crashed_threadid
', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0)
641 KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_PROC_STATUS
')] = KCSubTypeElement('p_status
', KCSUBTYPE_TYPE.KC_ST_UINT8, 1, 0, 0)
643 KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_BSDINFOWITHUNIQID
')] = KCTypeDescription(GetTypeForName('TASK_CRASHINFO_BSDINFOWITHUNIQID
'),
644 ( KCSubTypeElement('p_uuid
', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(16, 1), 0, 1),
645 KCSubTypeElement.FromBasicCtype('p_uniqueid
', KCSUBTYPE_TYPE.KC_ST_UINT64, 16),
646 KCSubTypeElement.FromBasicCtype('p_puniqueid
', KCSUBTYPE_TYPE.KC_ST_UINT64, 24)
648 'proc_uniqidentifierinfo
')
650 KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_EXCEPTION_CODES
')] = KCSubTypeElement('TASK_CRASHINFO_EXCEPTION_CODES
', KCSUBTYPE_TYPE.KC_ST_INT64,
651 KCSubTypeElement.GetSizeForArray(2,8), 0, 1)
653 KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_RUSAGE_INFO
')] = KCTypeDescription(GetTypeForName('TASK_CRASHINFO_RUSAGE_INFO
'),
655 KCSubTypeElement('ri_uuid
', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(16, 1), 0, 1),
656 KCSubTypeElement.FromBasicCtype('ri_user_time
', KCSUBTYPE_TYPE.KC_ST_UINT64, 16),
657 KCSubTypeElement.FromBasicCtype('ri_system_time
', KCSUBTYPE_TYPE.KC_ST_UINT64, 24),
658 KCSubTypeElement.FromBasicCtype('ri_pkg_idle_wkups
', KCSUBTYPE_TYPE.KC_ST_UINT64, 32),
659 KCSubTypeElement.FromBasicCtype('ri_interrupt_wkups
', KCSUBTYPE_TYPE.KC_ST_UINT64, 40),
660 KCSubTypeElement.FromBasicCtype('ri_pageins
', KCSUBTYPE_TYPE.KC_ST_UINT64, 48),
661 KCSubTypeElement.FromBasicCtype('ri_wired_size
', KCSUBTYPE_TYPE.KC_ST_UINT64, 56),
662 KCSubTypeElement.FromBasicCtype('ri_resident_size
', KCSUBTYPE_TYPE.KC_ST_UINT64, 64),
663 KCSubTypeElement.FromBasicCtype('ri_phys_footprint
', KCSUBTYPE_TYPE.KC_ST_UINT64, 72),
664 KCSubTypeElement.FromBasicCtype('ri_proc_start_abstime
', KCSUBTYPE_TYPE.KC_ST_UINT64, 80),
665 KCSubTypeElement.FromBasicCtype('ri_proc_exit_abstime
', KCSUBTYPE_TYPE.KC_ST_UINT64, 88),
666 KCSubTypeElement.FromBasicCtype('ri_child_user_time
', KCSUBTYPE_TYPE.KC_ST_UINT64, 96),
667 KCSubTypeElement.FromBasicCtype('ri_child_system_time
', KCSUBTYPE_TYPE.KC_ST_UINT64, 104),
668 KCSubTypeElement.FromBasicCtype('ri_child_pkg_idle_wkups
', KCSUBTYPE_TYPE.KC_ST_UINT64, 112),
669 KCSubTypeElement.FromBasicCtype('ri_child_interrupt_wkups
', KCSUBTYPE_TYPE.KC_ST_UINT64, 120),
670 KCSubTypeElement.FromBasicCtype('ri_child_pageins
', KCSUBTYPE_TYPE.KC_ST_UINT64, 128),
671 KCSubTypeElement.FromBasicCtype('ri_child_elapsed_abstime
', KCSUBTYPE_TYPE.KC_ST_UINT64, 136),
672 KCSubTypeElement.FromBasicCtype('ri_diskio_bytesread
', KCSUBTYPE_TYPE.KC_ST_UINT64, 144),
673 KCSubTypeElement.FromBasicCtype('ri_diskio_byteswritten
', KCSUBTYPE_TYPE.KC_ST_UINT64, 152),
674 KCSubTypeElement.FromBasicCtype('ri_cpu_time_qos_default
', KCSUBTYPE_TYPE.KC_ST_UINT64, 160),
675 KCSubTypeElement.FromBasicCtype('ri_cpu_time_qos_maintenance
', KCSUBTYPE_TYPE.KC_ST_UINT64, 168),
676 KCSubTypeElement.FromBasicCtype('ri_cpu_time_qos_background
', KCSUBTYPE_TYPE.KC_ST_UINT64, 176),
677 KCSubTypeElement.FromBasicCtype('ri_cpu_time_qos_utility
', KCSUBTYPE_TYPE.KC_ST_UINT64, 184),
678 KCSubTypeElement.FromBasicCtype('ri_cpu_time_qos_legacy
', KCSUBTYPE_TYPE.KC_ST_UINT64, 192),
679 KCSubTypeElement.FromBasicCtype('ri_cpu_time_qos_user_initiated
', KCSUBTYPE_TYPE.KC_ST_UINT64, 200),
680 KCSubTypeElement.FromBasicCtype('ri_cpu_time_qos_user_interactive
', KCSUBTYPE_TYPE.KC_ST_UINT64, 208),
681 KCSubTypeElement.FromBasicCtype('ri_billed_system_time
', KCSUBTYPE_TYPE.KC_ST_UINT64, 216),
682 KCSubTypeElement.FromBasicCtype('ri_serviced_system_time
', KCSUBTYPE_TYPE.KC_ST_UINT64, 224)
686 def GetSecondsFromMATime(mat, tb):
687 return (float(mat) * tb['numerator
']) / tb['denominator
']
689 def FindLibraryForAddress(liblist, address):
696 def FindIndexOfLibInCatalog(catalog, lib):
700 if l[0] == lib[0] and l[1] == lib[1]:
707 index = len(catalog) - 1
711 def GetOffsetOfAddressForLib(lib, address):
712 return (address - lib[1])
714 def GetSymbolInfoForFrame(catalog, liblist, address):
715 lib = FindLibraryForAddress(liblist, address)
717 lib = ["00000000000000000000000000000000",0,"A"]
718 offset = GetOffsetOfAddressForLib(lib, address)
719 index = FindIndexOfLibInCatalog(catalog, lib)
720 return [index, offset]
722 def GetStateDescription(s):
732 retval.append("TH_WAIT")
734 retval.append("TH_SUSP")
736 retval.append("TH_RUN")
738 retval.append("TH_UNINT")
739 if (s & TH_TERMINATE):
740 retval.append("TH_TERMINATE")
741 if (s & TH_TERMINATE2):
742 retval.append("TH_TERMINATE2")
744 retval.append("TH_IDLE")
747 def SaveStackshotReport(j, outfile_name, dsc_uuid, dsc_libs_arr):
749 from operator import itemgetter, attrgetter
750 ss = j.get('KCDATA_BUFFER_BEGIN_STACKSHOT
')
752 print "No KCDATA_BUFFER_BEGIN_STACKSHOT object found. Skipping writing report."
754 timestamp = ss.get('usecs_since_epoch
', int(time.time()))
755 timestamp = time.strftime("%Y-%m-%d %H:%M:%S %z",time.gmtime(timestamp))
756 os_version = ss.get('osversion
', 'Unknown
')
757 timebase = ss.get('timebase_info
', {"denominator": 1, "numerator": 1})
758 dsc_common = [ss.get('shared_cache_dyld_info
')['imageUUID
'].strip('<>'),
759 ss.get('shared_cache_dyld_info
')['loadAddress
'],
764 if dsc_common[0].replace('-', '').lower() == dsc_uuid:
765 print "SUCCESS: Found Matching dyld shared cache uuid. Loading library load addresses from layout provided."
766 _load_addr = dsc_common[1]
769 for i in dsc_libs_arr:
770 _uuid = i[2].lower().replace('-','').strip()
771 _addr = int(i[0], 16) + _load_addr
772 dsc_libs.append([_uuid, _addr, "P"])
773 #print "adding ", [_uuid, _addr, "C"]
777 obj["kernel"] = os_version
778 obj["date"] = timestamp
779 obj["reason"] = "kernel panic stackshot"
780 obj["incident"] = "ABCDEFGH-1234-56IJ-789K-0LMNOPQRSTUV"
781 obj["crashReporterKey"] = "12ab34cd45aabbccdd6712ab34cd45aabbccdd67"
782 obj["bootArgs"] = ss.get('bootargs
','')
783 obj["frontmostPids"] = [0]
784 obj["exception"] = "0xDEADF157"
785 obj["processByPid"] = {}
786 processByPid = obj["processByPid"]
787 ssplist = ss.get('STACKSHOT_KCCONTAINER_TASK
', {})
790 kl_infos = ssplist["0"].get("dyld_load_info", [])
791 for dlinfo in kl_infos:
792 kern_load_info.append([dlinfo['imageUUID
'].strip('<>'), dlinfo['loadAddress
'], "K"])
793 for pid,piddata in ssplist.iteritems():
794 processByPid[str(pid)] = {}
795 tsnap = processByPid[str(pid)]
796 pr_lib_dsc = dsc_common
797 if 'shared_cache_dyld_info
' in tsnap:
798 pr_lib_dsc = [tsnap.get('shared_cache_dyld_info
')['imageUUID
'].strip('<>'),
799 tsnap.get('shared_cache_dyld_info
')['loadAddress
'],
804 if len(dsc_libs) == 0:
805 pr_libs.append(pr_lib_dsc)
811 for dlinfo in piddata.get('dyld_load_info
',[]):
812 pr_libs.append([dlinfo['imageUUID
'].strip('<>'), dlinfo['loadAddress
'], _lib_type])
814 pr_libs.extend(kern_load_info)
815 pr_libs.extend(dsc_libs)
817 pr_libs.sort(key=itemgetter(1))
819 tasksnap = piddata['task_snapshot_v2
']
820 tsnap["pid"] = tasksnap["pid"]
821 tsnap["residentMemoryBytes"] = tasksnap["task_size"]
822 tsnap["timesDidThrottle"] = tasksnap["did_throttle"]
823 tsnap["systemTimeTask"] = GetSecondsFromMATime(tasksnap["system_time_in_terminated_threads"], timebase)
824 tsnap["pageIns"] = tasksnap["pageins"]
825 tsnap["pageFaults"] = tasksnap["faults"]
826 tsnap["userTimeTask"] = GetSecondsFromMATime(tasksnap["user_time_in_terminated_threads"], timebase)
827 tsnap["procname"] = tasksnap["p_comm"]
828 tsnap["copyOnWriteFaults"] = tasksnap["cow_faults"]
829 tsnap["timesThrottled"] = tasksnap["was_throttled"]
830 tsnap["threadById"] = {}
831 threadByID = tsnap["threadById"]
832 thlist = piddata.get('STACKSHOT_KCCONTAINER_THREAD
', {})
833 for tid,thdata in thlist.iteritems():
834 threadByID[str(tid)] = {}
835 thsnap = threadByID[str(tid)]
836 threadsnap = thdata["thread_snapshot_v2"]
837 thsnap["userTime"] = GetSecondsFromMATime(threadsnap["user_time"], timebase)
838 thsnap["id"] = threadsnap["thread_id"]
839 thsnap["basePriority"] = threadsnap["base_priority"]
840 thsnap["systemTime"] = threadsnap["sys_time"]
841 thsnap["schedPriority"] = threadsnap["sched_priority"]
842 thsnap["state"] = GetStateDescription(threadsnap['state
'])
843 thsnap["qosEffective"] = threadsnap["ts_eqos"]
844 thsnap["qosRequested"] = threadsnap["ts_rqos"]
846 if threadsnap['continuation
']:
847 thsnap["continuation"] = GetSymbolInfoForFrame(AllImageCatalog, pr_libs, threadsnap['continuation
'])
848 if "kernel_stack_frames" in thdata:
850 for f in thdata["kernel_stack_frames"]:
851 kuserframes.append(GetSymbolInfoForFrame(AllImageCatalog, pr_libs, f['lr
']))
852 thsnap["kernelFrames"] = kuserframes
854 if "user_stack_frames" in thdata:
856 for f in thdata["user_stack_frames"]:
857 uframes.append(GetSymbolInfoForFrame(AllImageCatalog, pr_libs, f['lr
']))
858 thsnap["userFrames"] = uframes
859 if threadsnap['wait_event
']:
860 thsnap["waitEvent"] = GetSymbolInfoForFrame(AllImageCatalog, pr_libs, threadsnap['wait_event
'])
862 obj['binaryImages
'] = AllImageCatalog
863 fh = open(outfile_name, "w")
864 fh.write('{"bug_type":"288", "timestamp":"'+ timestamp +'", "os_version":"'+ os_version +'"}
\n')
865 fh.write(json.dumps(obj, sort_keys=False, indent=2, separators=(',', ': ')))
868 ## Base utils for interacting with shell ##
869 def RunCommand(bash_cmd_string, get_stderr = True):
871 returns: (int,str) : exit_code and output_str
873 print "RUNNING: %s" % bash_cmd_string
874 cmd_args = shlex.split(bash_cmd_string)
879 output_str = subprocess.check_output(cmd_args, stderr=subprocess.STDOUT)
881 output_str = subprocess.check_output(cmd_args, stderr=None)
882 except subprocess.CalledProcessError, e:
883 exit_code = e.returncode
885 return (exit_code, output_str)
887 def ProcessDyldSharedCacheFile(shared_cache_file_path, sdk_str=""):
888 """ returns (uuid, text_info) output from shared_cache_util.
889 In case of error None is returned and err message is printed to stdout.
891 if not os.path.exists(shared_cache_file_path):
892 print "File path: %s does not exists" % shared_cache_file_path
895 sdk_str = ' -sdk
"%s" ' % sdk_str
896 (c, so) = RunCommand("xcrun {} -find dyld_shared_cache_util".format(sdk_str))
898 print "Failed to find path to dyld_shared_cache_util. Exit code: %d , message: %s" % (c,so)
900 dyld_shared_cache_util = so.strip()
901 (c, so) = RunCommand("{} -info {}".format(dyld_shared_cache_util, shared_cache_file_path))
903 print "Failed to get uuid info from %s" % shared_cache_file_path
907 uuid = so.splitlines()[0].split(": ")[-1].strip().replace("-","").lower()
909 (c, so) = RunCommand("{} -text_info {}".format(dyld_shared_cache_util, shared_cache_file_path))
911 print "Failed to get text_info from %s" % shared_cache_file_path
915 print "Found %s uuid: %s" % (shared_cache_file_path, uuid)
920 parser = argparse.ArgumentParser(description="Decode a kcdata binary file.")
921 parser.add_argument("-l", "--listtypes", action="store_true", required=False, default=False,
922 help="List all known types",
923 dest="list_known_types")
925 parser.add_argument("-s", "--stackshot", required=False, default=False,
926 help="Generate a stackshot report file",
927 dest="stackshot_file")
929 parser.add_argument("-U", "--uuid", required=False, default="", help="UUID of dyld shared cache to be analysed and filled in libs of stackshot report", dest="uuid")
930 parser.add_argument("-L", "--layout", required=False, type=argparse.FileType("r"), help="Path to layout file for DyldSharedCache. You can generate one by doing \n\tbash$xcrun -sdk <sdk> dyld_shared_cache_util -text_info </path/to/dyld_shared_cache> ", dest="layout")
931 parser.add_argument("-S", "--sdk", required=False, default="", help="sdk property passed to xcrun command to find the required tools. Default is empty string.", dest="sdk")
932 parser.add_argument("-D", "--dyld_shared_cache", required=False, default="", help="Path to dyld_shared_cache built by B&I", dest="dsc")
933 parser.add_argument("kcdata_file", type=argparse.FileType('r
'), help="Path to a kcdata binary file.")
937 if __name__ == '__main__
':
938 args = parser.parse_args()
940 if args.list_known_types:
941 for (n, t) in KNOWN_TYPES_COLLECTION.items():
942 print "%d : %s " % (n, str(t))
945 file_name = args.kcdata_file.name
947 master_container = None
948 current_container = None
949 for i in kcdata_item_iterator(file_name):
950 #print "processed " + str(i)
951 o = KCObject.FromKCItem(i)
952 if o.IsContainerType():
953 o = KCContainerObject(i.i_type, i.i_data, i.i_flags)
955 if current_container is None:
956 master_objs.append(o)
957 current_container = o
960 current_container.AddObject(o)
962 if o.IsContainerType():
963 master_objs.append(current_container)
964 current_container = o
966 if o.IsContainerEnd():
967 current_container = master_objs.pop()
968 str_data = "{" + master_container.GetJsonRepr() + "}"
970 json_obj = json.loads(str_data)
973 libs_re = re.compile("^\s*(0x[a-fA-F0-9]+)\s->\s(0x[a-fA-F0-9]+)\s+<([a-fA-F0-9\-]+)>\s+.*$", re.MULTILINE)
974 if args.uuid and args.layout:
975 dsc_uuid = args.uuid.strip().replace("-",'').lower()
976 dsc_libs_arr = libs_re.findall(args.layout.read())
979 _ret = ProcessDyldSharedCacheFile(args.dsc, args.sdk)
982 dsc_libs_arr = libs_re.findall(_ret[1])
984 if args.stackshot_file:
985 SaveStackshotReport(json_obj, args.stackshot_file, dsc_uuid, dsc_libs_arr)
987 print json.dumps(json_obj, sort_keys=True, indent=4, separators=(',', ': '))
992 print "--------------------------------------------"*3