1#!/usr/bin/env python3 2from __future__ import absolute_import, print_function, division 3import sys 4import struct 5import mmap 6import json 7import copy 8import re 9import base64 10import argparse 11import shlex 12import subprocess 13import logging 14import contextlib 15import base64 16import zlib 17import six 18 19if six.PY3: 20 long = int 21else: 22 # can be removed once we move to Python3.1+ 23 from future.utils.surrogateescape import register_surrogateescape 24 register_surrogateescape() 25 26class Globals(object): 27 pass 28G = Globals() 29G.accept_incomplete_data = False 30G.data_was_incomplete = False 31 32kcdata_type_def = { 33 'KCDATA_TYPE_INVALID': 0x0, 34 'KCDATA_TYPE_STRING_DESC': 0x1, 35 'KCDATA_TYPE_UINT32_DESC': 0x2, 36 'KCDATA_TYPE_UINT64_DESC': 0x3, 37 'KCDATA_TYPE_INT32_DESC': 0x4, 38 'KCDATA_TYPE_INT64_DESC': 0x5, 39 'KCDATA_TYPE_BINDATA_DESC': 0x6, 40 'KCDATA_TYPE_ARRAY': 0x11, 41 'KCDATA_TYPE_TYPEDEFINITION': 0x12, 42 'KCDATA_TYPE_CONTAINER_BEGIN': 0x13, 43 'KCDATA_TYPE_CONTAINER_END': 0x14, 44 45 'KCDATA_TYPE_ARRAY_PAD0': 0x20, 46 'KCDATA_TYPE_ARRAY_PAD1': 0x21, 47 'KCDATA_TYPE_ARRAY_PAD2': 0x22, 48 'KCDATA_TYPE_ARRAY_PAD3': 0x23, 49 'KCDATA_TYPE_ARRAY_PAD4': 0x24, 50 'KCDATA_TYPE_ARRAY_PAD5': 0x25, 51 'KCDATA_TYPE_ARRAY_PAD6': 0x26, 52 'KCDATA_TYPE_ARRAY_PAD7': 0x27, 53 'KCDATA_TYPE_ARRAY_PAD8': 0x28, 54 'KCDATA_TYPE_ARRAY_PAD9': 0x29, 55 'KCDATA_TYPE_ARRAY_PADa': 0x2a, 56 'KCDATA_TYPE_ARRAY_PADb': 0x2b, 57 'KCDATA_TYPE_ARRAY_PADc': 0x2c, 58 'KCDATA_TYPE_ARRAY_PADd': 0x2d, 59 'KCDATA_TYPE_ARRAY_PADe': 0x2e, 60 'KCDATA_TYPE_ARRAY_PADf': 0x2f, 61 62 'KCDATA_TYPE_LIBRARY_LOADINFO': 0x30, 63 'KCDATA_TYPE_LIBRARY_LOADINFO64': 0x31, 64 'KCDATA_TYPE_TIMEBASE': 0x32, 65 'KCDATA_TYPE_MACH_ABSOLUTE_TIME': 0x33, 66 'KCDATA_TYPE_TIMEVAL': 0x34, 67 'KCDATA_TYPE_USECS_SINCE_EPOCH': 0x35, 68 'KCDATA_TYPE_PID': 0x36, 69 'KCDATA_TYPE_PROCNAME': 0x37, 70 'KCDATA_TYPE_NESTED_KCDATA': 0x38, 71 'KCDATA_TYPE_LIBRARY_AOTINFO': 0x39, 72 73 'STACKSHOT_KCCONTAINER_TASK': 0x903, 74 'STACKSHOT_KCCONTAINER_THREAD': 0x904, 75 'STACKSHOT_KCTYPE_DONATING_PIDS': 0x907, 76 'STACKSHOT_KCTYPE_SHAREDCACHE_LOADINFO': 0x908, 77 'STACKSHOT_KCTYPE_THREAD_NAME': 0x909, 78 'STACKSHOT_KCTYPE_KERN_STACKFRAME': 0x90A, 79 'STACKSHOT_KCTYPE_KERN_STACKFRAME64': 0x90B, 80 'STACKSHOT_KCTYPE_USER_STACKFRAME': 0x90C, 81 'STACKSHOT_KCTYPE_USER_STACKFRAME64': 0x90D, 82 'STACKSHOT_KCTYPE_BOOTARGS': 0x90E, 83 'STACKSHOT_KCTYPE_OSVERSION': 0x90F, 84 'STACKSHOT_KCTYPE_KERN_PAGE_SIZE': 0x910, 85 'STACKSHOT_KCTYPE_JETSAM_LEVEL': 0x911, 86 'STACKSHOT_KCTYPE_DELTA_SINCE_TIMESTAMP': 0x912, 87 'STACKSHOT_KCTYPE_KERN_STACKLR': 0x913, 88 'STACKSHOT_KCTYPE_KERN_STACKLR64': 0x914, 89 'STACKSHOT_KCTYPE_USER_STACKLR': 0x915, 90 'STACKSHOT_KCTYPE_USER_STACKLR64': 0x916, 91 'STACKSHOT_KCTYPE_NONRUNNABLE_TIDS': 0x917, 92 'STACKSHOT_KCTYPE_NONRUNNABLE_TASKS': 0x918, 93 'STACKSHOT_KCTYPE_CPU_TIMES': 0x919, 94 'STACKSHOT_KCTYPE_STACKSHOT_DURATION': 0x91a, 95 'STACKSHOT_KCTYPE_STACKSHOT_FAULT_STATS': 0x91b, 96 'STACKSHOT_KCTYPE_KERNELCACHE_LOADINFO': 0x91c, 97 'STACKSHOT_KCTYPE_THREAD_WAITINFO' : 0x91d, 98 'STACKSHOT_KCTYPE_THREAD_GROUP_SNAPSHOT' : 0x91e, 99 'STACKSHOT_KCTYPE_THREAD_GROUP' : 0x91f, 100 'STACKSHOT_KCTYPE_JETSAM_COALITION_SNAPSHOT' : 0x920, 101 'STACKSHOT_KCTYPE_JETSAM_COALITION' : 0x921, 102 'STACKSHOT_KCTYPE_THREAD_POLICY_VERSION': 0x922, 103 'STACKSHOT_KCTYPE_INSTRS_CYCLES' : 0x923, 104 'STACKSHOT_KCTYPE_USER_STACKTOP' : 0x924, 105 'STACKSHOT_KCTYPE_ASID' : 0x925, 106 'STACKSHOT_KCTYPE_PAGE_TABLES' : 0x926, 107 'STACKSHOT_KCTYPE_SYS_SHAREDCACHE_LAYOUT' : 0x927, 108 'STACKSHOT_KCTYPE_THREAD_DISPATCH_QUEUE_LABEL' : 0x928, 109 'STACKSHOT_KCTYPE_THREAD_TURNSTILEINFO' : 0x929, 110 'STACKSHOT_KCTYPE_TASK_CPU_ARCHITECTURE' : 0x92a, 111 'STACKSHOT_KCTYPE_LATENCY_INFO' : 0x92b, 112 'STACKSHOT_KCTYPE_LATENCY_INFO_TASK' : 0x92c, 113 'STACKSHOT_KCTYPE_LATENCY_INFO_THREAD' : 0x92d, 114 'STACKSHOT_KCTYPE_LOADINFO64_TEXT_EXEC' : 0x92e, 115 'STACKSHOT_KCTYPE_AOTCACHE_LOADINFO' : 0x92f, 116 'STACKSHOT_KCTYPE_TRANSITIONING_TASK_SNAPSHOT' : 0x930, 117 'STACKSHOT_KCCONTAINER_TRANSITIONING_TASK' : 0x931, 118 'STACKSHOT_KCTYPE_USER_ASYNC_START_INDEX' : 0x932, 119 'STACKSHOT_KCTYPE_USER_ASYNC_STACKLR64' : 0x933, 120 'STACKSHOT_KCCONTAINER_PORTLABEL' : 0x934, 121 'STACKSHOT_KCTYPE_PORTLABEL' : 0x935, 122 'STACKSHOT_KCTYPE_PORTLABEL_NAME' : 0x936, 123 'STACKSHOT_KCTYPE_TASK_DELTA_SNAPSHOT': 0x940, 124 'STACKSHOT_KCTYPE_THREAD_DELTA_SNAPSHOT': 0x941, 125 126 'KCDATA_TYPE_BUFFER_END': 0xF19158ED, 127 128 'TASK_CRASHINFO_EXTMODINFO': 0x801, 129 'TASK_CRASHINFO_BSDINFOWITHUNIQID': 0x802, 130 'TASK_CRASHINFO_TASKDYLD_INFO': 0x803, 131 'TASK_CRASHINFO_UUID': 0x804, 132 'TASK_CRASHINFO_PID': 0x805, 133 'TASK_CRASHINFO_PPID': 0x806, 134 135 # Don't want anyone using this. It's struct rusage from whatever machine generated the data 136 #'TASK_CRASHINFO_RUSAGE': 0x807, 137 'Type_0x807': 0x807, 138 139 'TASK_CRASHINFO_RUSAGE_INFO': 0x808, 140 'TASK_CRASHINFO_PROC_NAME': 0x809, 141 'TASK_CRASHINFO_PROC_STARTTIME': 0x80B, 142 'TASK_CRASHINFO_USERSTACK': 0x80C, 143 'TASK_CRASHINFO_ARGSLEN': 0x80D, 144 'TASK_CRASHINFO_EXCEPTION_CODES': 0x80E, 145 'TASK_CRASHINFO_PROC_PATH': 0x80F, 146 'TASK_CRASHINFO_PROC_CSFLAGS': 0x810, 147 'TASK_CRASHINFO_PROC_STATUS': 0x811, 148 'TASK_CRASHINFO_UID': 0x812, 149 'TASK_CRASHINFO_GID': 0x813, 150 'TASK_CRASHINFO_PROC_ARGC': 0x814, 151 'TASK_CRASHINFO_PROC_FLAGS': 0x815, 152 'TASK_CRASHINFO_CPUTYPE': 0x816, 153 'TASK_CRASHINFO_WORKQUEUEINFO': 0x817, 154 'TASK_CRASHINFO_RESPONSIBLE_PID': 0x818, 155 'TASK_CRASHINFO_DIRTY_FLAGS': 0x819, 156 'TASK_CRASHINFO_CRASHED_THREADID': 0x81A, 157 'TASK_CRASHINFO_COALITION_ID': 0x81B, 158 'EXIT_REASON_SNAPSHOT': 0x1001, 159 'EXIT_REASON_USER_DESC': 0x1002, 160 'EXIT_REASON_USER_PAYLOAD': 0x1003, 161 'EXIT_REASON_CODESIGNING_INFO': 0x1004, 162 'EXIT_REASON_WORKLOOP_ID': 0x1005, 163 'EXIT_REASON_DISPATCH_QUEUE_NO': 0x1006, 164 'KCDATA_BUFFER_BEGIN_CRASHINFO': 0xDEADF157, 165 'KCDATA_BUFFER_BEGIN_DELTA_STACKSHOT': 0xDE17A59A, 166 'KCDATA_BUFFER_BEGIN_STACKSHOT': 0x59a25807, 167 'KCDATA_BUFFER_BEGIN_COMPRESSED': 0x434f4d50, 168 'KCDATA_BUFFER_BEGIN_OS_REASON': 0x53A20900, 169 'KCDATA_BUFFER_BEGIN_XNUPOST_CONFIG': 0x1E21C09F 170} 171kcdata_type_def_rev = dict((v, k) for k, v in iter(kcdata_type_def.items())) 172 173KNOWN_TYPES_COLLECTION = {} 174 175KNOWN_TOPLEVEL_CONTAINER_TYPES = () 176 177def enum(**args): 178 return type('enum', (), args) 179 180# 181# Decode bytes as UTF-8, using surrogateescape if there are invalid UTF-8 182# sequences; see PEP-383 183# 184def BytesToString(b): 185 if isinstance(b, six.string_types): 186 return b 187 return b.decode('utf-8', errors="surrogateescape") 188 189# important keys 190SC_SLID_FIRSTMAPPING_KEY = 'sharedCacheSlidFirstMapping' 191 192# important builtin types 193KCSUBTYPE_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) 194 195 196LEGAL_OLD_STYLE_ARRAY_TYPE_NAMES = ['KCDATA_TYPE_LIBRARY_LOADINFO', 197 'KCDATA_TYPE_LIBRARY_LOADINFO64', 198 'STACKSHOT_KCTYPE_KERN_STACKFRAME', 199 'STACKSHOT_KCTYPE_USER_STACKFRAME', 200 'STACKSHOT_KCTYPE_KERN_STACKFRAME64', 201 'STACKSHOT_KCTYPE_USER_STACKFRAME64', 202 'STACKSHOT_KCTYPE_DONATING_PIDS', 203 'STACKSHOT_KCTYPE_THREAD_DELTA_SNAPSHOT'] 204 205KCDATA_FLAGS_STRUCT_PADDING_MASK = 0xf 206KCDATA_FLAGS_STRUCT_HAS_PADDING = 0x80 207 208class KCSubTypeElement(object): 209 """convert kcdata_subtype_descriptor to """ 210 _unpack_formats = (None, 'c', 'b', 'B', 'h', 'H', 'i', 'I', 'q', 'Q') 211 _ctypes = ('Unknown', 'char', 'int8_t', 'uint8_t', 'int16_t', 'uint16_t', 'int32_t', 'uint32_t', 'int64_t', 'uint64_t') 212 213 def __init__(self, st_name, st_type, st_size, st_offset=0, st_flag=0, custom_repr=None): 214 self.name = st_name 215 self.offset = st_offset 216 self.type_id = st_type 217 if st_type <= 0 or st_type > KCSUBTYPE_TYPE.KC_ST_UINT64: 218 raise ValueError("Invalid type passed %d" % st_type) 219 self.unpack_fmt = KCSubTypeElement._unpack_formats[self.type_id] 220 self.size = st_size 221 self.totalsize = st_size 222 self.count = 1 223 self.is_array_type = False 224 self.custom_JsonRepr = custom_repr 225 if (st_flag & 0x1) == 0x1: 226 self.is_array_type = True 227 self.size = st_size & 0xffff 228 self.count = (st_size >> 16) & 0xffff 229 self.totalsize = self.size * self.count 230 231 @staticmethod 232 def GetSizeForArray(el_count, el_size): 233 return ((el_count & 0xffff) << 16) | (el_size & 0xffff) 234 235 @staticmethod 236 def FromBinaryTypeData(byte_data): 237 (st_flag, st_type, st_offset, st_size, st_name) = struct.unpack_from('=BBHI32s', byte_data) 238 st_name = BytesToString(st_name).rstrip('\0') 239 return KCSubTypeElement(st_name, st_type, st_size, st_offset, st_flag) 240 241 @staticmethod 242 def FromBasicCtype(st_name, st_type, st_offset=0, legacy_size=None): 243 if st_type <= 0 or st_type > KCSUBTYPE_TYPE.KC_ST_UINT64: 244 raise ValueError("Invalid type passed %d" % st_type) 245 st_size = struct.calcsize(KCSubTypeElement._unpack_formats[st_type]) 246 st_flag = 0 247 retval = KCSubTypeElement(st_name, st_type, st_size, st_offset, st_flag, KCSubTypeElement._get_naked_element_value) 248 if legacy_size: 249 retval.legacy_size = legacy_size 250 return retval 251 252 @staticmethod 253 def FromKCSubTypeElement(other, name_override=''): 254 _copy = copy.copy(other) 255 if name_override: 256 _copy.name = name_override 257 return copy 258 259 def GetName(self): 260 return self.name 261 262 def GetTotalSize(self): 263 return self.totalsize 264 265 def GetValueAsString(self, base_data, array_pos=0): 266 v = self.GetValue(base_data, array_pos) 267 if isinstance(v, bytes): 268 return BytesToString(v) 269 return str(v) 270 271 def GetValue(self, base_data, array_pos=0): 272 return struct.unpack_from(self.unpack_fmt, base_data[self.offset + (array_pos * self.size):])[0] 273 274 @staticmethod 275 def _get_naked_element_value(elementValue, elementName): 276 return json.dumps(elementValue) 277 278 def __str__(self): 279 if self.is_array_type: 280 return '[%d,%d] %s %s[%d];' % (self.offset, self.totalsize, self.GetCTypeDesc(), self.name, self.count) 281 return '[%d,%d] %s %s;' % (self.offset, self.totalsize, self.GetCTypeDesc(), self.name) 282 283 def __repr__(self): 284 return str(self) 285 286 def GetCTypeDesc(self): 287 return KCSubTypeElement._ctypes[self.type_id] 288 289 def GetStringRepr(self, base_data): 290 if not self.is_array_type: 291 return self.GetValueAsString(base_data) 292 if self.type_id == KCSUBTYPE_TYPE.KC_ST_CHAR: 293 str_len = self.count 294 if len(base_data) < str_len: 295 str_len = len(base_data) 296 str_arr = [] 297 for i in range(str_len): 298 _v = self.GetValue(base_data, i) 299 if ord(_v) == 0: 300 break 301 str_arr.append(self.GetValueAsString(base_data, i)) 302 return json.dumps(''.join(str_arr)) 303 304 count = self.count 305 if count > len(base_data)//self.size: 306 count = len(base_data)//self.size 307 308 o = '[' + ','.join([self.GetValueAsString(base_data, i) for i in range(count)]) + ']' 309 310 return o 311 312 def GetJsonRepr(self, base_data, flags=0): 313 if (flags & (KCDATA_FLAGS_STRUCT_HAS_PADDING | KCDATA_FLAGS_STRUCT_PADDING_MASK)) != 0: 314 padding = (flags & KCDATA_FLAGS_STRUCT_PADDING_MASK) 315 if padding: 316 base_data = base_data[:-padding] 317 if self.custom_JsonRepr: 318 if self.is_array_type: 319 e_data = [self.GetValue(base_data, i) for i in range(self.count)] 320 else: 321 e_data = self.GetValue(base_data) 322 return self.custom_JsonRepr(e_data, self.name) 323 return self.GetStringRepr(base_data) 324 325 def sizeof(self): 326 return self.totalsize 327 328 def ShouldSkip(self, data): 329 return len(data) < self.offset + self.totalsize 330 331 def ShouldMerge(self): 332 return False 333 334 335class KCTypeDescription(object): 336 def __init__(self, t_type_id, t_elements=[], t_name='anon', custom_repr=None, legacy_size=None, merge=False, naked=False): 337 self.type_id = t_type_id 338 self.elements = t_elements 339 self.name = t_name 340 self.totalsize = 0 341 self.custom_JsonRepr = custom_repr 342 if legacy_size: 343 self.legacy_size = legacy_size 344 self.merge = merge 345 self.naked = naked 346 for e in self.elements: 347 self.totalsize += e.GetTotalSize() 348 349 def ValidateData(self, base_data): 350 if len(base_data) >= self.totalsize: 351 return True 352 return False 353 354 def GetTypeID(self): 355 return self.type_id 356 357 def GetName(self): 358 return self.name 359 360 def __str__(self): 361 o = '%s {\n\t' % self.name + "\n\t".join([str(e) for e in self.elements]) + '\n};' 362 return o 363 364 @staticmethod 365 def FromKCTypeDescription(other, t_type_id, t_name): 366 retval = KCTypeDescription(t_type_id, other.elements, t_name, other.custom_JsonRepr, 367 legacy_size=getattr(other, 'legacy_size', None)) 368 return retval 369 370 def ShouldMerge(self): 371 return self.merge 372 373 def GetJsonRepr(self, base_data, flags): 374 if (flags & (KCDATA_FLAGS_STRUCT_HAS_PADDING | KCDATA_FLAGS_STRUCT_PADDING_MASK)) != 0: 375 padding = (flags & KCDATA_FLAGS_STRUCT_PADDING_MASK) 376 if padding: 377 base_data = base_data[:-padding] 378 elif hasattr(self, 'legacy_size') and len(base_data) == self.legacy_size + ((-self.legacy_size) & 0xf): 379 base_data = base_data[:self.legacy_size] 380 if self.custom_JsonRepr: 381 return self.custom_JsonRepr([e.GetValue(base_data) for e in self.elements]) 382 if self.naked: 383 o = ", ".join([e.GetJsonRepr(base_data) for e in self.elements if not e.ShouldSkip(base_data)]) 384 else: 385 o = ", ".join(['"%s": %s' % (e.GetName(), e.GetJsonRepr(base_data)) for e in self.elements if not e.ShouldSkip(base_data)]) 386 if not self.merge: 387 o = '{' + o + '}' 388 return o 389 390 def sizeof(self): 391 return max(st.totalsize + st.offset for st in self.elements) 392 393 394def GetTypeNameForKey(k): 395 retval = "0x%x" % k 396 if k in KNOWN_TYPES_COLLECTION: 397 retval = KNOWN_TYPES_COLLECTION[k].GetName() 398 elif k in kcdata_type_def_rev: 399 retval = kcdata_type_def_rev[k] 400 return retval 401 402 403def GetTypeForName(n): 404 ret = 0 405 if n in kcdata_type_def: 406 ret = kcdata_type_def[n] 407 return ret 408 409 410LEGAL_OLD_STYLE_ARRAY_TYPES = list(map(GetTypeForName, LEGAL_OLD_STYLE_ARRAY_TYPE_NAMES)) 411 412kcdata_type_def_rev[GetTypeForName('KCDATA_BUFFER_BEGIN_STACKSHOT')] = 'kcdata_stackshot' 413kcdata_type_def_rev[GetTypeForName('KCDATA_BUFFER_BEGIN_DELTA_STACKSHOT')] = 'kcdata_delta_stackshot' 414kcdata_type_def_rev[GetTypeForName('KCDATA_BUFFER_BEGIN_CRASHINFO')] = 'kcdata_crashinfo' 415kcdata_type_def_rev[GetTypeForName('KCDATA_BUFFER_BEGIN_OS_REASON')] = 'kcdata_reason' 416kcdata_type_def_rev[GetTypeForName('STACKSHOT_KCCONTAINER_TASK')] = 'task_snapshots' 417kcdata_type_def_rev[GetTypeForName('STACKSHOT_KCCONTAINER_TRANSITIONING_TASK')] = 'transitioning_task_snapshots' 418kcdata_type_def_rev[GetTypeForName('STACKSHOT_KCCONTAINER_THREAD')] = 'thread_snapshots' 419kcdata_type_def_rev[GetTypeForName('STACKSHOT_KCCONTAINER_PORTLABEL')] = 'portlabels' 420kcdata_type_def_rev[GetTypeForName('KCDATA_BUFFER_BEGIN_XNUPOST_CONFIG')] = 'xnupost_testconfig' 421 422class Indent(object): 423 def __init__(self): 424 self.n = 0 425 def __call__(self, end=False): 426 if end: 427 return " " * (self.n-4) 428 else: 429 return " " * self.n 430 @contextlib.contextmanager 431 def indent(self): 432 self.n += 4 433 try: 434 yield 435 finally: 436 self.n -= 4 437 438INDENT = Indent() 439 440class KCObject(object): 441 442 def __init__(self, type_code, data, offset, flags=0): 443 444 self.i_type = type_code 445 self.i_data = data 446 self.offset = offset 447 self.i_size = len(data) 448 self.i_flags = flags 449 self.obj_collection = [] 450 self.obj = {} 451 self.is_container_type = False 452 self.is_array_type = False 453 self.is_naked_type = False 454 self.nested_kcdata = None 455 self.i_name = GetTypeNameForKey(type_code) 456 457 self.ParseData() 458 459 if self.i_type == GetTypeForName('KCDATA_TYPE_CONTAINER_BEGIN'): 460 self.__class__ = KCContainerObject 461 elif self.i_type == GetTypeForName('KCDATA_BUFFER_BEGIN_COMPRESSED'): 462 self.__class__ = KCCompressedBufferObject 463 elif self.i_type in KNOWN_TOPLEVEL_CONTAINER_TYPES: 464 self.__class__ = KCBufferObject 465 466 self.InitAfterParse() 467 468 def __str__(self): 469 return "<KCObject at 0x%x>" % self.offset 470 471 def InitAfterParse(self): 472 pass 473 474 @staticmethod 475 def FromKCItem(kcitem): 476 return KCObject(kcitem.i_type, kcitem.i_data, kcitem.i_offset, kcitem.i_flags) 477 478 def IsContainerEnd(self): 479 return self.i_type == GetTypeForName('KCDATA_TYPE_CONTAINER_END') 480 481 def IsBufferEnd(self): 482 return self.i_type == GetTypeForName('KCDATA_TYPE_BUFFER_END') 483 484 def IsArray(self): 485 return self.is_array_type 486 487 def ShouldMerge(self): 488 if self.nested_kcdata: 489 return True 490 elif not self.is_array_type and self.i_type in KNOWN_TYPES_COLLECTION: 491 return KNOWN_TYPES_COLLECTION[self.i_type].ShouldMerge() 492 else: 493 return False 494 495 def GetJsonRepr(self): 496 if self.is_array_type: 497 return '[' + ', '.join([i.GetJsonRepr() for i in self.obj_collection]) + ']' 498 if self.i_type in KNOWN_TYPES_COLLECTION: 499 return KNOWN_TYPES_COLLECTION[self.i_type].GetJsonRepr(self.i_data, self.i_flags) 500 if self.is_naked_type: 501 return json.dumps(self.obj) 502 if self.nested_kcdata: 503 return self.nested_kcdata.GetJsonRepr() 504 505 raise NotImplementedError("Broken GetJsonRepr implementation") 506 507 def ParseData(self): 508 509 510 if self.i_type == GetTypeForName('KCDATA_TYPE_CONTAINER_BEGIN'): 511 self.obj['uniqID'] = self.i_flags 512 self.i_name = str(self.obj['uniqID']) 513 self.obj['typeID'] = struct.unpack_from('I', self.i_data)[0] 514 logging.info("0x%08x: %sCONTAINER: %s(%x)" % (self.offset, INDENT(), GetTypeNameForKey(self.obj['typeID']), self.i_flags)) 515 516 elif self.i_type in (KNOWN_TOPLEVEL_CONTAINER_TYPES): 517 self.obj['uniqID'] = self.i_name 518 self.obj['typeID'] = self.i_type 519 logging.info("0x%08x: %s%s" % (self.offset, INDENT(), self.i_name)) 520 521 elif self.i_type == GetTypeForName('KCDATA_TYPE_CONTAINER_END'): 522 self.obj['uniqID'] = self.i_flags 523 logging.info("0x%08x: %sEND" % (self.offset, INDENT(end=True))) 524 525 elif self.i_type == GetTypeForName('KCDATA_TYPE_BUFFER_END'): 526 self.obj = '' 527 logging.info("0x%08x: %sEND_BUFFER" % (self.offset, INDENT(end=True))) 528 529 elif self.i_type == GetTypeForName('KCDATA_TYPE_UINT32_DESC'): 530 self.is_naked_type = True 531 u_d = struct.unpack_from('32sI', self.i_data) 532 self.i_name = BytesToString(u_d[0]).rstrip('\0') 533 self.obj = u_d[1] 534 logging.info("0x%08x: %s%s" % (self.offset, INDENT(), self.i_name)) 535 536 elif self.i_type == GetTypeForName('KCDATA_TYPE_UINT64_DESC'): 537 self.is_naked_type = True 538 u_d = struct.unpack_from('32sQ', self.i_data) 539 self.i_name = BytesToString(u_d[0]).rstrip('\0') 540 self.obj = u_d[1] 541 logging.info("0x%08x: %s%s" % (self.offset, INDENT(), self.i_name)) 542 543 elif self.i_type == GetTypeForName('KCDATA_TYPE_TYPEDEFINITION'): 544 self.is_naked_type = True 545 u_d = struct.unpack_from('II32s', self.i_data) 546 self.obj['name'] = BytesToString(u_d[2]).split(chr(0))[0] 547 self.i_name = "typedef[%s]" % self.obj['name'] 548 self.obj['typeID'] = u_d[0] 549 self.obj['numOfFields'] = u_d[1] 550 element_arr = [] 551 for i in range(u_d[1]): 552 e = KCSubTypeElement.FromBinaryTypeData(self.i_data[40+(i*40):]) 553 element_arr.append(e) 554 type_desc = KCTypeDescription(u_d[0], element_arr, self.obj['name']) 555 self.obj['fields'] = [str(e) for e in element_arr] 556 KNOWN_TYPES_COLLECTION[type_desc.GetTypeID()] = type_desc 557 logging.info("0x%08x: %s%s" % (self.offset, INDENT(), self.i_name)) 558 559 elif self.i_type == GetTypeForName('KCDATA_TYPE_ARRAY'): 560 self.is_array_type = True 561 e_t = (self.i_flags >> 32) & 0xffffffff 562 if e_t not in LEGAL_OLD_STYLE_ARRAY_TYPES: 563 raise Exception("illegal old-style array type: %s (0x%x)" % (GetTypeNameForKey(e_t), e_t)) 564 e_c = self.i_flags & 0xffffffff 565 e_s = KNOWN_TYPES_COLLECTION[e_t].legacy_size 566 if e_s * e_c > self.i_size: 567 raise Exception("array too small for its count") 568 self.obj['typeID'] = e_t 569 self.i_name = GetTypeNameForKey(e_t) 570 self.i_type = e_t 571 self.obj['numOfElements'] = e_c 572 self.obj['sizeOfElement'] = e_s 573 logging.info("0x%08x: %sARRAY: %s" % (self.offset, INDENT(), self.i_name)) 574 #populate the array here by recursive creation of KCObject 575 with INDENT.indent(): 576 for _i in range(e_c): 577 _o = KCObject(e_t, self.i_data[(_i * e_s):(_i * e_s) + e_s], self.offset + _i*e_s) 578 self.obj_collection.append(_o) 579 580 elif self.i_type >= GetTypeForName('KCDATA_TYPE_ARRAY_PAD0') and self.i_type <= GetTypeForName('KCDATA_TYPE_ARRAY_PADf'): 581 self.is_array_type = True 582 e_t = (self.i_flags >> 32) & 0xffffffff 583 e_c = self.i_flags & 0xffffffff 584 e_s = (self.i_size - (self.i_type & 0xf)) // e_c if e_c != 0 else None 585 self.obj['typeID'] = e_t 586 self.i_name = GetTypeNameForKey(e_t) 587 self.i_type = e_t 588 self.obj['numOfElements'] = e_c 589 self.obj['sizeOfElement'] = e_s 590 logging.info("0x%08x: %sARRAY: %s" % (self.offset, INDENT(), self.i_name)) 591 #populate the array here by recursive creation of KCObject 592 with INDENT.indent(): 593 for _i in range(e_c): 594 _o = KCObject(e_t, self.i_data[(_i * e_s):(_i * e_s) + e_s], self.offset + _i*e_s) 595 self.obj_collection.append(_o) 596 597 elif self.i_type == GetTypeForName('KCDATA_TYPE_NESTED_KCDATA'): 598 logging.info("0x%08x: %sNESTED_KCDATA" % (self.offset, INDENT())) 599 with INDENT.indent(): 600 nested_iterator = kcdata_item_iterator(self.i_data[:self.i_size]) 601 nested_buffer = KCObject.FromKCItem(six.next(nested_iterator)) 602 if not isinstance(nested_buffer, KCBufferObject): 603 raise Exception("nested buffer isn't a KCBufferObject") 604 nested_buffer.ReadItems(nested_iterator) 605 self.nested_kcdata = nested_buffer 606 607 elif self.i_type in KNOWN_TYPES_COLLECTION: 608 self.i_name = KNOWN_TYPES_COLLECTION[self.i_type].GetName() 609 self.is_naked_type = True 610 logging.info("0x%08x: %s%s" % (self.offset, INDENT(), self.i_name)) 611 else: 612 self.is_naked_type = True 613 #self.obj = "data of len %d" % len(self.i_data) 614 #self.obj = ''.join(["%x" % ki for ki in struct.unpack('%dB' % len(self.i_data), self.i_data)]) 615 if isinstance(self.i_data, six.string_types): 616 self.obj = list(map(ord, BytesToString(self.i_data))) 617 else: 618 self.obj = [i for i in self.i_data] 619 logging.info("0x%08x: %s%s" % (self.offset, INDENT(), self.i_name)) 620 621 622class KCContainerObject(KCObject): 623 def __init__(self, *args, **kwargs): 624 assert False 625 626 def InitAfterParse(self): 627 self.obj_container_dict = {} 628 self.obj_nested_objs = {} 629 630 def ShouldMerge(self): 631 return True 632 633 def GetJsonRepr(self): 634 # o = '"%s"' % self.obj['uniqID'] + ' : { "typeID" : %d ,' % self.obj['typeID'] 635 o = '"%s"' % self.obj['uniqID'] + ' : { ' 636 for (k, v) in self.obj_container_dict.items(): 637 if v.ShouldMerge(): 638 o += v.GetJsonRepr() + "," 639 else: 640 o += ' "%s" : ' % k + v.GetJsonRepr() + "," 641 642 for (k, v) in self.obj_nested_objs.items(): 643 o += '"%s" : {' % k + ",".join([vi.GetJsonRepr() for vi in v.values()]) + "} ," 644 645 o = o.rstrip(',') + "}" 646 647 return o 648 649 def AddObject(self, kco): 650 assert not kco.IsContainerEnd() 651 if isinstance(kco, KCContainerObject): 652 type_name = GetTypeNameForKey(kco.obj['typeID']) 653 if type_name not in self.obj_nested_objs: 654 self.obj_nested_objs[type_name] = {} 655 self.obj_nested_objs[type_name][kco.i_name] = kco 656 return 657 if kco.i_name in self.obj_container_dict: 658 if kco.IsArray() and self.obj_container_dict[kco.i_name].IsArray(): 659 self.obj_container_dict[kco.i_name].obj_collection.extend( kco.obj_collection ) 660 else: 661 self.obj_container_dict[kco.i_name] = kco 662 663 def IsEndMarker(self, o): 664 if not o.IsContainerEnd(): 665 return False 666 if o.i_flags != self.i_flags: 667 raise Exception("container end marker doesn't match") 668 return True 669 670 no_end_message = "could not find container end marker" 671 672 def ReadItems(self, iterator): 673 found_end = False 674 with INDENT.indent(): 675 for i in iterator: 676 o = KCObject.FromKCItem(i) 677 if self.IsEndMarker(o): 678 found_end = True 679 break 680 if o.IsBufferEnd(): 681 break 682 if isinstance(o, KCContainerObject): 683 o.ReadItems(iterator) 684 self.AddObject(o) 685 if not found_end: 686 if G.accept_incomplete_data: 687 if not G.data_was_incomplete: 688 print("kcdata.py WARNING: data is incomplete!", file=sys.stderr) 689 G.data_was_incomplete = True 690 else: 691 raise Exception(self.no_end_message) 692 693 694 695class KCBufferObject(KCContainerObject): 696 697 def IsEndMarker(self,o): 698 if o.IsContainerEnd(): 699 raise Exception("container end marker at the toplevel") 700 return o.IsBufferEnd() 701 702 no_end_message = "could not find buffer end marker" 703 704class KCCompressedBufferObject(KCContainerObject): 705 706 def ReadItems(self, iterator): 707 self.header = dict() 708 with INDENT.indent(): 709 for i in iterator: 710 o = KCObject.FromKCItem(i) 711 if self.IsEndMarker(o): 712 self.compressed_type = o.i_type 713 self.blob_start = o.offset + 16 714 break 715 o.ParseData() 716 self.header[o.i_name] = o.obj 717 718 def IsEndMarker(self, o): 719 return o.i_type in KNOWN_TOPLEVEL_CONTAINER_TYPES 720 721 def GetCompressedBlob(self, data): 722 if self.header['kcd_c_type'] != 1: 723 raise NotImplementedError 724 blob = data[self.blob_start:self.blob_start+self.header['kcd_c_totalout']] 725 if len(blob) != self.header['kcd_c_totalout']: 726 raise ValueError 727 return blob 728 729 def Decompress(self, data): 730 start_marker = struct.pack('<IIII', self.compressed_type, 0, 0, 0) 731 end_marker = struct.pack('<IIII', GetTypeForName('KCDATA_TYPE_BUFFER_END'), 0, 0, 0) 732 decompressed = zlib.decompress(self.GetCompressedBlob(data)) 733 if len(decompressed) != self.header['kcd_c_totalin']: 734 raise ValueError("length of decompressed: %d vs expected %d" % (len(decompressed), self.header['kcd_c_totalin'])) 735 alignbytes = b'\x00' * (-len(decompressed) % 16) 736 return start_marker + decompressed + alignbytes + end_marker 737 738 739class KCData_item: 740 """ a basic kcdata_item type object. 741 """ 742 header_size = 16 # (uint32_t + uint32_t + uint64_t) 743 744 def __init__(self, item_type, item_size, item_flags, item_data): 745 self.i_type = item_type 746 self.i_size = item_size 747 self.i_flags = item_flags 748 self.i_data = item_data 749 self.i_offset = None 750 751 def __init__(self, barray, pos=0): 752 """ create an object by parsing data from bytes array 753 returns : obj - if data is readable 754 raises ValueError if something is not ok. 755 """ 756 self.i_type = struct.unpack('I', barray[pos:pos+4])[0] # int.from_bytes(barray[pos:pos+4]) 757 self.i_size = struct.unpack('I', barray[pos+4:pos+8])[0] # int.from_bytes(barray[pos+4:pos+8]) 758 self.i_flags = struct.unpack('Q', barray[pos+8:pos+16])[0] # int.from_bytes(barray[pos+8:pos+16]) 759 self.i_data = barray[pos+16: (pos + 16 + self.i_size)] 760 self.i_offset = pos 761 762 def __len__(self): 763 return self.i_size + KCData_item.header_size 764 765 def GetHeaderDescription(self): 766 outs = "type: 0x%x size: 0x%x flags: 0x%x (%s)" % (self.i_type, self.i_size, self.i_flags, GetTypeNameForKey(self.i_type)) 767 if not self.i_offset is None: 768 outs = "pos: 0x%x" % self.i_offset + outs 769 return outs 770 771 def __str__(self): 772 return self.GetHeaderDescription() 773 774def kcdata_item_iterator(data): 775 file_len = len(data) 776 curpos = 0 777 while curpos < file_len: 778 item = KCData_item(data, curpos) 779 yield item 780 curpos += len(item) 781 782def _get_data_element(elementValues): 783 return json.dumps(elementValues[-1]) 784 785KNOWN_TOPLEVEL_CONTAINER_TYPES = list(map(GetTypeForName, ('KCDATA_BUFFER_BEGIN_COMPRESSED', 'KCDATA_BUFFER_BEGIN_CRASHINFO', 'KCDATA_BUFFER_BEGIN_STACKSHOT', 'KCDATA_BUFFER_BEGIN_DELTA_STACKSHOT', 'KCDATA_BUFFER_BEGIN_OS_REASON','KCDATA_BUFFER_BEGIN_XNUPOST_CONFIG'))) 786 787KNOWN_TYPES_COLLECTION[GetTypeForName('KCDATA_TYPE_UINT32_DESC')] = KCTypeDescription(GetTypeForName('KCDATA_TYPE_UINT32_DESC'), ( 788 KCSubTypeElement('desc', KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(32, 1), 0, 1), 789 KCSubTypeElement('data', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 32, 0) 790), 791 'KCDATA_TYPE_UINT32_DESC', 792 _get_data_element 793) 794 795KNOWN_TYPES_COLLECTION[GetTypeForName('KCDATA_TYPE_UINT64_DESC')] = KCTypeDescription(GetTypeForName('KCDATA_TYPE_UINT64_DESC'), ( 796 KCSubTypeElement('desc', KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(32, 1), 0, 1), 797 KCSubTypeElement('data', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 32, 0) 798), 799 'KCDATA_TYPE_UINT64_DESC', 800 _get_data_element 801) 802 803KNOWN_TYPES_COLLECTION[GetTypeForName('KCDATA_TYPE_TIMEBASE')] = KCTypeDescription(GetTypeForName('KCDATA_TYPE_TIMEBASE'), ( 804 KCSubTypeElement('numer', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 0, 0), 805 KCSubTypeElement('denom', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4, 0) 806), 807 'mach_timebase_info' 808) 809 810 811STACKSHOT_IO_NUM_PRIORITIES = 4 812KNOWN_TYPES_COLLECTION[0x901] = KCTypeDescription(0x901, ( 813 KCSubTypeElement.FromBasicCtype('ss_disk_reads_count', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 814 KCSubTypeElement.FromBasicCtype('ss_disk_reads_size', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 815 KCSubTypeElement.FromBasicCtype('ss_disk_writes_count', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 816 KCSubTypeElement.FromBasicCtype('ss_disk_writes_size', KCSUBTYPE_TYPE.KC_ST_UINT64, 24), 817 KCSubTypeElement('ss_io_priority_count', KCSUBTYPE_TYPE.KC_ST_UINT64, KCSubTypeElement.GetSizeForArray(STACKSHOT_IO_NUM_PRIORITIES, 8), 32, 1), 818 KCSubTypeElement('ss_io_priority_size', KCSUBTYPE_TYPE.KC_ST_UINT64, KCSubTypeElement.GetSizeForArray(STACKSHOT_IO_NUM_PRIORITIES, 8), 32 + (STACKSHOT_IO_NUM_PRIORITIES * 8), 1), 819 KCSubTypeElement.FromBasicCtype('ss_paging_count', KCSUBTYPE_TYPE.KC_ST_UINT64, 32 + 2 * (STACKSHOT_IO_NUM_PRIORITIES * 8)), 820 KCSubTypeElement.FromBasicCtype('ss_paging_size', KCSUBTYPE_TYPE.KC_ST_UINT64, 40 + 2 * (STACKSHOT_IO_NUM_PRIORITIES * 8)), 821 KCSubTypeElement.FromBasicCtype('ss_non_paging_count', KCSUBTYPE_TYPE.KC_ST_UINT64, 48 + 2 * (STACKSHOT_IO_NUM_PRIORITIES * 8)), 822 KCSubTypeElement.FromBasicCtype('ss_non_paging_size', KCSUBTYPE_TYPE.KC_ST_UINT64, 56 + 2 * (STACKSHOT_IO_NUM_PRIORITIES * 8)), 823 KCSubTypeElement.FromBasicCtype('ss_data_count', KCSUBTYPE_TYPE.KC_ST_UINT64, 64 + 2 * (STACKSHOT_IO_NUM_PRIORITIES * 8)), 824 KCSubTypeElement.FromBasicCtype('ss_data_size', KCSUBTYPE_TYPE.KC_ST_UINT64, 72 + 2 * (STACKSHOT_IO_NUM_PRIORITIES * 8)), 825 KCSubTypeElement.FromBasicCtype('ss_metadata_count', KCSUBTYPE_TYPE.KC_ST_UINT64, 80 + 2 * (STACKSHOT_IO_NUM_PRIORITIES * 8)), 826 KCSubTypeElement.FromBasicCtype('ss_metadata_size', KCSUBTYPE_TYPE.KC_ST_UINT64, 88 + 2 * (STACKSHOT_IO_NUM_PRIORITIES * 8)) 827), 828 'io_statistics' 829) 830 831KNOWN_TYPES_COLLECTION[0x902] = KCTypeDescription(0x902, ( 832 KCSubTypeElement('snapshot_magic', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 0, 0), 833 KCSubTypeElement('free_pages', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 1, 0), 834 KCSubTypeElement('active_pages', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 2, 0), 835 KCSubTypeElement('inactive_pages', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 3, 0), 836 KCSubTypeElement('purgeable_pages', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 4, 0), 837 KCSubTypeElement('wired_pages', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 5, 0), 838 KCSubTypeElement('speculative_pages', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 6, 0), 839 KCSubTypeElement('throttled_pages', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 7, 0), 840 KCSubTypeElement('filebacked_pages', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 8, 0), 841 KCSubTypeElement('compressions', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 9, 0), 842 KCSubTypeElement('decompressions', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 10, 0), 843 KCSubTypeElement('compressor_size', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 11, 0), 844 KCSubTypeElement('busy_buffer_count', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 4 * 12, 0), 845 KCSubTypeElement('pages_wanted', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 13, 0), 846 KCSubTypeElement('pages_reclaimed', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 4 * 14, 0), 847 KCSubTypeElement('pages_wanted_reclaimed_valid', KCSUBTYPE_TYPE.KC_ST_UINT8, 1, 4 * 15, 0) 848), 849 'mem_and_io_snapshot' 850) 851 852 853KNOWN_TYPES_COLLECTION[0x930] = KCTypeDescription(0x930, ( 854 KCSubTypeElement.FromBasicCtype('tts_unique_pid', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 855 KCSubTypeElement.FromBasicCtype('tts_ss_flags', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 856 KCSubTypeElement.FromBasicCtype('tts_transition_type', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 857 KCSubTypeElement.FromBasicCtype('tts_pid', KCSUBTYPE_TYPE.KC_ST_INT32, 24), 858 KCSubTypeElement('tts_p_comm', KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(32, 1), 28, 1) 859), 860 'transitioning_task_snapshot' 861) 862 863KNOWN_TYPES_COLLECTION[0x905] = KCTypeDescription(0x905, ( 864 KCSubTypeElement.FromBasicCtype('ts_unique_pid', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 865 KCSubTypeElement.FromBasicCtype('ts_ss_flags', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 866 KCSubTypeElement.FromBasicCtype('ts_user_time_in_terminated_thre', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 867 KCSubTypeElement.FromBasicCtype('ts_system_time_in_terminated_th', KCSUBTYPE_TYPE.KC_ST_UINT64, 24), 868 KCSubTypeElement.FromBasicCtype('ts_p_start_sec', KCSUBTYPE_TYPE.KC_ST_UINT64, 32), 869 KCSubTypeElement.FromBasicCtype('ts_task_size', KCSUBTYPE_TYPE.KC_ST_UINT64, 40), 870 KCSubTypeElement.FromBasicCtype('ts_max_resident_size', KCSUBTYPE_TYPE.KC_ST_UINT64, 48), 871 KCSubTypeElement.FromBasicCtype('ts_suspend_count', KCSUBTYPE_TYPE.KC_ST_UINT32, 56), 872 KCSubTypeElement.FromBasicCtype('ts_faults', KCSUBTYPE_TYPE.KC_ST_UINT32, 60), 873 KCSubTypeElement.FromBasicCtype('ts_pageins', KCSUBTYPE_TYPE.KC_ST_UINT32, 64), 874 KCSubTypeElement.FromBasicCtype('ts_cow_faults', KCSUBTYPE_TYPE.KC_ST_UINT32, 68), 875 KCSubTypeElement.FromBasicCtype('ts_was_throttled', KCSUBTYPE_TYPE.KC_ST_UINT32, 72), 876 KCSubTypeElement.FromBasicCtype('ts_did_throttle', KCSUBTYPE_TYPE.KC_ST_UINT32, 76), 877 KCSubTypeElement.FromBasicCtype('ts_latency_qos', KCSUBTYPE_TYPE.KC_ST_UINT32, 80), 878 KCSubTypeElement.FromBasicCtype('ts_pid', KCSUBTYPE_TYPE.KC_ST_INT32, 84), 879 KCSubTypeElement('ts_p_comm', KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(32, 1), 88, 1) 880), 881 'task_snapshot' 882) 883 884KNOWN_TYPES_COLLECTION[0x906] = KCTypeDescription(0x906, ( 885 KCSubTypeElement.FromBasicCtype('ths_thread_id', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 886 KCSubTypeElement.FromBasicCtype('ths_wait_event', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 887 KCSubTypeElement.FromBasicCtype('ths_continuation', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 888 KCSubTypeElement.FromBasicCtype('ths_total_syscalls', KCSUBTYPE_TYPE.KC_ST_UINT64, 24), 889 KCSubTypeElement.FromBasicCtype('ths_voucher_identifier', KCSUBTYPE_TYPE.KC_ST_UINT64, 32), 890 KCSubTypeElement.FromBasicCtype('ths_dqserialnum', KCSUBTYPE_TYPE.KC_ST_UINT64, 40), 891 KCSubTypeElement.FromBasicCtype('ths_user_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 48), 892 KCSubTypeElement.FromBasicCtype('ths_sys_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 56), 893 KCSubTypeElement.FromBasicCtype('ths_ss_flags', KCSUBTYPE_TYPE.KC_ST_UINT64, 64), 894 KCSubTypeElement.FromBasicCtype('ths_last_run_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 72), 895 KCSubTypeElement.FromBasicCtype('ths_last_made_runnable_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 80), 896 KCSubTypeElement.FromBasicCtype('ths_state', KCSUBTYPE_TYPE.KC_ST_UINT32, 88), 897 KCSubTypeElement.FromBasicCtype('ths_sched_flags', KCSUBTYPE_TYPE.KC_ST_UINT32, 92), 898 KCSubTypeElement.FromBasicCtype('ths_base_priority', KCSUBTYPE_TYPE.KC_ST_INT16, 96), 899 KCSubTypeElement.FromBasicCtype('ths_sched_priority', KCSUBTYPE_TYPE.KC_ST_INT16, 98), 900 KCSubTypeElement.FromBasicCtype('ths_eqos', KCSUBTYPE_TYPE.KC_ST_UINT8, 100), 901 KCSubTypeElement.FromBasicCtype('ths_rqos', KCSUBTYPE_TYPE.KC_ST_UINT8, 101), 902 KCSubTypeElement.FromBasicCtype('ths_rqos_override', KCSUBTYPE_TYPE.KC_ST_UINT8, 102), 903 KCSubTypeElement.FromBasicCtype('ths_io_tier', KCSUBTYPE_TYPE.KC_ST_UINT8, 103), 904 KCSubTypeElement.FromBasicCtype('ths_thread_t', KCSUBTYPE_TYPE.KC_ST_UINT64, 104), 905 KCSubTypeElement.FromBasicCtype('ths_requested_policy', KCSUBTYPE_TYPE.KC_ST_UINT64, 112), 906 KCSubTypeElement.FromBasicCtype('ths_effective_policy', KCSUBTYPE_TYPE.KC_ST_UINT64, 120), 907), 908 'thread_snapshot', 909 legacy_size = 0x68 910) 911 912KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_THREAD_DISPATCH_QUEUE_LABEL')] = KCSubTypeElement('dispatch_queue_label', KCSUBTYPE_TYPE.KC_ST_CHAR, 913 KCSubTypeElement.GetSizeForArray(64, 1), 0, 1) 914 915KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_THREAD_DELTA_SNAPSHOT')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_THREAD_DELTA_SNAPSHOT'), ( 916 KCSubTypeElement.FromBasicCtype('tds_thread_id', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 917 KCSubTypeElement.FromBasicCtype('tds_voucher_identifier', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 918 KCSubTypeElement.FromBasicCtype('tds_ss_flags', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 919 KCSubTypeElement.FromBasicCtype('tds_last_made_runnable_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 24), 920 KCSubTypeElement.FromBasicCtype('tds_state', KCSUBTYPE_TYPE.KC_ST_UINT32, 32), 921 KCSubTypeElement.FromBasicCtype('tds_sched_flags', KCSUBTYPE_TYPE.KC_ST_UINT32, 36), 922 KCSubTypeElement.FromBasicCtype('tds_base_priority', KCSUBTYPE_TYPE.KC_ST_INT16, 40), 923 KCSubTypeElement.FromBasicCtype('tds_sched_priority', KCSUBTYPE_TYPE.KC_ST_INT16, 42), 924 KCSubTypeElement.FromBasicCtype('tds_eqos', KCSUBTYPE_TYPE.KC_ST_UINT8, 44), 925 KCSubTypeElement.FromBasicCtype('tds_rqos', KCSUBTYPE_TYPE.KC_ST_UINT8, 45), 926 KCSubTypeElement.FromBasicCtype('tds_rqos_override', KCSUBTYPE_TYPE.KC_ST_UINT8, 46), 927 KCSubTypeElement.FromBasicCtype('tds_io_tier', KCSUBTYPE_TYPE.KC_ST_UINT8, 47), 928 KCSubTypeElement.FromBasicCtype('tds_requested_policy', KCSUBTYPE_TYPE.KC_ST_UINT64, 48), 929 KCSubTypeElement.FromBasicCtype('tds_effective_policy', KCSUBTYPE_TYPE.KC_ST_UINT64, 56), 930), 931 'thread_delta_snapshot', 932 legacy_size = 48 933) 934 935KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_TASK_DELTA_SNAPSHOT')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_TASK_DELTA_SNAPSHOT'), ( 936 KCSubTypeElement.FromBasicCtype('tds_unique_pid', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 937 KCSubTypeElement.FromBasicCtype('tds_ss_flags', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 938 KCSubTypeElement.FromBasicCtype('tds_user_time_in_terminated_thr', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 939 KCSubTypeElement.FromBasicCtype('tds_system_time_in_terminated_t', KCSUBTYPE_TYPE.KC_ST_UINT64, 24), 940 KCSubTypeElement.FromBasicCtype('tds_task_size', KCSUBTYPE_TYPE.KC_ST_UINT64, 32), 941 KCSubTypeElement.FromBasicCtype('tds_max_resident_size', KCSUBTYPE_TYPE.KC_ST_UINT64, 40), 942 KCSubTypeElement.FromBasicCtype('tds_suspend_count', KCSUBTYPE_TYPE.KC_ST_UINT32, 48), 943 KCSubTypeElement.FromBasicCtype('tds_faults', KCSUBTYPE_TYPE.KC_ST_UINT32, 52), 944 KCSubTypeElement.FromBasicCtype('tds_pageins', KCSUBTYPE_TYPE.KC_ST_UINT32, 56), 945 KCSubTypeElement.FromBasicCtype('tds_cow_faults', KCSUBTYPE_TYPE.KC_ST_UINT32, 60), 946 KCSubTypeElement.FromBasicCtype('tds_was_throttled', KCSUBTYPE_TYPE.KC_ST_UINT32, 64), 947 KCSubTypeElement.FromBasicCtype('tds_did_throttle', KCSUBTYPE_TYPE.KC_ST_UINT32, 68), 948 KCSubTypeElement.FromBasicCtype('tds_latency_qos', KCSUBTYPE_TYPE.KC_ST_UINT32, 72), 949), 950 'task_delta_snapshot' 951) 952 953 954KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_THREAD_NAME')] = KCSubTypeElement('pth_name', KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(64, 1), 0, 1) 955 956KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_SYS_SHAREDCACHE_LAYOUT')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_SYS_SHAREDCACHE_LAYOUT'), ( 957 KCSubTypeElement('imageLoadAddress', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0), 958 KCSubTypeElement('imageUUID', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(16, 1), 8, 1) 959), 960 'system_shared_cache_layout' 961) 962 963KNOWN_TYPES_COLLECTION[GetTypeForName('KCDATA_TYPE_LIBRARY_LOADINFO64')] = KCTypeDescription(GetTypeForName('KCDATA_TYPE_LIBRARY_LOADINFO64'), ( 964 KCSubTypeElement('imageLoadAddress', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0), 965 KCSubTypeElement('imageUUID', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(16, 1), 8, 1) 966), 967 'dyld_load_info', 968 legacy_size = 24 969) 970 971KNOWN_TYPES_COLLECTION[GetTypeForName('KCDATA_TYPE_LIBRARY_LOADINFO')] = KCTypeDescription(GetTypeForName('KCDATA_TYPE_LIBRARY_LOADINFO'), ( 972 KCSubTypeElement('imageLoadAddress', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 0, 0), 973 KCSubTypeElement('imageUUID', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(16, 1), 4, 1) 974), 975 'dyld_load_info', 976 legacy_size = 20 977) 978 979KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_LOADINFO64_TEXT_EXEC')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_LOADINFO64_TEXT_EXEC'), ( 980 KCSubTypeElement('imageLoadAddress', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0), 981 KCSubTypeElement('imageUUID', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(16, 1), 8, 1), 982), 983 'dyld_load_info_text_exec' 984) 985 986KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_AOTCACHE_LOADINFO')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_AOTCACHE_LOADINFO'), ( 987 KCSubTypeElement('x86SlidBaseAddress', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0), 988 KCSubTypeElement('x86UUID', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(16, 1), 8, 1), 989 KCSubTypeElement('aotSlidBaseAddress', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 24, 0), 990 KCSubTypeElement('aotUUID', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(16, 1), 32, 1), 991), 992 'dyld_aot_cache_uuid_info' 993) 994 995KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_SHAREDCACHE_LOADINFO')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_SHAREDCACHE_LOADINFO'), ( 996 KCSubTypeElement('imageLoadAddress', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0), 997 KCSubTypeElement('imageUUID', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(16, 1), 8, 1), 998 KCSubTypeElement('imageSlidBaseAddress', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 24, 0), 999 KCSubTypeElement('sharedCacheSlidFirstMapping', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 32, 0), 1000), 1001 'shared_cache_dyld_load_info', 1002 legacy_size = 0x18 1003) 1004 1005KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_KERNELCACHE_LOADINFO')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_KERNELCACHE_LOADINFO'), ( 1006 KCSubTypeElement('imageLoadAddress', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0), 1007 KCSubTypeElement('imageUUID', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(16, 1), 8, 1), 1008), 1009 'kernelcache_load_info' 1010) 1011 1012KNOWN_TYPES_COLLECTION[0x33] = KCSubTypeElement('mach_absolute_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0, KCSubTypeElement._get_naked_element_value) 1013KNOWN_TYPES_COLLECTION[0x907] = KCSubTypeElement.FromBasicCtype('donating_pids', KCSUBTYPE_TYPE.KC_ST_INT32, legacy_size=4) 1014 1015KNOWN_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) 1016 1017KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKFRAME')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKFRAME'), ( 1018 KCSubTypeElement.FromBasicCtype('lr', KCSUBTYPE_TYPE.KC_ST_UINT32), 1019 KCSubTypeElement.FromBasicCtype('sp', KCSUBTYPE_TYPE.KC_ST_UINT32, 4) 1020), 1021 'kernel_stack_frames', 1022 legacy_size = 8 1023) 1024 1025KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKLR')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKLR'), ( 1026 KCSubTypeElement.FromBasicCtype('lr', KCSUBTYPE_TYPE.KC_ST_UINT32), 1027), 1028 'kernel_stack_frames' 1029) 1030 1031 1032KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_USER_STACKFRAME')] = KCTypeDescription.FromKCTypeDescription( 1033 KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKFRAME')], 1034 GetTypeForName('STACKSHOT_KCTYPE_USER_STACKFRAME'), 1035 'user_stack_frames' 1036) 1037 1038KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_USER_STACKLR')] = KCTypeDescription.FromKCTypeDescription( 1039 KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKLR')], 1040 GetTypeForName('STACKSHOT_KCTYPE_USER_STACKLR'), 1041 'user_stack_frames' 1042) 1043 1044KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKFRAME64')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKFRAME64'), ( 1045 KCSubTypeElement.FromBasicCtype('lr', KCSUBTYPE_TYPE.KC_ST_UINT64), 1046 KCSubTypeElement.FromBasicCtype('sp', KCSUBTYPE_TYPE.KC_ST_UINT64, 8) 1047), 1048 'kernel_stack_frames', 1049 legacy_size = 16 1050) 1051 1052KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_USER_STACKFRAME64')] = KCTypeDescription.FromKCTypeDescription( 1053 KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKFRAME64')], 1054 GetTypeForName('STACKSHOT_KCTYPE_USER_STACKFRAME64'), 1055 'user_stack_frames' 1056) 1057 1058 1059KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKLR64')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKLR64'), ( 1060 KCSubTypeElement.FromBasicCtype('lr', KCSUBTYPE_TYPE.KC_ST_UINT64), 1061), 1062 'kernel_stack_frames' 1063) 1064 1065KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_USER_STACKLR64')] = KCTypeDescription.FromKCTypeDescription( 1066 KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKLR64')], 1067 GetTypeForName('STACKSHOT_KCTYPE_USER_STACKLR64'), 1068 'user_stack_frames' 1069) 1070 1071KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_USER_ASYNC_START_INDEX')] = KCSubTypeElement.FromBasicCtype('user_async_start_index', KCSUBTYPE_TYPE.KC_ST_UINT32) 1072 1073KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_USER_ASYNC_STACKLR64')] = KCTypeDescription.FromKCTypeDescription( 1074 KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_KERN_STACKLR64')], 1075 GetTypeForName('STACKSHOT_KCTYPE_USER_ASYNC_STACKLR64'), 1076 'user_async_stack_frames' 1077) 1078 1079KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_NONRUNNABLE_TIDS')] = KCSubTypeElement.FromBasicCtype('nonrunnable_threads', KCSUBTYPE_TYPE.KC_ST_INT64) 1080 1081KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_NONRUNNABLE_TASKS')] = KCSubTypeElement.FromBasicCtype('nonrunnable_tasks', KCSUBTYPE_TYPE.KC_ST_INT64) 1082 1083KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_OSVERSION')] = KCSubTypeElement('osversion', KCSUBTYPE_TYPE.KC_ST_CHAR, 1084 KCSubTypeElement.GetSizeForArray(256, 1), 0, 1) 1085 1086KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_BOOTARGS')] = KCSubTypeElement('boot_args', KCSUBTYPE_TYPE.KC_ST_CHAR, 1087 KCSubTypeElement.GetSizeForArray(256, 1), 0, 1) 1088 1089KNOWN_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) 1090 1091KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_THREAD_POLICY_VERSION')] = KCSubTypeElement('thread_policy_version', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 0, 0, KCSubTypeElement._get_naked_element_value) 1092 1093KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_JETSAM_LEVEL')] = KCSubTypeElement('jetsam_level', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 0, 0, KCSubTypeElement._get_naked_element_value) 1094 1095KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_DELTA_SINCE_TIMESTAMP')] = KCSubTypeElement("stackshot_delta_since_timestamp", KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0, KCSubTypeElement._get_naked_element_value) 1096 1097KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_STACKSHOT_FAULT_STATS')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_STACKSHOT_FAULT_STATS'), 1098 ( 1099 KCSubTypeElement.FromBasicCtype('sfs_pages_faulted_in', KCSUBTYPE_TYPE.KC_ST_UINT32, 0), 1100 KCSubTypeElement.FromBasicCtype('sfs_time_spent_faulting', KCSUBTYPE_TYPE.KC_ST_UINT64, 4), 1101 KCSubTypeElement.FromBasicCtype('sfs_system_max_fault_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 12), 1102 KCSubTypeElement.FromBasicCtype('sfs_stopped_faulting', KCSUBTYPE_TYPE.KC_ST_UINT8, 20) 1103 ), 1104 'stackshot_fault_stats') 1105 1106KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_THREAD_WAITINFO')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_THREAD_WAITINFO'), 1107 ( 1108 KCSubTypeElement.FromBasicCtype('owner', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1109 KCSubTypeElement.FromBasicCtype('waiter', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1110 KCSubTypeElement.FromBasicCtype('context', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1111 KCSubTypeElement.FromBasicCtype('wait_type', KCSUBTYPE_TYPE.KC_ST_UINT8, 24), 1112 KCSubTypeElement.FromBasicCtype('portlabel_id', KCSUBTYPE_TYPE.KC_ST_INT16, 25), 1113 KCSubTypeElement.FromBasicCtype('wait_flags', KCSUBTYPE_TYPE.KC_ST_INT32, 27) 1114 ), 1115 'thread_waitinfo') 1116 1117KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_THREAD_TURNSTILEINFO')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_THREAD_TURNSTILEINFO'), 1118 ( 1119 KCSubTypeElement.FromBasicCtype('waiter', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1120 KCSubTypeElement.FromBasicCtype('turnstile_context', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1121 KCSubTypeElement.FromBasicCtype('turnstile_priority', KCSUBTYPE_TYPE.KC_ST_UINT8, 16), 1122 KCSubTypeElement.FromBasicCtype('number_of_hops', KCSUBTYPE_TYPE.KC_ST_UINT8, 17), 1123 KCSubTypeElement.FromBasicCtype('turnstile_flags', KCSUBTYPE_TYPE.KC_ST_UINT64, 18), 1124 KCSubTypeElement.FromBasicCtype('portlabel_id', KCSUBTYPE_TYPE.KC_ST_INT16, 26), 1125 ), 1126 'thread_turnstileinfo') 1127 1128KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_PORTLABEL')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_PORTLABEL'), 1129 ( 1130 KCSubTypeElement.FromBasicCtype('portlabel_id', KCSUBTYPE_TYPE.KC_ST_INT16, 0), 1131 KCSubTypeElement.FromBasicCtype('portlabel_flags', KCSUBTYPE_TYPE.KC_ST_UINT16, 2), 1132 KCSubTypeElement.FromBasicCtype('portlabel_domain', KCSUBTYPE_TYPE.KC_ST_UINT8, 4), 1133 ), 1134 'portlabel_info', merge=True) 1135 1136KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_PORTLABEL_NAME')] = ( 1137 KCSubTypeElement("portlabel_name", KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(-1, 1), 0, 1)) 1138 1139KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_THREAD_GROUP_SNAPSHOT')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_THREAD_GROUP'), 1140 ( 1141 KCSubTypeElement.FromBasicCtype('tgs_id', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1142 KCSubTypeElement('tgs_name', KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(16, 1), 1143 8, 1), 1144 KCSubTypeElement.FromBasicCtype('tgs_flags', KCSUBTYPE_TYPE.KC_ST_UINT64, 24), 1145 KCSubTypeElement('tgs_name_cont', KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(16, 1), 1146 32, 1), 1147 ), 1148 'thread_group_snapshot') 1149 1150 1151KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_THREAD_GROUP')] = KCSubTypeElement('thread_group', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0, KCSubTypeElement._get_naked_element_value) 1152 1153KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_JETSAM_COALITION_SNAPSHOT')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_JETSAM_COALITION_SNAPSHOT'), 1154 ( 1155 KCSubTypeElement.FromBasicCtype('jcs_id', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1156 KCSubTypeElement.FromBasicCtype('jcs_flags', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1157 KCSubTypeElement.FromBasicCtype('jcs_thread_group', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1158 KCSubTypeElement.FromBasicCtype('jcs_leader_task_uniqueid', KCSUBTYPE_TYPE.KC_ST_UINT64, 24) 1159 ), 1160 'jetsam_coalition_snapshot') 1161 1162KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_JETSAM_COALITION')] = KCSubTypeElement('jetsam_coalition', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0, KCSubTypeElement._get_naked_element_value) 1163 1164KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_INSTRS_CYCLES')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_INSTRS_CYCLES'), 1165 ( 1166 KCSubTypeElement.FromBasicCtype('ics_instructions', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1167 KCSubTypeElement.FromBasicCtype('ics_cycles', KCSUBTYPE_TYPE.KC_ST_UINT64, 8) 1168 ), 1169 'instrs_cycles_snapshot') 1170 1171KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_TASK_CPU_ARCHITECTURE')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_TASK_CPU_ARCHITECTURE'), 1172 ( 1173 KCSubTypeElement.FromBasicCtype('cputype', KCSUBTYPE_TYPE.KC_ST_INT32, 0), 1174 KCSubTypeElement.FromBasicCtype('cpusubtype', KCSUBTYPE_TYPE.KC_ST_INT32, 4) 1175 ), 1176 'task_cpu_architecture') 1177 1178KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_LATENCY_INFO')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_LATENCY_INFO'), 1179 ( 1180 KCSubTypeElement.FromBasicCtype('latency_version', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1181 KCSubTypeElement.FromBasicCtype('setup_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1182 KCSubTypeElement.FromBasicCtype('total_task_iteration_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1183 KCSubTypeElement.FromBasicCtype('total_terminated_task_iteration', KCSUBTYPE_TYPE.KC_ST_UINT64, 24) 1184 ), 1185 'stackshot_latency_collection') 1186 1187KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_LATENCY_INFO_TASK')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_LATENCY_INFO_TASK'), 1188 ( 1189 KCSubTypeElement.FromBasicCtype('task_uniqueid', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1190 KCSubTypeElement.FromBasicCtype('setup_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1191 KCSubTypeElement.FromBasicCtype('task_thread_count_loop_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1192 KCSubTypeElement.FromBasicCtype('task_thread_data_loop_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 24), 1193 KCSubTypeElement.FromBasicCtype('cur_tsnap_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 32), 1194 KCSubTypeElement.FromBasicCtype('pmap_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 40), 1195 KCSubTypeElement.FromBasicCtype('bsd_proc_ids_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 48), 1196 KCSubTypeElement.FromBasicCtype('misc_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 56), 1197 KCSubTypeElement.FromBasicCtype('misc2_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 64), 1198 KCSubTypeElement.FromBasicCtype('end_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 72) 1199 ), 1200 'stackshot_latency_task') 1201 1202KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_LATENCY_INFO_THREAD')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_LATENCY_INFO_THREAD'), 1203 ( 1204 KCSubTypeElement.FromBasicCtype('thread_id', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1205 KCSubTypeElement.FromBasicCtype('cur_thsnap1_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1206 KCSubTypeElement.FromBasicCtype('dispatch_serial_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1207 KCSubTypeElement.FromBasicCtype('dispatch_label_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 24), 1208 KCSubTypeElement.FromBasicCtype('cur_thsnap2_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 32), 1209 KCSubTypeElement.FromBasicCtype('thread_name_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 40), 1210 KCSubTypeElement.FromBasicCtype('sur_times_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 48), 1211 KCSubTypeElement.FromBasicCtype('user_stack_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 56), 1212 KCSubTypeElement.FromBasicCtype('kernel_stack_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 64), 1213 KCSubTypeElement.FromBasicCtype('misc_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 72), 1214 ), 1215 'stackshot_latency_thread') 1216 1217def set_type(name, *args): 1218 typ = GetTypeForName(name) 1219 KNOWN_TYPES_COLLECTION[typ] = KCTypeDescription(GetTypeForName(typ), *args) 1220 1221 1222set_type('STACKSHOT_KCTYPE_USER_STACKTOP', 1223 ( 1224 KCSubTypeElement.FromBasicCtype('sp', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1225 KCSubTypeElement('stack_contents', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(8, 1), 8, 1), 1226 ), 1227 'user_stacktop') 1228 1229#KNOWN_TYPES_COLLECTION[0x907] = KCSubTypeElement('donating_pids', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 0, 0, KCSubTypeElement._get_naked_element_value) 1230KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_PID')] = KCSubTypeElement('pid', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0) 1231KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_PPID')] = KCSubTypeElement('ppid', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0) 1232KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_PROC_NAME')] = KCSubTypeElement('p_comm', KCSUBTYPE_TYPE.KC_ST_CHAR, 1233 KCSubTypeElement.GetSizeForArray(32, 1), 0, 1) 1234KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_USERSTACK')] = KCSubTypeElement('userstack_ptr', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0) 1235KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_ARGSLEN')] = KCSubTypeElement('p_argslen', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0) 1236 1237KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_PROC_PATH')] = KCSubTypeElement('p_path', KCSUBTYPE_TYPE.KC_ST_CHAR, 1238 KCSubTypeElement.GetSizeForArray(1024, 1), 0, 1) 1239KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_PROC_CSFLAGS')] = KCSubTypeElement('p_csflags', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0) 1240KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_UID')] = KCSubTypeElement('uid', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0) 1241KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_GID')] = KCSubTypeElement('gid', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0) 1242KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_PROC_ARGC')] = KCSubTypeElement('argc', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0) 1243KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_PROC_FLAGS')] = KCSubTypeElement('p_flags', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0) 1244KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_CPUTYPE')] = KCSubTypeElement('cputype', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0) 1245KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_RESPONSIBLE_PID')] = KCSubTypeElement('responsible_pid', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0) 1246KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_DIRTY_FLAGS')] = KCSubTypeElement('dirty_flags', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0) 1247KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_CRASHED_THREADID')] = KCSubTypeElement('crashed_threadid', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0) 1248KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_COALITION_ID')] = KCSubTypeElement('coalition_id', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0) 1249 1250KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_PROC_STATUS')] = KCSubTypeElement('p_status', KCSUBTYPE_TYPE.KC_ST_UINT8, 1, 0, 0) 1251 1252KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_BSDINFOWITHUNIQID')] = KCTypeDescription(GetTypeForName('TASK_CRASHINFO_BSDINFOWITHUNIQID'), 1253 ( KCSubTypeElement('p_uuid', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(16, 1), 0, 1), 1254 KCSubTypeElement.FromBasicCtype('p_uniqueid', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1255 KCSubTypeElement.FromBasicCtype('p_puniqueid', KCSUBTYPE_TYPE.KC_ST_UINT64, 24) 1256 ), 1257 'proc_uniqidentifierinfo') 1258 1259KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_EXCEPTION_CODES')] = ( 1260 KCTypeDescription(GetTypeForName('TASK_CRASHINFO_EXCEPTION_CODES'), 1261 (KCSubTypeElement.FromBasicCtype('code_0', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1262 KCSubTypeElement.FromBasicCtype('code_1', KCSUBTYPE_TYPE.KC_ST_UINT64, 8)), 1263 'mach_exception_data_t')) 1264 1265 1266KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_PROC_STARTTIME')] = ( 1267 KCTypeDescription(GetTypeForName('TASK_CRASHINFO_PROC_STARTTIME'), 1268 (KCSubTypeElement.FromBasicCtype('tv_sec', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1269 KCSubTypeElement.FromBasicCtype('tv_usec', KCSUBTYPE_TYPE.KC_ST_UINT64, 8)), 1270 'proc_starttime')) 1271 1272 1273KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_RUSAGE_INFO')] = KCTypeDescription(GetTypeForName('TASK_CRASHINFO_RUSAGE_INFO'), 1274 ( 1275 KCSubTypeElement('ri_uuid', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(16, 1), 0, 1), 1276 KCSubTypeElement.FromBasicCtype('ri_user_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1277 KCSubTypeElement.FromBasicCtype('ri_system_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 24), 1278 KCSubTypeElement.FromBasicCtype('ri_pkg_idle_wkups', KCSUBTYPE_TYPE.KC_ST_UINT64, 32), 1279 KCSubTypeElement.FromBasicCtype('ri_interrupt_wkups', KCSUBTYPE_TYPE.KC_ST_UINT64, 40), 1280 KCSubTypeElement.FromBasicCtype('ri_pageins', KCSUBTYPE_TYPE.KC_ST_UINT64, 48), 1281 KCSubTypeElement.FromBasicCtype('ri_wired_size', KCSUBTYPE_TYPE.KC_ST_UINT64, 56), 1282 KCSubTypeElement.FromBasicCtype('ri_resident_size', KCSUBTYPE_TYPE.KC_ST_UINT64, 64), 1283 KCSubTypeElement.FromBasicCtype('ri_phys_footprint', KCSUBTYPE_TYPE.KC_ST_UINT64, 72), 1284 KCSubTypeElement.FromBasicCtype('ri_proc_start_abstime', KCSUBTYPE_TYPE.KC_ST_UINT64, 80), 1285 KCSubTypeElement.FromBasicCtype('ri_proc_exit_abstime', KCSUBTYPE_TYPE.KC_ST_UINT64, 88), 1286 KCSubTypeElement.FromBasicCtype('ri_child_user_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 96), 1287 KCSubTypeElement.FromBasicCtype('ri_child_system_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 104), 1288 KCSubTypeElement.FromBasicCtype('ri_child_pkg_idle_wkups', KCSUBTYPE_TYPE.KC_ST_UINT64, 112), 1289 KCSubTypeElement.FromBasicCtype('ri_child_interrupt_wkups', KCSUBTYPE_TYPE.KC_ST_UINT64, 120), 1290 KCSubTypeElement.FromBasicCtype('ri_child_pageins', KCSUBTYPE_TYPE.KC_ST_UINT64, 128), 1291 KCSubTypeElement.FromBasicCtype('ri_child_elapsed_abstime', KCSUBTYPE_TYPE.KC_ST_UINT64, 136), 1292 KCSubTypeElement.FromBasicCtype('ri_diskio_bytesread', KCSUBTYPE_TYPE.KC_ST_UINT64, 144), 1293 KCSubTypeElement.FromBasicCtype('ri_diskio_byteswritten', KCSUBTYPE_TYPE.KC_ST_UINT64, 152), 1294 KCSubTypeElement.FromBasicCtype('ri_cpu_time_qos_default', KCSUBTYPE_TYPE.KC_ST_UINT64, 160), 1295 KCSubTypeElement.FromBasicCtype('ri_cpu_time_qos_maintenance', KCSUBTYPE_TYPE.KC_ST_UINT64, 168), 1296 KCSubTypeElement.FromBasicCtype('ri_cpu_time_qos_background', KCSUBTYPE_TYPE.KC_ST_UINT64, 176), 1297 KCSubTypeElement.FromBasicCtype('ri_cpu_time_qos_utility', KCSUBTYPE_TYPE.KC_ST_UINT64, 184), 1298 KCSubTypeElement.FromBasicCtype('ri_cpu_time_qos_legacy', KCSUBTYPE_TYPE.KC_ST_UINT64, 192), 1299 KCSubTypeElement.FromBasicCtype('ri_cpu_time_qos_user_initiated', KCSUBTYPE_TYPE.KC_ST_UINT64, 200), 1300 KCSubTypeElement.FromBasicCtype('ri_cpu_time_qos_user_interactiv', KCSUBTYPE_TYPE.KC_ST_UINT64, 208), 1301 KCSubTypeElement.FromBasicCtype('ri_billed_system_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 216), 1302 KCSubTypeElement.FromBasicCtype('ri_serviced_system_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 224) 1303 ), 1304 'rusage_info') 1305 1306KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_CPU_TIMES')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_CPU_TIMES'), 1307 ( 1308 KCSubTypeElement.FromBasicCtype('user_usec', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1309 KCSubTypeElement.FromBasicCtype('system_usec', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1310 KCSubTypeElement.FromBasicCtype('runnable_usec', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1311 ), 'cpu_times') 1312 1313KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_STACKSHOT_DURATION')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_STACKSHOT_DURATION'), 1314 ( 1315 KCSubTypeElement.FromBasicCtype('stackshot_duration', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1316 KCSubTypeElement.FromBasicCtype('stackshot_duration_outer', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1317 KCSubTypeElement.FromBasicCtype('stackshot_duration_prior', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1318 ), 'stackshot_duration', merge=True 1319) 1320 1321KNOWN_TYPES_COLLECTION[GetTypeForName('KCDATA_TYPE_PROCNAME')] = ( 1322 KCSubTypeElement("proc_name", KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(-1, 1), 0, 1)) 1323 1324KNOWN_TYPES_COLLECTION[GetTypeForName('KCDATA_TYPE_PID')] = ( 1325 KCSubTypeElement('pid', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0)) 1326 1327KNOWN_TYPES_COLLECTION[GetTypeForName('KCDATA_TYPE_LIBRARY_AOTINFO')] = KCTypeDescription(GetTypeForName('KCDATA_TYPE_LIBRARY_AOTINFO'), 1328 ( 1329 KCSubTypeElement('x86LoadAddress', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0), 1330 KCSubTypeElement('aotLoadAddress', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 8, 0), 1331 KCSubTypeElement('aotImageSize', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 16, 0), 1332 KCSubTypeElement('aotImageKey', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(32, 1), 24, 1), 1333 ), 'dyld_aot_info') 1334 1335KNOWN_TYPES_COLLECTION[GetTypeForName('EXIT_REASON_SNAPSHOT')] = KCTypeDescription(GetTypeForName('EXIT_REASON_SNAPSHOT'), 1336 ( 1337 KCSubTypeElement.FromBasicCtype('ers_namespace', KCSUBTYPE_TYPE.KC_ST_UINT32, 0), 1338 KCSubTypeElement.FromBasicCtype('ers_code', KCSUBTYPE_TYPE.KC_ST_UINT64, 4), 1339 KCSubTypeElement.FromBasicCtype('ers_flags', KCSUBTYPE_TYPE.KC_ST_UINT64, 12), 1340 ), 'exit_reason_basic_info') 1341 1342KNOWN_TYPES_COLLECTION[GetTypeForName('EXIT_REASON_USER_DESC')] = ( 1343 KCSubTypeElement("exit_reason_user_description", KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(-1, 1), 0, 1)) 1344 1345KNOWN_TYPES_COLLECTION[GetTypeForName('EXIT_REASON_USER_PAYLOAD')] = KCSubTypeElement('exit_reason_user_payload', 1346 KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(-1, 1), 0, 1) 1347 1348KNOWN_TYPES_COLLECTION[GetTypeForName('EXIT_REASON_CODESIGNING_INFO')] = KCTypeDescription(GetTypeForName('EXIT_REASON_CODESIGNING_INFO'), 1349 ( 1350 KCSubTypeElement.FromBasicCtype('ceri_virt_addr', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1351 KCSubTypeElement.FromBasicCtype('ceri_file_offset', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1352 KCSubTypeElement("ceri_pathname", KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(1024, 1), 16, 1), 1353 KCSubTypeElement("ceri_filename", KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(1024, 1), 1040, 1), 1354 KCSubTypeElement.FromBasicCtype('ceri_codesig_modtime_secs', KCSUBTYPE_TYPE.KC_ST_UINT64, 2064), 1355 KCSubTypeElement.FromBasicCtype('ceri_codesig_modtime_nsecs', KCSUBTYPE_TYPE.KC_ST_UINT64, 2072), 1356 KCSubTypeElement.FromBasicCtype('ceri_page_modtime_secs', KCSUBTYPE_TYPE.KC_ST_UINT64, 2080), 1357 KCSubTypeElement.FromBasicCtype('ceri_page_modtime_nsecs', KCSUBTYPE_TYPE.KC_ST_UINT64, 2088), 1358 KCSubTypeElement.FromBasicCtype('ceri_path_truncated', KCSUBTYPE_TYPE.KC_ST_UINT8, 2096), 1359 KCSubTypeElement.FromBasicCtype('ceri_object_codesigned', KCSUBTYPE_TYPE.KC_ST_UINT8, 2097), 1360 KCSubTypeElement.FromBasicCtype('ceri_page_codesig_validated', KCSUBTYPE_TYPE.KC_ST_UINT8, 2098), 1361 KCSubTypeElement.FromBasicCtype('ceri_page_codesig_tainted', KCSUBTYPE_TYPE.KC_ST_UINT8, 2099), 1362 KCSubTypeElement.FromBasicCtype('ceri_page_codesig_nx', KCSUBTYPE_TYPE.KC_ST_UINT8, 2100), 1363 KCSubTypeElement.FromBasicCtype('ceri_page_wpmapped', KCSUBTYPE_TYPE.KC_ST_UINT8, 2101), 1364 KCSubTypeElement.FromBasicCtype('ceri_page_slid', KCSUBTYPE_TYPE.KC_ST_UINT8, 2102), 1365 KCSubTypeElement.FromBasicCtype('ceri_page_dirty', KCSUBTYPE_TYPE.KC_ST_UINT8, 2103), 1366 KCSubTypeElement.FromBasicCtype('ceri_page_shadow_depth', KCSUBTYPE_TYPE.KC_ST_UINT32, 2104), 1367 ), 'exit_reason_codesigning_info') 1368 1369KNOWN_TYPES_COLLECTION[GetTypeForName('EXIT_REASON_WORKLOOP_ID')] = ( 1370 KCSubTypeElement('exit_reason_workloop_id', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0, KCSubTypeElement._get_naked_element_value)) 1371 1372KNOWN_TYPES_COLLECTION[GetTypeForName('EXIT_REASON_DISPATCH_QUEUE_NO')] = ( 1373 KCSubTypeElement('exit_reason_dispatch_queue_no', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0, KCSubTypeElement._get_naked_element_value)) 1374 1375KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_ASID')] = ( 1376 KCSubTypeElement('ts_asid', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 0, 0)) 1377 1378KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_PAGE_TABLES')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_PAGE_TABLES'), ( 1379 KCSubTypeElement(None, KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0, KCSubTypeElement._get_naked_element_value), ), 1380 'ts_pagetable', 1381 merge=True, 1382 naked=True 1383) 1384 1385def GetSecondsFromMATime(mat, tb): 1386 return (float(long(mat) * tb['numer']) / tb['denom']) / 1e9 1387 1388def GetLongForAddress(address): 1389 if isinstance(address, six.string_types): 1390 if '0x' in address.lower(): 1391 address = long(address, 16) 1392 else: 1393 address = long(address) 1394 return address 1395 1396def FindLibraryForAddress(liblist, address): 1397 current_lib = None 1398 for l in liblist: 1399 l_addr = GetLongForAddress(l[1]) 1400 if address >= l_addr: 1401 current_lib = l 1402 return current_lib 1403 1404def FindIndexOfLibInCatalog(catalog, lib): 1405 index = None 1406 i = 0 1407 for l in catalog: 1408 if l[0] == lib[0] and l[1] == lib[1]: 1409 index = i 1410 break 1411 i += 1 1412 1413 if index is None: 1414 catalog.append(lib) 1415 index = len(catalog) - 1 1416 1417 return index 1418 1419def GetOffsetOfAddressForLib(lib, address): 1420 return (address - GetLongForAddress(lib[1])) 1421 1422def GetSymbolInfoForFrame(catalog, liblist, address): 1423 address = GetLongForAddress(address) 1424 lib = FindLibraryForAddress(liblist, address) 1425 if not lib: 1426 lib = ["00000000000000000000000000000000",0,"A"] 1427 offset = GetOffsetOfAddressForLib(lib, address) 1428 index = FindIndexOfLibInCatalog(catalog, lib) 1429 return [index, offset] 1430 1431def GetStateDescription(s): 1432 retval = [] 1433 TH_WAIT = 0x01 1434 TH_SUSP = 0x02 1435 TH_RUN = 0x04 1436 TH_UNINT = 0x08 1437 TH_TERMINATE = 0x10 1438 TH_TERMINATE2 = 0x20 1439 TH_WAIT_REPORT = 0x40 1440 TH_IDLE = 0x80 1441 if (s & TH_WAIT): 1442 retval.append("TH_WAIT") 1443 if (s & TH_SUSP): 1444 retval.append("TH_SUSP") 1445 if (s & TH_RUN): 1446 retval.append("TH_RUN") 1447 if (s & TH_UNINT): 1448 retval.append("TH_UNINT") 1449 if (s & TH_TERMINATE): 1450 retval.append("TH_TERMINATE") 1451 if (s & TH_TERMINATE2): 1452 retval.append("TH_TERMINATE2") 1453 if (s & TH_WAIT_REPORT): 1454 retval.append("TH_WAIT_REPORT") 1455 if (s & TH_IDLE): 1456 retval.append("TH_IDLE") 1457 return retval 1458 1459 1460def format_uuid(elementValues): 1461 # sometimes we get string like "25A926D8-F742-3E5E..." 1462 if isinstance(elementValues, six.string_types): 1463 return elementValues 1464 return ''.join("%02x" % i for i in elementValues) 1465 1466kThreadWaitNone = 0x00 1467kThreadWaitKernelMutex = 0x01 1468kThreadWaitPortReceive = 0x02 1469kThreadWaitPortSetReceive = 0x03 1470kThreadWaitPortSend = 0x04 1471kThreadWaitPortSendInTransit = 0x05 1472kThreadWaitSemaphore = 0x06 1473kThreadWaitKernelRWLockRead = 0x07 1474kThreadWaitKernelRWLockWrite = 0x08 1475kThreadWaitKernelRWLockUpgrade = 0x09 1476kThreadWaitUserLock = 0x0a 1477kThreadWaitPThreadMutex = 0x0b 1478kThreadWaitPThreadRWLockRead = 0x0c 1479kThreadWaitPThreadRWLockWrite = 0x0d 1480kThreadWaitPThreadCondVar = 0x0e 1481kThreadWaitParkedWorkQueue = 0x0f 1482kThreadWaitWorkloopSyncWait = 0x10 1483kThreadWaitOnProcess = 0x11 1484kThreadWaitSleepWithInheritor = 0x12 1485kThreadWaitEventlink = 0x13 1486kThreadWaitCompressor = 0x14 1487 1488 1489UINT64_MAX = 0xffffffffffffffff 1490STACKSHOT_WAITOWNER_KERNEL = (UINT64_MAX - 1) 1491STACKSHOT_WAITOWNER_PORT_LOCKED = (UINT64_MAX - 2) 1492STACKSHOT_WAITOWNER_PSET_LOCKED = (UINT64_MAX - 3) 1493STACKSHOT_WAITOWNER_INTRANSIT = (UINT64_MAX - 4) 1494STACKSHOT_WAITOWNER_MTXSPIN = (UINT64_MAX - 5) 1495STACKSHOT_WAITOWNER_THREQUESTED = (UINT64_MAX - 6) 1496STACKSHOT_WAITOWNER_SUSPENDED = (UINT64_MAX - 7) 1497 1498STACKSHOT_TURNSTILE_STATUS_UNKNOWN = 0x01 1499STACKSHOT_TURNSTILE_STATUS_LOCKED_WAITQ = 0x02 1500STACKSHOT_TURNSTILE_STATUS_WORKQUEUE = 0x04 1501STACKSHOT_TURNSTILE_STATUS_THREAD = 0x08 1502STACKSHOT_TURNSTILE_STATUS_BLOCKED_ON_TASK = 0x10 1503STACKSHOT_TURNSTILE_STATUS_HELD_IPLOCK = 0x20 1504STACKSHOT_TURNSTILE_STATUS_SENDPORT = 0x40 1505STACKSHOT_TURNSTILE_STATUS_RECEIVEPORT = 0x80 1506 1507# 1508# These come from xpc_domain_type_t in <xpc/launch_private.h> 1509PORTLABEL_DOMAINS = { 1510 1: 'system', # XPC_DOMAIN_SYSTEM 1511 2: 'user', # XPC_DOMAIN_USER 1512 5: 'pid', # XPC_DOMAIN_PID 1513 7: 'port', # XPC_DOMAIN_PORT 1514} 1515def portlabel_domain(x): 1516 if x is None: 1517 return "unknown" 1518 return PORTLABEL_DOMAINS.get(x, "unknown.{}".format(x)) 1519 1520STACKSHOT_WAITINFO_FLAGS_SPECIALREPLY = 0x1 1521 1522def formatPortLabelID(portlabel_id, portlabels): 1523 if portlabel_id > 0: 1524 portlabel = {} 1525 if portlabels is not None: 1526 portlabel = portlabels.get(str(portlabel_id), {}) 1527 portlabel_name = portlabel_domain(portlabel.get('portlabel_domain')) + " " 1528 portlabel_name += portlabel.get("portlabel_name", "!!!unknown, ID {} !!!".format(portlabel_id)); 1529 return " {" + portlabel_name + "}" 1530 if portlabel_id < 0: 1531 return" {labeled, info trucated}" 1532 return "" 1533 1534def formatWaitInfo(info, wantHex, portlabels): 1535 base='#x' if wantHex else 'd' 1536 s = 'thread {0:{base}}: '.format(info['waiter'], base=base) 1537 type = info['wait_type'] 1538 context = info['context'] 1539 owner = info['owner'] 1540 ownerThread = "{0:{base}}".format(owner, base=base) 1541 portlabel_id = info.get('portlabel_id', 0) 1542 flags = info.get('wait_flags', 0) 1543 1544 if type == kThreadWaitKernelMutex: 1545 s += 'kernel mutex %x' % context 1546 if owner == STACKSHOT_WAITOWNER_MTXSPIN: 1547 s += " in spin mode" 1548 elif owner: 1549 s += " owned by thread %s" % ownerThread 1550 else: 1551 s += "with unknown owner" 1552 elif type == kThreadWaitPortReceive: 1553 s += "mach_msg receive on " 1554 if flags & STACKSHOT_WAITINFO_FLAGS_SPECIALREPLY: 1555 s += "REPLY " 1556 flags = flags - STACKSHOT_WAITINFO_FLAGS_SPECIALREPLY 1557 if owner == STACKSHOT_WAITOWNER_PORT_LOCKED: 1558 s += "locked port %x" % context 1559 elif owner == STACKSHOT_WAITOWNER_INTRANSIT: 1560 s += "intransit port %x" % context 1561 elif owner: 1562 s += "port %x name %x" % (context, owner) 1563 else: 1564 s += "port %x" % context 1565 elif type == kThreadWaitPortSetReceive: 1566 if owner == STACKSHOT_WAITOWNER_PSET_LOCKED: 1567 s += "mach_msg receive on locked port set %x" % context 1568 else: 1569 s += "mach_msg receive on port set %x" % context 1570 elif type == kThreadWaitPortSend: 1571 s += "mach_msg send on " 1572 if owner == STACKSHOT_WAITOWNER_PORT_LOCKED: 1573 s += "locked port %x" % context 1574 elif owner == STACKSHOT_WAITOWNER_INTRANSIT: 1575 s += "intransit port %x" % context 1576 elif owner == STACKSHOT_WAITOWNER_KERNEL: 1577 s += "port %x owned by kernel" % context 1578 elif owner: 1579 s += "port %x owned by pid %d" % (context, owner) 1580 else: 1581 s += "port %x with unknown owner" % context 1582 elif type == kThreadWaitPortSendInTransit: 1583 s += "mach_msg send on port %x in transit to " % context 1584 if owner: 1585 s += "port %x" % owner 1586 else: 1587 s += "unknown port" 1588 elif type == kThreadWaitSemaphore: 1589 s += "semaphore port %x " % context 1590 if owner: 1591 s += "owned by pid %d" % owner 1592 else: 1593 s += "with unknown owner" 1594 elif type == kThreadWaitKernelRWLockRead: 1595 s += "krwlock %x for reading" % context 1596 if owner: 1597 s += " owned by thread %s" % ownerThread 1598 elif type == kThreadWaitKernelRWLockWrite: 1599 s += "krwlock %x for writing" % context 1600 if owner: 1601 s += " owned by thread %s" % ownerThread 1602 elif type == kThreadWaitKernelRWLockUpgrade: 1603 s += "krwlock %x for upgrading" % context 1604 if owner: 1605 s += " owned by thread %s" % ownerThread 1606 elif type == kThreadWaitUserLock: 1607 if owner: 1608 s += "unfair lock %x owned by thread %s" % (context, ownerThread) 1609 else: 1610 s += "spin lock %x" % context 1611 elif type == kThreadWaitPThreadMutex: 1612 s += "pthread mutex %x" % context 1613 if owner: 1614 s += " owned by thread %s" % ownerThread 1615 else: 1616 s += " with unknown owner" 1617 elif type == kThreadWaitPThreadRWLockRead: 1618 s += "pthread rwlock %x for reading" % context 1619 elif type == kThreadWaitPThreadRWLockWrite: 1620 s += "pthread rwlock %x for writing" % context 1621 elif type == kThreadWaitPThreadCondVar: 1622 s += "pthread condvar %x" % context 1623 elif type == kThreadWaitWorkloopSyncWait: 1624 s += "workloop sync wait" 1625 if owner == STACKSHOT_WAITOWNER_SUSPENDED: 1626 s += ", suspended" 1627 elif owner == STACKSHOT_WAITOWNER_THREQUESTED: 1628 s += ", thread requested" 1629 elif owner != 0: 1630 s += ", owned by thread %s" % ownerThread 1631 else: 1632 s += ", unknown owner" 1633 s += ", workloop id %x" % context 1634 elif type == kThreadWaitOnProcess: 1635 if owner == 2**64-1: 1636 s += "waitpid, for any children" 1637 elif 2**32 <= owner and owner < 2**64-1: 1638 s += "waitpid, for process group %d" % abs(owner - 2**64) 1639 else: 1640 s += "waitpid, for pid %d" % owner 1641 elif type == kThreadWaitSleepWithInheritor: 1642 if owner == 0: 1643 s += "turnstile, held waitq" 1644 else: 1645 s += "turnstile, pushing thread %s" % ownerThread 1646 elif type == kThreadWaitEventlink: 1647 if owner == 0: 1648 s += "eventlink, held waitq" 1649 else: 1650 s += "eventlink, signaled by thread %s" % ownerThread 1651 elif type == kThreadWaitCompressor: 1652 s += "in compressor segment %x, busy for thread %s" % (context, ownerThread) 1653 1654 else: 1655 s += "unknown type %d (owner %s, context %x)" % (type, ownerThread, context) 1656 1657 s += formatPortLabelID(portlabel_id, portlabels) 1658 1659 if flags != 0: 1660 s += "flags {}".format(hex(flags)) 1661 return s 1662 1663def formatTurnstileInfo(ti, wi_portlabel_id, portlabels): 1664 if ti is None: 1665 return " [no turnstile]" 1666 1667 ts_flags = int(ti['turnstile_flags']) 1668 ctx = int(ti['turnstile_context']) 1669 hop = int(ti['number_of_hops']) 1670 prio = int(ti['turnstile_priority']) 1671 portlabel_id = ti.get("portlabel_id", 0) 1672 1673 portlabel_summary = "" 1674 if portlabel_id != 0 and portlabel_id != wi_portlabel_id: 1675 portlabel_summary += formatPortLabelID(portlabel_id, portlabels) 1676 1677 if ts_flags & STACKSHOT_TURNSTILE_STATUS_HELD_IPLOCK: 1678 return " [turnstile blocked on task, but ip_lock was held]" + portlabel_summary 1679 if ts_flags & STACKSHOT_TURNSTILE_STATUS_BLOCKED_ON_TASK: 1680 return " [turnstile blocked on task pid %d, hops: %d, priority: %d]%s" % (ctx, hop, prio, portlabel_summary) 1681 if ts_flags & STACKSHOT_TURNSTILE_STATUS_LOCKED_WAITQ: 1682 return " [turnstile was in process of being updated]" + portlabel_summary 1683 if ts_flags & STACKSHOT_TURNSTILE_STATUS_WORKQUEUE: 1684 return " [blocked on workqueue: 0x%x, hops: %x, priority: %d]%s" % (ctx, hop, prio, portlabel_summary) 1685 if ts_flags & STACKSHOT_TURNSTILE_STATUS_THREAD: 1686 return " [blocked on: %d, hops: %x, priority: %d]%s" % (ctx, hop, prio, portlabel_summary) 1687 if ts_flags & STACKSHOT_TURNSTILE_STATUS_UNKNOWN: 1688 return " [turnstile with unknown inheritor]" + portlabel_summary 1689 1690 return " [unknown turnstile status!]" + portlabel_summary 1691 1692def formatWaitInfoWithTurnstiles(waitinfos, tsinfos, portlabels): 1693 wis_tis = [] 1694 for w in waitinfos: 1695 found_pair = False 1696 for t in tsinfos: 1697 if int(w['waiter']) == int(t['waiter']): 1698 wis_tis.append((w, t)) 1699 found_pair = True 1700 break 1701 if not found_pair: 1702 wis_tis.append((w, None)) 1703 1704 return [formatWaitInfo(wi, False, portlabels) + formatTurnstileInfo(ti, wi.get('portlabel_id', 0), portlabels) for (wi, ti) in wis_tis] 1705 1706def SaveStackshotReport(j, outfile_name, incomplete): 1707 import time 1708 from operator import itemgetter, attrgetter 1709 ss = j.get('kcdata_stackshot') 1710 if not ss: 1711 print("No KCDATA_BUFFER_BEGIN_STACKSHOT object found. Skipping writing report.") 1712 return 1713 1714 timestamp = ss.get('usecs_since_epoch') 1715 try: 1716 timestamp = time.strftime("%Y-%m-%d %H:%M:%S +0000",time.gmtime(timestamp // 1000000 if timestamp else None)) 1717 except ValueError as e: 1718 print("couldn't convert timestamp:", str(e)) 1719 timestamp = None 1720 1721 os_version = ss.get('osversion', 'Unknown') 1722 timebase = ss.get('mach_timebase_info', {"denom": 1, "numer": 1}) 1723 1724 sc_note = None 1725 extra_note = None 1726 dsc_common = None 1727 shared_cache_info = ss.get('shared_cache_dyld_load_info') 1728 if shared_cache_info: 1729 shared_cache_base_addr = shared_cache_info['imageSlidBaseAddress'] 1730 # If we have a slidFirstMapping and it's >= base_address, use that. 1731 # 1732 # Otherwise we're processing a stackshot from before the slidFirstMapping 1733 # field was introduced and corrected. On ARM the SlidBaseAddress is the 1734 # same, but on x86 it's off by 0x20000000. We use 'X86_64' in the 1735 # kernel version string plus checking kern_page_size == 4k' as 1736 # proxy for x86_64, and only adjust SlidBaseAddress if the unslid 1737 # address is precisely the expected incorrect value. 1738 # 1739 is_intel = ('X86_64' in ss.get('osversion', "") and 1740 ss.get('kernel_page_size', 0) == 4096) 1741 slidFirstMapping = shared_cache_info.get(SC_SLID_FIRSTMAPPING_KEY, -1); 1742 if slidFirstMapping >= shared_cache_base_addr: 1743 shared_cache_base_addr = slidFirstMapping 1744 sc_note = "base-accurate" 1745 1746 elif is_intel: 1747 sc_slide = shared_cache_info['imageLoadAddress'] 1748 if (shared_cache_base_addr - sc_slide) == 0x7fff00000000: 1749 shared_cache_base_addr += 0x20000000 1750 sc_note = "base-x86-adjusted" 1751 extra_note = "Shared cache base adjusted for x86. " 1752 else: 1753 sc_note = "base-x86-unknown" 1754 1755 dsc_common = [format_uuid(shared_cache_info['imageUUID']), 1756 shared_cache_base_addr, "S" ] 1757 print("Shared cache UUID found from the binary data is <%s> " % str(dsc_common[0])) 1758 1759 dsc_layout = ss.get('system_shared_cache_layout') 1760 1761 dsc_libs = [] 1762 if dsc_layout: 1763 print("Found in memory system shared cache layout with {} images".format(len(dsc_layout))) 1764 slide = ss.get('shared_cache_dyld_load_info')['imageLoadAddress'] 1765 1766 for image in dsc_layout: 1767 dsc_libs.append([format_uuid(image['imageUUID']), image['imageLoadAddress'] + slide, "C"]) 1768 1769 AllImageCatalog = [] 1770 obj = {} 1771 obj["kernel"] = os_version 1772 if timestamp is not None: 1773 obj["date"] = timestamp 1774 obj["reason"] = "kernel panic stackshot" 1775 obj["incident"] = "ABCDEFGH-1234-56IJ-789K-0LMNOPQRSTUV" 1776 obj["crashReporterKey"] = "12ab34cd45aabbccdd6712ab34cd45aabbccdd67" 1777 obj["bootArgs"] = ss.get('boot_args','') 1778 obj["frontmostPids"] = [0] 1779 obj["exception"] = "0xDEADF157" 1780 obj["processByPid"] = {} 1781 if sc_note is not None: 1782 obj["sharedCacheNote"] = sc_note 1783 1784 if incomplete: 1785 obj["reason"] = "!!!INCOMPLETE!!! kernel panic stackshot" 1786 obj["notes"] = "Generated by xnu kcdata.py from incomplete data! Some information is missing! " 1787 else: 1788 obj["notes"] = "Generated by xnu kcdata.py. " 1789 1790 if extra_note is not None: 1791 obj["notes"] = obj["notes"] + extra_note 1792 1793 processByPid = obj["processByPid"] 1794 ssplist = ss.get('task_snapshots', {}) 1795 ssplist.update(ss.get('transitioning_task_snapshots', {})) 1796 kern_load_info = [] 1797 if "0" in ssplist: 1798 kc_uuid = ssplist["0"].get('kernelcache_load_info', None) 1799 if kc_uuid: 1800 kernelcache_uuid = [format_uuid(kc_uuid['imageUUID']), kc_uuid['imageLoadAddress'], "U" ] 1801 kern_load_info.append(kernelcache_uuid) 1802 1803 kl_infos = ssplist["0"].get("dyld_load_info", []) 1804 for dlinfo in kl_infos: 1805 kern_load_info.append([format_uuid(dlinfo['imageUUID']), dlinfo['imageLoadAddress'], "K"]) 1806 1807 kl_infos_text_exec = ssplist["0"].get("dyld_load_info_text_exec", []) 1808 for dlinfo in kl_infos_text_exec: 1809 kern_load_info.append([format_uuid(dlinfo['imageUUID']), dlinfo['imageLoadAddress'], "T"]) 1810 1811 for pid,piddata in list(ssplist.items()): 1812 processByPid[str(pid)] = {} 1813 tsnap = processByPid[str(pid)] 1814 pr_lib_dsc = dsc_common 1815 1816 # see if there's an alternate shared cache 1817 scd = piddata.get('shared_cache_dyld_load_info') 1818 if scd is not None: 1819 if 'imageSlidBaseAddress' not in scd: 1820 print("Specific task shared cache format does not include slid shared cache base address. Skipping writing report.") 1821 return 1822 1823 scd_uuid = format_uuid(scd['imageUUID']) 1824 scd_base_addr = scd['imageSlidBaseAddress'] 1825 pr_lib_dsc = [scd_uuid, scd_base_addr, "S"] 1826 1827 pr_libs = [] 1828 if len(dsc_libs) == 0 and pr_lib_dsc: 1829 pr_libs.append(pr_lib_dsc) 1830 _lib_type = "P" 1831 if int(pid) == 0: 1832 _lib_type = "K" 1833 pr_libs = [] 1834 else: 1835 for dlinfo in piddata.get('dyld_load_info',[]): 1836 pr_libs.append([format_uuid(dlinfo['imageUUID']), dlinfo['imageLoadAddress'], _lib_type]) 1837 1838 pr_libs.extend(kern_load_info) 1839 pr_libs.extend(dsc_libs) 1840 1841 pr_libs.sort(key=itemgetter(1)) 1842 1843 ttsnap = piddata.get('transitioning_task_snapshot', None) 1844 if ttsnap is not None: 1845 # Transitioning task snapshots have "tts_" prefixes; change them to 1846 # "ts_". 1847 ttsnap = { key[1:] : value for key,value in ttsnap.items() } 1848 # Add a note to let people know 1849 obj["notes"] = obj["notes"] + "PID {} is a transitioning (exiting) task. ".format(pid) 1850 tasksnap = piddata.get('task_snapshot', ttsnap); 1851 if tasksnap is None: 1852 continue; 1853 tsnap["pid"] = tasksnap["ts_pid"] 1854 if 'ts_asid' in piddata: 1855 tsnap["asid"] = piddata["ts_asid"] 1856 1857 if 'ts_pagetable' in piddata: 1858 pagetables = [] 1859 for tte in piddata["ts_pagetable"]: 1860 pagetables.append(tte) 1861 tsnap["pageTables"] = pagetables 1862 1863 # Some fields are missing from transitioning_task snapshots. 1864 if ttsnap is None: 1865 tsnap["residentMemoryBytes"] = tasksnap["ts_task_size"] 1866 tsnap["timesDidThrottle"] = tasksnap["ts_did_throttle"] 1867 tsnap["systemTimeTask"] = GetSecondsFromMATime(tasksnap["ts_system_time_in_terminated_th"], timebase) 1868 tsnap["pageIns"] = tasksnap["ts_pageins"] 1869 tsnap["pageFaults"] = tasksnap["ts_faults"] 1870 tsnap["userTimeTask"] = GetSecondsFromMATime(tasksnap["ts_user_time_in_terminated_thre"], timebase) 1871 tsnap["procname"] = tasksnap["ts_p_comm"] 1872 if ttsnap is None: 1873 tsnap["copyOnWriteFaults"] = tasksnap["ts_cow_faults"] 1874 tsnap["timesThrottled"] = tasksnap["ts_was_throttled"] 1875 tsnap["threadById"] = {} 1876 threadByID = tsnap["threadById"] 1877 thlist = piddata.get('thread_snapshots', {}) 1878 for tid,thdata in list(thlist.items()): 1879 threadByID[str(tid)] = {} 1880 thsnap = threadByID[str(tid)] 1881 if "thread_snapshot" not in thdata: 1882 print("Found broken thread state for thread ID: %s." % tid) 1883 break 1884 threadsnap = thdata["thread_snapshot"] 1885 thsnap["userTime"] = GetSecondsFromMATime(threadsnap["ths_user_time"], timebase) 1886 thsnap["id"] = threadsnap["ths_thread_id"] 1887 thsnap["basePriority"] = threadsnap["ths_base_priority"] 1888 thsnap["systemTime"] = GetSecondsFromMATime(threadsnap["ths_sys_time"], timebase) 1889 thsnap["schedPriority"] = threadsnap["ths_sched_priority"] 1890 thsnap["state"] = GetStateDescription(threadsnap['ths_state']) 1891 thsnap["qosEffective"] = threadsnap["ths_eqos"] 1892 thsnap["qosRequested"] = threadsnap["ths_rqos"] 1893 1894 if "pth_name" in thdata: 1895 thsnap["name"] = thdata["pth_name"]; 1896 1897 if threadsnap['ths_continuation']: 1898 thsnap["continuation"] = GetSymbolInfoForFrame(AllImageCatalog, pr_libs, threadsnap['ths_continuation']) 1899 if "kernel_stack_frames" in thdata: 1900 kuserframes = [] 1901 for f in thdata["kernel_stack_frames"]: 1902 kuserframes.append(GetSymbolInfoForFrame(AllImageCatalog, pr_libs, f['lr'])) 1903 thsnap["kernelFrames"] = kuserframes 1904 1905 if "user_stack_frames" in thdata: 1906 uframes = [] 1907 for f in thdata["user_stack_frames"]: 1908 uframes.append(GetSymbolInfoForFrame(AllImageCatalog, pr_libs, f['lr'])) 1909 thsnap["userFrames"] = uframes 1910 1911 if "user_stacktop" in thdata: 1912 (address,) = struct.unpack("<Q", struct.pack("B"*8, *thdata["user_stacktop"]["stack_contents"])) 1913 thsnap["userStacktop"] = GetSymbolInfoForFrame(AllImageCatalog, pr_libs, address) 1914 1915 if threadsnap['ths_wait_event']: 1916 thsnap["waitEvent"] = GetSymbolInfoForFrame(AllImageCatalog, pr_libs, threadsnap['ths_wait_event']) 1917 1918 if 'thread_waitinfo' in piddata and 'thread_turnstileinfo' in piddata: 1919 tsnap['waitInfo'] = formatWaitInfoWithTurnstiles(piddata['thread_waitinfo'], piddata['thread_turnstileinfo'], piddata.get('portlabels', None)) 1920 elif 'thread_waitinfo' in piddata: 1921 portlabels = ss.get('portlabels', None) 1922 tsnap['waitInfo'] = [formatWaitInfo(x, False, portlabels) for x in piddata['thread_waitinfo']] 1923 obj['binaryImages'] = AllImageCatalog 1924 if outfile_name == '-': 1925 fh = sys.stdout 1926 else: 1927 fh = open(outfile_name, "w") 1928 1929 header = {} 1930 header['bug_type'] = 288 1931 if timestamp is not None: 1932 header['timestamp'] = timestamp 1933 header['os_version'] = os_version 1934 fh.write(json.dumps(header)) 1935 fh.write("\n") 1936 1937 fh.write(json.dumps(obj, sort_keys=False, indent=2, separators=(',', ': '))) 1938 fh.close() 1939 1940## Base utils for interacting with shell ## 1941def RunCommand(bash_cmd_string, get_stderr = True): 1942 """ 1943 returns: (int,str) : exit_code and output_str 1944 """ 1945 print("RUNNING: %s" % bash_cmd_string) 1946 cmd_args = shlex.split(bash_cmd_string) 1947 output_str = "" 1948 exit_code = 0 1949 try: 1950 if get_stderr: 1951 output_str = subprocess.check_output(cmd_args, stderr=subprocess.STDOUT) 1952 else: 1953 output_str = subprocess.check_output(cmd_args, stderr=None) 1954 except subprocess.CalledProcessError as e: 1955 exit_code = e.returncode 1956 finally: 1957 return (exit_code, output_str) 1958 1959 1960@contextlib.contextmanager 1961def data_from_stream(stream): 1962 try: 1963 fmap = mmap.mmap(stream.fileno(), 0, mmap.MAP_SHARED, mmap.PROT_READ) 1964 except: 1965 yield stream.read() 1966 else: 1967 try: 1968 yield fmap 1969 finally: 1970 fmap.close() 1971 1972def iterate_kcdatas(kcdata_file): 1973 with data_from_stream(kcdata_file) as data: 1974 iterator = kcdata_item_iterator(data) 1975 kcdata_buffer = KCObject.FromKCItem(six.next(iterator)) 1976 1977 if isinstance(kcdata_buffer, KCCompressedBufferObject): 1978 kcdata_buffer.ReadItems(iterator) 1979 decompressed = kcdata_buffer.Decompress(data) 1980 iterator = kcdata_item_iterator(decompressed) 1981 kcdata_buffer = KCObject.FromKCItem(six.next(iterator)) 1982 1983 if not isinstance(kcdata_buffer, KCBufferObject): 1984 # ktrace stackshot chunk 1985 iterator = kcdata_item_iterator(data[16:]) 1986 kcdata_buffer = KCObject.FromKCItem(six.next(iterator)) 1987 1988 if not isinstance(kcdata_buffer, KCBufferObject): 1989 try: 1990 decoded = base64.b64decode(data) 1991 except: 1992 pass 1993 else: 1994 iterator = kcdata_item_iterator(decoded) 1995 kcdata_buffer = KCObject.FromKCItem(six.next(iterator)) 1996 if not isinstance(kcdata_buffer, KCBufferObject): 1997 import gzip 1998 from io import BytesIO 1999 try: 2000 decompressed = gzip.GzipFile(fileobj=BytesIO(data[:])).read() 2001 except: 2002 pass 2003 else: 2004 iterator = kcdata_item_iterator(decompressed) 2005 kcdata_buffer = KCObject.FromKCItem(six.next(iterator)) 2006 2007 if not isinstance(kcdata_buffer, KCBufferObject): 2008 raise Exception("unknown file type") 2009 2010 2011 kcdata_buffer.ReadItems(iterator) 2012 yield kcdata_buffer 2013 2014 for magic in iterator: 2015 kcdata_buffer = KCObject.FromKCItem(magic) 2016 if kcdata_buffer.i_type == 0: 2017 continue 2018 if not isinstance(kcdata_buffer, KCBufferObject): 2019 raise Exception("unknown file type") 2020 kcdata_buffer.ReadItems(iterator) 2021 yield kcdata_buffer 2022 2023# 2024# Values for various flag fields. Each entry's key is the key seen in the 2025# processed kcdata, the value is an array of bits, from low (0x1) to high, with 2026# either a string flag name or None for unused holes. 2027# 2028# Only put flags in here which are stable - this is run against stackshots 2029# of all different versions. For anything unstable, we'll need a decoder ring 2030# added to the stackshot. 2031# 2032PRETTIFY_FLAGS = { 2033 'jcs_flags': [ 2034 'kCoalitionTermRequested', 2035 'kCoalitionTerminated', 2036 'kCoalitionReaped', 2037 'kCoalitionPrivileged', 2038 ], 2039 'stackshot_in_flags': [ # STACKSHOT_*, also stackshot_out_flags 2040 'get_dq', 2041 'save_loadinfo', 2042 'get_global_mem_stats', 2043 'save_kext_loadinfo', 2044 None, 2045 None, 2046 None, 2047 None, 2048 'active_kernel_threads_only', 2049 'get_boot_profile', 2050 'do_compress', 2051 None, 2052 None, 2053 'save_imp_donation_pids', 2054 'save_in_kernel_buffer', 2055 'retrieve_existing_buffer', 2056 'kcdata_format', 2057 'enable_bt_faulting', 2058 'collect_delta_snapshot', 2059 'collect_sharedcache_layout', 2060 'trylock', 2061 'enable_uuid_faulting', 2062 'from_panic', 2063 'no_io_stats', 2064 'thread_waitinfo', 2065 'thread_group', 2066 'save_jetsam_coalitions', 2067 'instrs_cycles', 2068 'asid', 2069 'page_tables', 2070 'disable_latency_info', 2071 ], 2072 'system_state_flags': [ 2073 'kUser64_p', 2074 'kKern64_p', 2075 ], 2076 'tgs_flags': [ 2077 'kThreadGroupEfficient', 2078 'kThreadGroupUIApp', 2079 ], 2080 'ths_ss_flags': [ 2081 'kUser64_p', 2082 'kKern64_p', 2083 'kHasDispatchSerial', 2084 'kStacksPCOnly', 2085 'kThreadDarwinBG', 2086 'kThreadIOPassive', 2087 'kThreadSuspended', 2088 'kThreadTruncatedBT', 2089 'kGlobalForcedIdle', 2090 'kThreadFaultedBT', 2091 'kThreadTriedFaultBT', 2092 'kThreadOnCore', 2093 'kThreadIdleWorker', 2094 'kThreadMain', 2095 'kThreadTruncKernBT', 2096 'kThreadTruncUserBT', 2097 'kThreadTruncUserAsyncBT', 2098 ], 2099 'ths_state': [ 2100 'TH_WAIT', 2101 'TH_SUSP', 2102 'TH_RUN', 2103 'TH_UNINT', 2104 'TH_TERMINATE', 2105 'TH_TERMINATE2', 2106 'TH_WAIT_REPORT', 2107 'TH_IDLE', 2108 ], 2109 'ts_ss_flags': [ 2110 'kUser64_p', 2111 'kKern64_p', 2112 'kTaskRsrcFlagged', 2113 'kTerminatedSnapshot', 2114 'kPidSuspended', 2115 'kFrozen', 2116 'kTaskDarwinBG', 2117 'kTaskExtDarwinBG', 2118 'kTaskVisVisible', 2119 'kTaskVisNonvisible', 2120 'kTaskIsForeground', 2121 'kTaskIsBoosted', 2122 'kTaskIsSuppressed', 2123 'kTaskIsTimerThrottled', 2124 'kTaskIsImpDonor', 2125 'kTaskIsLiveImpDonor', 2126 'kTaskIsDirty', 2127 'kTaskWqExceededConstrainedThreadLimit', 2128 'kTaskWqExceededTotalThreadLimit', 2129 'kTaskWqFlagsAvailable', 2130 'kTaskUUIDInfoFaultedIn', 2131 'kTaskUUIDInfoMissing', 2132 'kTaskUUIDInfoTriedFault', 2133 'kTaskSharedRegionInfoUnavailable', 2134 'kTaskTALEngaged', 2135 None, 2136 'kTaskIsDirtyTracked', 2137 'kTaskAllowIdleExit', 2138 'kTaskIsTranslated', 2139 'kTaskSharedRegionNone', 2140 'kTaskSharedRegionSystem', 2141 'kTaskSharedRegionOther', 2142 ], 2143 'turnstile_flags': [ 2144 'turnstile_status_unknown', 2145 'turnstile_status_locked_waitq', 2146 'turnstile_status_workqueue', 2147 'turnstile_status_thread', 2148 'turnstile_status_blocked_on_task', 2149 'turnstile_status_held_iplock', 2150 ], 2151} 2152PRETTIFY_FLAGS['stackshot_out_flags'] = PRETTIFY_FLAGS['stackshot_in_flags'] 2153PRETTIFY_FLAGS['tts_ss_flags'] = PRETTIFY_FLAGS['ts_ss_flags'] 2154 2155# Fields which should never be hexified 2156PRETTIFY_DONTHEX = { 2157 'stackshot_in_pid': True, 2158 'tts_pid': True, 2159 'ts_pid': True, 2160 'donating_pids': True, 2161 'ppid': True, 2162} 2163 2164# Only hex() the value if it is multiple digits 2165def prettify_hex(v): 2166 if v < -9 or v > 9: 2167 return hex(v) 2168 return str(v) 2169 2170def prettify_flags(v, flags): 2171 output="" 2172 seen = 0 2173 if v == 0: 2174 return "0" 2175 for (s, n) in zip(range(len(flags)),flags): 2176 if n is None: 2177 continue 2178 if (v & (2 ** s)): 2179 output += "|" + n 2180 seen |= 2 ** s 2181 if output == "": 2182 return prettify_hex(v) 2183 rest = (v & ~seen) 2184 if (rest != 0): 2185 output += "|" + prettify_hex(rest) 2186 return prettify_hex(v) + " (" + output[1:] + ")" 2187 2188def prettify_core(data, mosthex, key, portlabels): 2189 if key == 'stack_contents': 2190 (address,) = struct.unpack("<Q", struct.pack("B"*8, *data)) 2191 return '0x%X' % address 2192 2193 elif isinstance(data, list): 2194 if 'uuid' in key.lower() and len(data) == 16: 2195 return '%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X' % tuple(data) 2196 2197 return [prettify_core(x, mosthex, key, portlabels) for x in data] 2198 2199 elif key == 'thread_waitinfo': 2200 return formatWaitInfo(data, mosthex, portlabels) 2201 2202 elif isinstance(data, dict): 2203 if 'portlabels' in data: 2204 portlabels = data['portlabels'] 2205 newdata = dict() 2206 for key, value in data.items(): 2207 if mosthex and key != 'task_snapshots' and len(key) > 0 and key.isnumeric(): 2208 key = prettify_hex(int(key)) 2209 newdata[key] = prettify_core(value, mosthex, key, portlabels) 2210 return newdata 2211 2212 elif 'address' in key.lower() and isinstance(data, (int, long)): 2213 return '0x%X' % data 2214 elif key == 'lr' or key == SC_SLID_FIRSTMAPPING_KEY: 2215 return '0x%X' % data 2216 elif key in PRETTIFY_FLAGS and isinstance(data, (int, long)): 2217 return prettify_flags(data, PRETTIFY_FLAGS[key]) 2218 elif key.endswith('_flags') and isinstance(data, (int, long)): 2219 return prettify_hex(data) 2220 2221 elif mosthex and not PRETTIFY_DONTHEX.get(key, False): 2222 if isinstance(data, (int, long)): 2223 return prettify_hex(data) 2224 elif isinstance(data, six.string_types) and len(data) > 0 and data.isnumeric(): 2225 return prettify_hex(int(data)) 2226 return data 2227 2228 else: 2229 return data 2230 2231def prettify(data, mosthex): 2232 return prettify_core(data, mosthex, "", None) 2233 2234if __name__ == '__main__': 2235 parser = argparse.ArgumentParser(description="Decode a kcdata binary file.") 2236 parser.add_argument("-l", "--listtypes", action="store_true", required=False, default=False, 2237 help="List all known types", 2238 dest="list_known_types") 2239 2240 parser.add_argument("-s", "--stackshot", required=False, default=False, 2241 help="Generate a stackshot report file", 2242 dest="stackshot_file") 2243 2244 parser.add_argument("--multiple", help="look for multiple stackshots in a single file", action='store_true') 2245 2246 parser.add_argument("-p", "--plist", required=False, default=False, 2247 help="output as plist", action="store_true") 2248 2249 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") 2250 parser.add_argument("-P", "--pretty", default=False, action='store_true', help="make the output a little more human readable") 2251 parser.add_argument("-X", "--prettyhex", default=False, action='store_true', help="make the output a little more human readable, and print most things as hex") 2252 parser.add_argument("--incomplete", action='store_true', help="accept incomplete data") 2253 parser.add_argument("kcdata_file", type=argparse.FileType('r'), help="Path to a kcdata binary file.") 2254 2255 class VerboseAction(argparse.Action): 2256 def __call__(self, parser, namespace, values, option_string=None): 2257 logging.basicConfig(level=logging.INFO, stream=sys.stderr, format='%(message)s') 2258 parser.add_argument('-v', "--verbose", action=VerboseAction, nargs=0) 2259 2260 args = parser.parse_args() 2261 2262 if args.multiple and args.stackshot_file: 2263 raise NotImplementedError 2264 2265 if args.list_known_types: 2266 for (n, t) in KNOWN_TYPES_COLLECTION.items(): 2267 print("%d : %s " % (n, str(t))) 2268 sys.exit(1) 2269 2270 if args.incomplete or args.stackshot_file: 2271 G.accept_incomplete_data = True 2272 2273 for i,kcdata_buffer in enumerate(iterate_kcdatas(args.kcdata_file)): 2274 if i > 0 and not args.multiple: 2275 break 2276 2277 str_data = "{" + kcdata_buffer.GetJsonRepr() + "}" 2278 str_data = str_data.replace("\t", " ") 2279 2280 try: 2281 json_obj = json.loads(str_data) 2282 except: 2283 print("JSON reparsing failed! Printing string data!\n", file=sys.stderr) 2284 import textwrap 2285 print(textwrap.fill(str_data, 100)) 2286 raise 2287 2288 if args.prettyhex: 2289 json_obj = prettify(json_obj, True) 2290 elif args.pretty: 2291 json_obj = prettify(json_obj, False) 2292 2293 if args.stackshot_file: 2294 SaveStackshotReport(json_obj, args.stackshot_file, G.data_was_incomplete) 2295 elif args.plist: 2296 import Foundation 2297 plist = Foundation.NSPropertyListSerialization.dataWithPropertyList_format_options_error_( 2298 json_obj, Foundation.NSPropertyListXMLFormat_v1_0, 0, None)[0].bytes().tobytes() 2299 #sigh. on some pythons long integers are getting output with L's in the plist. 2300 plist = re.sub(r'^(\s*<integer>\d+)L(</integer>\s*)$', r"\1\2", BytesToString(plist), flags=re.MULTILINE) 2301 print(plist,) 2302 else: 2303 print(json.dumps(json_obj, sort_keys=True, indent=4, separators=(',', ': '))) 2304