1#!/usr/bin/env python3 2from __future__ 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 121 'STACKSHOT_KCTYPE_TASK_DELTA_SNAPSHOT': 0x940, 122 'STACKSHOT_KCTYPE_THREAD_DELTA_SNAPSHOT': 0x941, 123 124 125 126 'KCDATA_TYPE_BUFFER_END': 0xF19158ED, 127 128 129 'TASK_CRASHINFO_EXTMODINFO': 0x801, 130 'TASK_CRASHINFO_BSDINFOWITHUNIQID': 0x802, 131 'TASK_CRASHINFO_TASKDYLD_INFO': 0x803, 132 'TASK_CRASHINFO_UUID': 0x804, 133 'TASK_CRASHINFO_PID': 0x805, 134 'TASK_CRASHINFO_PPID': 0x806, 135 136 # Don't want anyone using this. It's struct rusage from whatever machine generated the data 137 #'TASK_CRASHINFO_RUSAGE': 0x807, 138 'Type_0x807': 0x807, 139 140 'TASK_CRASHINFO_RUSAGE_INFO': 0x808, 141 'TASK_CRASHINFO_PROC_NAME': 0x809, 142 'TASK_CRASHINFO_PROC_STARTTIME': 0x80B, 143 'TASK_CRASHINFO_USERSTACK': 0x80C, 144 'TASK_CRASHINFO_ARGSLEN': 0x80D, 145 'TASK_CRASHINFO_EXCEPTION_CODES': 0x80E, 146 'TASK_CRASHINFO_PROC_PATH': 0x80F, 147 'TASK_CRASHINFO_PROC_CSFLAGS': 0x810, 148 'TASK_CRASHINFO_PROC_STATUS': 0x811, 149 'TASK_CRASHINFO_UID': 0x812, 150 'TASK_CRASHINFO_GID': 0x813, 151 'TASK_CRASHINFO_PROC_ARGC': 0x814, 152 'TASK_CRASHINFO_PROC_FLAGS': 0x815, 153 'TASK_CRASHINFO_CPUTYPE': 0x816, 154 'TASK_CRASHINFO_WORKQUEUEINFO': 0x817, 155 'TASK_CRASHINFO_RESPONSIBLE_PID': 0x818, 156 'TASK_CRASHINFO_DIRTY_FLAGS': 0x819, 157 'TASK_CRASHINFO_CRASHED_THREADID': 0x81A, 158 'TASK_CRASHINFO_COALITION_ID': 0x81B, 159 'EXIT_REASON_SNAPSHOT': 0x1001, 160 'EXIT_REASON_USER_DESC': 0x1002, 161 'EXIT_REASON_USER_PAYLOAD': 0x1003, 162 'EXIT_REASON_CODESIGNING_INFO': 0x1004, 163 'EXIT_REASON_WORKLOOP_ID': 0x1005, 164 'EXIT_REASON_DISPATCH_QUEUE_NO': 0x1006, 165 'KCDATA_BUFFER_BEGIN_CRASHINFO': 0xDEADF157, 166 'KCDATA_BUFFER_BEGIN_DELTA_STACKSHOT': 0xDE17A59A, 167 'KCDATA_BUFFER_BEGIN_STACKSHOT': 0x59a25807, 168 'KCDATA_BUFFER_BEGIN_COMPRESSED': 0x434f4d50, 169 'KCDATA_BUFFER_BEGIN_OS_REASON': 0x53A20900, 170 'KCDATA_BUFFER_BEGIN_XNUPOST_CONFIG': 0x1E21C09F 171} 172kcdata_type_def_rev = dict((v, k) for k, v in iter(kcdata_type_def.items())) 173 174KNOWN_TYPES_COLLECTION = {} 175 176KNOWN_TOPLEVEL_CONTAINER_TYPES = () 177 178def enum(**args): 179 return type('enum', (), args) 180 181# 182# Decode bytes as UTF-8, using surrogateescape if there are invalid UTF-8 183# sequences; see PEP-383 184# 185def BytesToString(b): 186 if isinstance(b, six.string_types): 187 return b 188 return b.decode('utf-8', errors="surrogateescape") 189 190# important keys 191SC_SLID_FIRSTMAPPING_KEY = 'sharedCacheSlidFirstMapping' 192 193# important builtin types 194KCSUBTYPE_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) 195 196 197LEGAL_OLD_STYLE_ARRAY_TYPE_NAMES = ['KCDATA_TYPE_LIBRARY_LOADINFO', 198 'KCDATA_TYPE_LIBRARY_LOADINFO64', 199 'STACKSHOT_KCTYPE_KERN_STACKFRAME', 200 'STACKSHOT_KCTYPE_USER_STACKFRAME', 201 'STACKSHOT_KCTYPE_KERN_STACKFRAME64', 202 'STACKSHOT_KCTYPE_USER_STACKFRAME64', 203 'STACKSHOT_KCTYPE_DONATING_PIDS', 204 'STACKSHOT_KCTYPE_THREAD_DELTA_SNAPSHOT'] 205 206KCDATA_FLAGS_STRUCT_PADDING_MASK = 0xf 207KCDATA_FLAGS_STRUCT_HAS_PADDING = 0x80 208 209class KCSubTypeElement(object): 210 """convert kcdata_subtype_descriptor to """ 211 _unpack_formats = (None, 'c', 'b', 'B', 'h', 'H', 'i', 'I', 'q', 'Q') 212 _ctypes = ('Unknown', 'char', 'int8_t', 'uint8_t', 'int16_t', 'uint16_t', 'int32_t', 'uint32_t', 'int64_t', 'uint64_t') 213 214 def __init__(self, st_name, st_type, st_size, st_offset=0, st_flag=0, custom_repr=None): 215 self.name = st_name 216 self.offset = st_offset 217 self.type_id = st_type 218 if st_type <= 0 or st_type > KCSUBTYPE_TYPE.KC_ST_UINT64: 219 raise ValueError("Invalid type passed %d" % st_type) 220 self.unpack_fmt = KCSubTypeElement._unpack_formats[self.type_id] 221 self.size = st_size 222 self.totalsize = st_size 223 self.count = 1 224 self.is_array_type = False 225 self.custom_JsonRepr = custom_repr 226 if (st_flag & 0x1) == 0x1: 227 self.is_array_type = True 228 self.size = st_size & 0xffff 229 self.count = (st_size >> 16) & 0xffff 230 self.totalsize = self.size * self.count 231 232 @staticmethod 233 def GetSizeForArray(el_count, el_size): 234 return ((el_count & 0xffff) << 16) | (el_size & 0xffff) 235 236 @staticmethod 237 def FromBinaryTypeData(byte_data): 238 (st_flag, st_type, st_offset, st_size, st_name) = struct.unpack_from('=BBHI32s', byte_data) 239 st_name = BytesToString(st_name).rstrip('\0') 240 return KCSubTypeElement(st_name, st_type, st_size, st_offset, st_flag) 241 242 @staticmethod 243 def FromBasicCtype(st_name, st_type, st_offset=0, legacy_size=None): 244 if st_type <= 0 or st_type > KCSUBTYPE_TYPE.KC_ST_UINT64: 245 raise ValueError("Invalid type passed %d" % st_type) 246 st_size = struct.calcsize(KCSubTypeElement._unpack_formats[st_type]) 247 st_flag = 0 248 retval = KCSubTypeElement(st_name, st_type, st_size, st_offset, st_flag, KCSubTypeElement._get_naked_element_value) 249 if legacy_size: 250 retval.legacy_size = legacy_size 251 return retval 252 253 @staticmethod 254 def FromKCSubTypeElement(other, name_override=''): 255 _copy = copy.copy(other) 256 if name_override: 257 _copy.name = name_override 258 return copy 259 260 def GetName(self): 261 return self.name 262 263 def GetTotalSize(self): 264 return self.totalsize 265 266 def GetValueAsString(self, base_data, array_pos=0): 267 v = self.GetValue(base_data, array_pos) 268 if isinstance(v, bytes): 269 return BytesToString(v) 270 return str(v) 271 272 def GetValue(self, base_data, array_pos=0): 273 return struct.unpack_from(self.unpack_fmt, base_data[self.offset + (array_pos * self.size):])[0] 274 275 @staticmethod 276 def _get_naked_element_value(elementValue, elementName): 277 return json.dumps(elementValue) 278 279 def __str__(self): 280 if self.is_array_type: 281 return '[%d,%d] %s %s[%d];' % (self.offset, self.totalsize, self.GetCTypeDesc(), self.name, self.count) 282 return '[%d,%d] %s %s;' % (self.offset, self.totalsize, self.GetCTypeDesc(), self.name) 283 284 def __repr__(self): 285 return str(self) 286 287 def GetCTypeDesc(self): 288 return KCSubTypeElement._ctypes[self.type_id] 289 290 def GetStringRepr(self, base_data): 291 if not self.is_array_type: 292 return self.GetValueAsString(base_data) 293 if self.type_id == KCSUBTYPE_TYPE.KC_ST_CHAR: 294 str_len = self.count 295 if len(base_data) < str_len: 296 str_len = len(base_data) 297 str_arr = [] 298 for i in range(str_len): 299 _v = self.GetValue(base_data, i) 300 if ord(_v) == 0: 301 break 302 str_arr.append(self.GetValueAsString(base_data, i)) 303 return json.dumps(''.join(str_arr)) 304 305 count = self.count 306 if count > len(base_data)//self.size: 307 count = len(base_data)//self.size 308 309 o = '[' + ','.join([self.GetValueAsString(base_data, i) for i in range(count)]) + ']' 310 311 return o 312 313 def GetJsonRepr(self, base_data, flags=0): 314 if (flags & (KCDATA_FLAGS_STRUCT_HAS_PADDING | KCDATA_FLAGS_STRUCT_PADDING_MASK)) != 0: 315 padding = (flags & KCDATA_FLAGS_STRUCT_PADDING_MASK) 316 if padding: 317 base_data = base_data[:-padding] 318 if self.custom_JsonRepr: 319 if self.is_array_type: 320 e_data = [self.GetValue(base_data, i) for i in range(self.count)] 321 else: 322 e_data = self.GetValue(base_data) 323 return self.custom_JsonRepr(e_data, self.name) 324 return self.GetStringRepr(base_data) 325 326 def sizeof(self): 327 return self.totalsize 328 329 def ShouldSkip(self, data): 330 return len(data) < self.offset + self.totalsize 331 332 def ShouldMerge(self): 333 return False 334 335 336class KCTypeDescription(object): 337 def __init__(self, t_type_id, t_elements=[], t_name='anon', custom_repr=None, legacy_size=None, merge=False, naked=False): 338 self.type_id = t_type_id 339 self.elements = t_elements 340 self.name = t_name 341 self.totalsize = 0 342 self.custom_JsonRepr = custom_repr 343 if legacy_size: 344 self.legacy_size = legacy_size 345 self.merge = merge 346 self.naked = naked 347 for e in self.elements: 348 self.totalsize += e.GetTotalSize() 349 350 def ValidateData(self, base_data): 351 if len(base_data) >= self.totalsize: 352 return True 353 return False 354 355 def GetTypeID(self): 356 return self.type_id 357 358 def GetName(self): 359 return self.name 360 361 def __str__(self): 362 o = '%s {\n\t' % self.name + "\n\t".join([str(e) for e in self.elements]) + '\n};' 363 return o 364 365 @staticmethod 366 def FromKCTypeDescription(other, t_type_id, t_name): 367 retval = KCTypeDescription(t_type_id, other.elements, t_name, other.custom_JsonRepr, 368 legacy_size=getattr(other, 'legacy_size', None)) 369 return retval 370 371 def ShouldMerge(self): 372 return self.merge 373 374 def GetJsonRepr(self, base_data, flags): 375 if (flags & (KCDATA_FLAGS_STRUCT_HAS_PADDING | KCDATA_FLAGS_STRUCT_PADDING_MASK)) != 0: 376 padding = (flags & KCDATA_FLAGS_STRUCT_PADDING_MASK) 377 if padding: 378 base_data = base_data[:-padding] 379 elif hasattr(self, 'legacy_size') and len(base_data) == self.legacy_size + ((-self.legacy_size) & 0xf): 380 base_data = base_data[:self.legacy_size] 381 if self.custom_JsonRepr: 382 return self.custom_JsonRepr([e.GetValue(base_data) for e in self.elements]) 383 if self.naked: 384 o = ", ".join([e.GetJsonRepr(base_data) for e in self.elements if not e.ShouldSkip(base_data)]) 385 else: 386 o = ", ".join(['"%s": %s' % (e.GetName(), e.GetJsonRepr(base_data)) for e in self.elements if not e.ShouldSkip(base_data)]) 387 if not self.merge: 388 o = '{' + o + '}' 389 return o 390 391 def sizeof(self): 392 return max(st.totalsize + st.offset for st in self.elements) 393 394 395def GetTypeNameForKey(k): 396 retval = "0x%x" % k 397 if k in KNOWN_TYPES_COLLECTION: 398 retval = KNOWN_TYPES_COLLECTION[k].GetName() 399 elif k in kcdata_type_def_rev: 400 retval = kcdata_type_def_rev[k] 401 return retval 402 403 404def GetTypeForName(n): 405 ret = 0 406 if n in kcdata_type_def: 407 ret = kcdata_type_def[n] 408 return ret 409 410 411LEGAL_OLD_STYLE_ARRAY_TYPES = list(map(GetTypeForName, LEGAL_OLD_STYLE_ARRAY_TYPE_NAMES)) 412 413kcdata_type_def_rev[GetTypeForName('KCDATA_BUFFER_BEGIN_STACKSHOT')] = 'kcdata_stackshot' 414kcdata_type_def_rev[GetTypeForName('KCDATA_BUFFER_BEGIN_DELTA_STACKSHOT')] = 'kcdata_delta_stackshot' 415kcdata_type_def_rev[GetTypeForName('KCDATA_BUFFER_BEGIN_CRASHINFO')] = 'kcdata_crashinfo' 416kcdata_type_def_rev[GetTypeForName('KCDATA_BUFFER_BEGIN_OS_REASON')] = 'kcdata_reason' 417kcdata_type_def_rev[GetTypeForName('STACKSHOT_KCCONTAINER_TASK')] = 'task_snapshots' 418kcdata_type_def_rev[GetTypeForName('STACKSHOT_KCCONTAINER_TRANSITIONING_TASK')] = 'transitioning_task_snapshots' 419kcdata_type_def_rev[GetTypeForName('STACKSHOT_KCCONTAINER_THREAD')] = 'thread_snapshots' 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 ), 1113 'thread_waitinfo') 1114 1115KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_THREAD_TURNSTILEINFO')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_THREAD_TURNSTILEINFO'), 1116 ( 1117 KCSubTypeElement.FromBasicCtype('waiter', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1118 KCSubTypeElement.FromBasicCtype('turnstile_context', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1119 KCSubTypeElement.FromBasicCtype('turnstile_priority', KCSUBTYPE_TYPE.KC_ST_UINT8, 16), 1120 KCSubTypeElement.FromBasicCtype('number_of_hops', KCSUBTYPE_TYPE.KC_ST_UINT8, 17), 1121 KCSubTypeElement.FromBasicCtype('turnstile_flags', KCSUBTYPE_TYPE.KC_ST_UINT64, 18), 1122 ), 1123 'thread_turnstileinfo') 1124 1125KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_THREAD_GROUP_SNAPSHOT')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_THREAD_GROUP'), 1126 ( 1127 KCSubTypeElement.FromBasicCtype('tgs_id', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1128 KCSubTypeElement('tgs_name', KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(16, 1), 1129 8, 1), 1130 KCSubTypeElement.FromBasicCtype('tgs_flags', KCSUBTYPE_TYPE.KC_ST_UINT64, 24), 1131 ), 1132 'thread_group_snapshot') 1133 1134 1135KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_THREAD_GROUP')] = KCSubTypeElement('thread_group', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0, KCSubTypeElement._get_naked_element_value) 1136 1137KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_JETSAM_COALITION_SNAPSHOT')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_JETSAM_COALITION_SNAPSHOT'), 1138 ( 1139 KCSubTypeElement.FromBasicCtype('jcs_id', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1140 KCSubTypeElement.FromBasicCtype('jcs_flags', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1141 KCSubTypeElement.FromBasicCtype('jcs_thread_group', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1142 KCSubTypeElement.FromBasicCtype('jcs_leader_task_uniqueid', KCSUBTYPE_TYPE.KC_ST_UINT64, 24) 1143 ), 1144 'jetsam_coalition_snapshot') 1145 1146KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_JETSAM_COALITION')] = KCSubTypeElement('jetsam_coalition', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0, KCSubTypeElement._get_naked_element_value) 1147 1148KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_INSTRS_CYCLES')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_INSTRS_CYCLES'), 1149 ( 1150 KCSubTypeElement.FromBasicCtype('ics_instructions', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1151 KCSubTypeElement.FromBasicCtype('ics_cycles', KCSUBTYPE_TYPE.KC_ST_UINT64, 8) 1152 ), 1153 'instrs_cycles_snapshot') 1154 1155KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_TASK_CPU_ARCHITECTURE')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_TASK_CPU_ARCHITECTURE'), 1156 ( 1157 KCSubTypeElement.FromBasicCtype('cputype', KCSUBTYPE_TYPE.KC_ST_INT32, 0), 1158 KCSubTypeElement.FromBasicCtype('cpusubtype', KCSUBTYPE_TYPE.KC_ST_INT32, 4) 1159 ), 1160 'task_cpu_architecture') 1161 1162KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_LATENCY_INFO')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_LATENCY_INFO'), 1163 ( 1164 KCSubTypeElement.FromBasicCtype('latency_version', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1165 KCSubTypeElement.FromBasicCtype('setup_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1166 KCSubTypeElement.FromBasicCtype('total_task_iteration_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1167 KCSubTypeElement.FromBasicCtype('total_terminated_task_iteration', KCSUBTYPE_TYPE.KC_ST_UINT64, 24) 1168 ), 1169 'stackshot_latency_collection') 1170 1171KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_LATENCY_INFO_TASK')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_LATENCY_INFO_TASK'), 1172 ( 1173 KCSubTypeElement.FromBasicCtype('task_uniqueid', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1174 KCSubTypeElement.FromBasicCtype('setup_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1175 KCSubTypeElement.FromBasicCtype('task_thread_count_loop_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1176 KCSubTypeElement.FromBasicCtype('task_thread_data_loop_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 24), 1177 KCSubTypeElement.FromBasicCtype('cur_tsnap_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 32), 1178 KCSubTypeElement.FromBasicCtype('pmap_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 40), 1179 KCSubTypeElement.FromBasicCtype('bsd_proc_ids_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 48), 1180 KCSubTypeElement.FromBasicCtype('misc_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 56), 1181 KCSubTypeElement.FromBasicCtype('misc2_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 64), 1182 KCSubTypeElement.FromBasicCtype('end_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 72) 1183 ), 1184 'stackshot_latency_task') 1185 1186KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_LATENCY_INFO_THREAD')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_LATENCY_INFO_THREAD'), 1187 ( 1188 KCSubTypeElement.FromBasicCtype('thread_id', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1189 KCSubTypeElement.FromBasicCtype('cur_thsnap1_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1190 KCSubTypeElement.FromBasicCtype('dispatch_serial_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1191 KCSubTypeElement.FromBasicCtype('dispatch_label_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 24), 1192 KCSubTypeElement.FromBasicCtype('cur_thsnap2_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 32), 1193 KCSubTypeElement.FromBasicCtype('thread_name_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 40), 1194 KCSubTypeElement.FromBasicCtype('sur_times_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 48), 1195 KCSubTypeElement.FromBasicCtype('user_stack_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 56), 1196 KCSubTypeElement.FromBasicCtype('kernel_stack_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 64), 1197 KCSubTypeElement.FromBasicCtype('misc_latency', KCSUBTYPE_TYPE.KC_ST_UINT64, 72), 1198 ), 1199 'stackshot_latency_thread') 1200 1201def set_type(name, *args): 1202 typ = GetTypeForName(name) 1203 KNOWN_TYPES_COLLECTION[typ] = KCTypeDescription(GetTypeForName(typ), *args) 1204 1205 1206set_type('STACKSHOT_KCTYPE_USER_STACKTOP', 1207 ( 1208 KCSubTypeElement.FromBasicCtype('sp', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1209 KCSubTypeElement('stack_contents', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(8, 1), 8, 1), 1210 ), 1211 'user_stacktop') 1212 1213#KNOWN_TYPES_COLLECTION[0x907] = KCSubTypeElement('donating_pids', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 0, 0, KCSubTypeElement._get_naked_element_value) 1214KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_PID')] = KCSubTypeElement('pid', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0) 1215KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_PPID')] = KCSubTypeElement('ppid', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0) 1216KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_PROC_NAME')] = KCSubTypeElement('p_comm', KCSUBTYPE_TYPE.KC_ST_CHAR, 1217 KCSubTypeElement.GetSizeForArray(32, 1), 0, 1) 1218KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_USERSTACK')] = KCSubTypeElement('userstack_ptr', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0) 1219KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_ARGSLEN')] = KCSubTypeElement('p_argslen', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0) 1220 1221KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_PROC_PATH')] = KCSubTypeElement('p_path', KCSUBTYPE_TYPE.KC_ST_CHAR, 1222 KCSubTypeElement.GetSizeForArray(1024, 1), 0, 1) 1223KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_PROC_CSFLAGS')] = KCSubTypeElement('p_csflags', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0) 1224KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_UID')] = KCSubTypeElement('uid', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0) 1225KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_GID')] = KCSubTypeElement('gid', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0) 1226KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_PROC_ARGC')] = KCSubTypeElement('argc', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0) 1227KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_PROC_FLAGS')] = KCSubTypeElement('p_flags', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0) 1228KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_CPUTYPE')] = KCSubTypeElement('cputype', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0) 1229KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_RESPONSIBLE_PID')] = KCSubTypeElement('responsible_pid', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0) 1230KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_DIRTY_FLAGS')] = KCSubTypeElement('dirty_flags', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0) 1231KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_CRASHED_THREADID')] = KCSubTypeElement('crashed_threadid', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0) 1232KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_COALITION_ID')] = KCSubTypeElement('coalition_id', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0) 1233 1234KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_PROC_STATUS')] = KCSubTypeElement('p_status', KCSUBTYPE_TYPE.KC_ST_UINT8, 1, 0, 0) 1235 1236KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_BSDINFOWITHUNIQID')] = KCTypeDescription(GetTypeForName('TASK_CRASHINFO_BSDINFOWITHUNIQID'), 1237 ( KCSubTypeElement('p_uuid', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(16, 1), 0, 1), 1238 KCSubTypeElement.FromBasicCtype('p_uniqueid', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1239 KCSubTypeElement.FromBasicCtype('p_puniqueid', KCSUBTYPE_TYPE.KC_ST_UINT64, 24) 1240 ), 1241 'proc_uniqidentifierinfo') 1242 1243KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_EXCEPTION_CODES')] = ( 1244 KCTypeDescription(GetTypeForName('TASK_CRASHINFO_EXCEPTION_CODES'), 1245 (KCSubTypeElement.FromBasicCtype('code_0', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1246 KCSubTypeElement.FromBasicCtype('code_1', KCSUBTYPE_TYPE.KC_ST_UINT64, 8)), 1247 'mach_exception_data_t')) 1248 1249 1250KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_PROC_STARTTIME')] = ( 1251 KCTypeDescription(GetTypeForName('TASK_CRASHINFO_PROC_STARTTIME'), 1252 (KCSubTypeElement.FromBasicCtype('tv_sec', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1253 KCSubTypeElement.FromBasicCtype('tv_usec', KCSUBTYPE_TYPE.KC_ST_UINT64, 8)), 1254 'proc_starttime')) 1255 1256 1257KNOWN_TYPES_COLLECTION[GetTypeForName('TASK_CRASHINFO_RUSAGE_INFO')] = KCTypeDescription(GetTypeForName('TASK_CRASHINFO_RUSAGE_INFO'), 1258 ( 1259 KCSubTypeElement('ri_uuid', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(16, 1), 0, 1), 1260 KCSubTypeElement.FromBasicCtype('ri_user_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1261 KCSubTypeElement.FromBasicCtype('ri_system_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 24), 1262 KCSubTypeElement.FromBasicCtype('ri_pkg_idle_wkups', KCSUBTYPE_TYPE.KC_ST_UINT64, 32), 1263 KCSubTypeElement.FromBasicCtype('ri_interrupt_wkups', KCSUBTYPE_TYPE.KC_ST_UINT64, 40), 1264 KCSubTypeElement.FromBasicCtype('ri_pageins', KCSUBTYPE_TYPE.KC_ST_UINT64, 48), 1265 KCSubTypeElement.FromBasicCtype('ri_wired_size', KCSUBTYPE_TYPE.KC_ST_UINT64, 56), 1266 KCSubTypeElement.FromBasicCtype('ri_resident_size', KCSUBTYPE_TYPE.KC_ST_UINT64, 64), 1267 KCSubTypeElement.FromBasicCtype('ri_phys_footprint', KCSUBTYPE_TYPE.KC_ST_UINT64, 72), 1268 KCSubTypeElement.FromBasicCtype('ri_proc_start_abstime', KCSUBTYPE_TYPE.KC_ST_UINT64, 80), 1269 KCSubTypeElement.FromBasicCtype('ri_proc_exit_abstime', KCSUBTYPE_TYPE.KC_ST_UINT64, 88), 1270 KCSubTypeElement.FromBasicCtype('ri_child_user_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 96), 1271 KCSubTypeElement.FromBasicCtype('ri_child_system_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 104), 1272 KCSubTypeElement.FromBasicCtype('ri_child_pkg_idle_wkups', KCSUBTYPE_TYPE.KC_ST_UINT64, 112), 1273 KCSubTypeElement.FromBasicCtype('ri_child_interrupt_wkups', KCSUBTYPE_TYPE.KC_ST_UINT64, 120), 1274 KCSubTypeElement.FromBasicCtype('ri_child_pageins', KCSUBTYPE_TYPE.KC_ST_UINT64, 128), 1275 KCSubTypeElement.FromBasicCtype('ri_child_elapsed_abstime', KCSUBTYPE_TYPE.KC_ST_UINT64, 136), 1276 KCSubTypeElement.FromBasicCtype('ri_diskio_bytesread', KCSUBTYPE_TYPE.KC_ST_UINT64, 144), 1277 KCSubTypeElement.FromBasicCtype('ri_diskio_byteswritten', KCSUBTYPE_TYPE.KC_ST_UINT64, 152), 1278 KCSubTypeElement.FromBasicCtype('ri_cpu_time_qos_default', KCSUBTYPE_TYPE.KC_ST_UINT64, 160), 1279 KCSubTypeElement.FromBasicCtype('ri_cpu_time_qos_maintenance', KCSUBTYPE_TYPE.KC_ST_UINT64, 168), 1280 KCSubTypeElement.FromBasicCtype('ri_cpu_time_qos_background', KCSUBTYPE_TYPE.KC_ST_UINT64, 176), 1281 KCSubTypeElement.FromBasicCtype('ri_cpu_time_qos_utility', KCSUBTYPE_TYPE.KC_ST_UINT64, 184), 1282 KCSubTypeElement.FromBasicCtype('ri_cpu_time_qos_legacy', KCSUBTYPE_TYPE.KC_ST_UINT64, 192), 1283 KCSubTypeElement.FromBasicCtype('ri_cpu_time_qos_user_initiated', KCSUBTYPE_TYPE.KC_ST_UINT64, 200), 1284 KCSubTypeElement.FromBasicCtype('ri_cpu_time_qos_user_interactiv', KCSUBTYPE_TYPE.KC_ST_UINT64, 208), 1285 KCSubTypeElement.FromBasicCtype('ri_billed_system_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 216), 1286 KCSubTypeElement.FromBasicCtype('ri_serviced_system_time', KCSUBTYPE_TYPE.KC_ST_UINT64, 224) 1287 ), 1288 'rusage_info') 1289 1290KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_CPU_TIMES')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_CPU_TIMES'), 1291 ( 1292 KCSubTypeElement.FromBasicCtype('user_usec', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1293 KCSubTypeElement.FromBasicCtype('system_usec', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1294 KCSubTypeElement.FromBasicCtype('runnable_usec', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1295 ), 'cpu_times') 1296 1297KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_STACKSHOT_DURATION')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_STACKSHOT_DURATION'), 1298 ( 1299 KCSubTypeElement.FromBasicCtype('stackshot_duration', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1300 KCSubTypeElement.FromBasicCtype('stackshot_duration_outer', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1301 KCSubTypeElement.FromBasicCtype('stackshot_duration_prior', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1302 ), 'stackshot_duration', merge=True 1303) 1304 1305KNOWN_TYPES_COLLECTION[GetTypeForName('KCDATA_TYPE_PROCNAME')] = ( 1306 KCSubTypeElement("proc_name", KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(-1, 1), 0, 1)) 1307 1308KNOWN_TYPES_COLLECTION[GetTypeForName('KCDATA_TYPE_PID')] = ( 1309 KCSubTypeElement('pid', KCSUBTYPE_TYPE.KC_ST_INT32, 4, 0, 0)) 1310 1311KNOWN_TYPES_COLLECTION[GetTypeForName('KCDATA_TYPE_LIBRARY_AOTINFO')] = KCTypeDescription(GetTypeForName('KCDATA_TYPE_LIBRARY_AOTINFO'), 1312 ( 1313 KCSubTypeElement('x86LoadAddress', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0), 1314 KCSubTypeElement('aotLoadAddress', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 8, 0), 1315 KCSubTypeElement('aotImageSize', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 16, 0), 1316 KCSubTypeElement('aotImageKey', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(32, 1), 24, 1), 1317 ), 'dyld_aot_info') 1318 1319KNOWN_TYPES_COLLECTION[GetTypeForName('EXIT_REASON_SNAPSHOT')] = KCTypeDescription(GetTypeForName('EXIT_REASON_SNAPSHOT'), 1320 ( 1321 KCSubTypeElement.FromBasicCtype('ers_namespace', KCSUBTYPE_TYPE.KC_ST_UINT32, 0), 1322 KCSubTypeElement.FromBasicCtype('ers_code', KCSUBTYPE_TYPE.KC_ST_UINT64, 4), 1323 KCSubTypeElement.FromBasicCtype('ers_flags', KCSUBTYPE_TYPE.KC_ST_UINT64, 12), 1324 ), 'exit_reason_basic_info') 1325 1326KNOWN_TYPES_COLLECTION[GetTypeForName('EXIT_REASON_USER_DESC')] = ( 1327 KCSubTypeElement("exit_reason_user_description", KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(-1, 1), 0, 1)) 1328 1329KNOWN_TYPES_COLLECTION[GetTypeForName('EXIT_REASON_USER_PAYLOAD')] = KCSubTypeElement('exit_reason_user_payload', 1330 KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(-1, 1), 0, 1) 1331 1332KNOWN_TYPES_COLLECTION[GetTypeForName('EXIT_REASON_CODESIGNING_INFO')] = KCTypeDescription(GetTypeForName('EXIT_REASON_CODESIGNING_INFO'), 1333 ( 1334 KCSubTypeElement.FromBasicCtype('ceri_virt_addr', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1335 KCSubTypeElement.FromBasicCtype('ceri_file_offset', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1336 KCSubTypeElement("ceri_pathname", KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(1024, 1), 16, 1), 1337 KCSubTypeElement("ceri_filename", KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(1024, 1), 1040, 1), 1338 KCSubTypeElement.FromBasicCtype('ceri_codesig_modtime_secs', KCSUBTYPE_TYPE.KC_ST_UINT64, 2064), 1339 KCSubTypeElement.FromBasicCtype('ceri_codesig_modtime_nsecs', KCSUBTYPE_TYPE.KC_ST_UINT64, 2072), 1340 KCSubTypeElement.FromBasicCtype('ceri_page_modtime_secs', KCSUBTYPE_TYPE.KC_ST_UINT64, 2080), 1341 KCSubTypeElement.FromBasicCtype('ceri_page_modtime_nsecs', KCSUBTYPE_TYPE.KC_ST_UINT64, 2088), 1342 KCSubTypeElement.FromBasicCtype('ceri_path_truncated', KCSUBTYPE_TYPE.KC_ST_UINT8, 2096), 1343 KCSubTypeElement.FromBasicCtype('ceri_object_codesigned', KCSUBTYPE_TYPE.KC_ST_UINT8, 2097), 1344 KCSubTypeElement.FromBasicCtype('ceri_page_codesig_validated', KCSUBTYPE_TYPE.KC_ST_UINT8, 2098), 1345 KCSubTypeElement.FromBasicCtype('ceri_page_codesig_tainted', KCSUBTYPE_TYPE.KC_ST_UINT8, 2099), 1346 KCSubTypeElement.FromBasicCtype('ceri_page_codesig_nx', KCSUBTYPE_TYPE.KC_ST_UINT8, 2100), 1347 KCSubTypeElement.FromBasicCtype('ceri_page_wpmapped', KCSUBTYPE_TYPE.KC_ST_UINT8, 2101), 1348 KCSubTypeElement.FromBasicCtype('ceri_page_slid', KCSUBTYPE_TYPE.KC_ST_UINT8, 2102), 1349 KCSubTypeElement.FromBasicCtype('ceri_page_dirty', KCSUBTYPE_TYPE.KC_ST_UINT8, 2103), 1350 KCSubTypeElement.FromBasicCtype('ceri_page_shadow_depth', KCSUBTYPE_TYPE.KC_ST_UINT32, 2104), 1351 ), 'exit_reason_codesigning_info') 1352 1353KNOWN_TYPES_COLLECTION[GetTypeForName('EXIT_REASON_WORKLOOP_ID')] = ( 1354 KCSubTypeElement('exit_reason_workloop_id', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0, KCSubTypeElement._get_naked_element_value)) 1355 1356KNOWN_TYPES_COLLECTION[GetTypeForName('EXIT_REASON_DISPATCH_QUEUE_NO')] = ( 1357 KCSubTypeElement('exit_reason_dispatch_queue_no', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0, KCSubTypeElement._get_naked_element_value)) 1358 1359KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_ASID')] = ( 1360 KCSubTypeElement('ts_asid', KCSUBTYPE_TYPE.KC_ST_UINT32, 4, 0, 0)) 1361 1362KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_PAGE_TABLES')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_PAGE_TABLES'), ( 1363 KCSubTypeElement(None, KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0, KCSubTypeElement._get_naked_element_value), ), 1364 'ts_pagetable', 1365 merge=True, 1366 naked=True 1367) 1368 1369def GetSecondsFromMATime(mat, tb): 1370 return (float(long(mat) * tb['numer']) / tb['denom']) / 1e9 1371 1372def GetLongForAddress(address): 1373 if isinstance(address, six.string_types): 1374 if '0x' in address.lower(): 1375 address = long(address, 16) 1376 else: 1377 address = long(address) 1378 return address 1379 1380def FindLibraryForAddress(liblist, address): 1381 current_lib = None 1382 for l in liblist: 1383 l_addr = GetLongForAddress(l[1]) 1384 if address >= l_addr: 1385 current_lib = l 1386 return current_lib 1387 1388def FindIndexOfLibInCatalog(catalog, lib): 1389 index = None 1390 i = 0 1391 for l in catalog: 1392 if l[0] == lib[0] and l[1] == lib[1]: 1393 index = i 1394 break 1395 i += 1 1396 1397 if index is None: 1398 catalog.append(lib) 1399 index = len(catalog) - 1 1400 1401 return index 1402 1403def GetOffsetOfAddressForLib(lib, address): 1404 return (address - GetLongForAddress(lib[1])) 1405 1406def GetSymbolInfoForFrame(catalog, liblist, address): 1407 address = GetLongForAddress(address) 1408 lib = FindLibraryForAddress(liblist, address) 1409 if not lib: 1410 lib = ["00000000000000000000000000000000",0,"A"] 1411 offset = GetOffsetOfAddressForLib(lib, address) 1412 index = FindIndexOfLibInCatalog(catalog, lib) 1413 return [index, offset] 1414 1415def GetStateDescription(s): 1416 retval = [] 1417 TH_WAIT = 0x01 1418 TH_SUSP = 0x02 1419 TH_RUN = 0x04 1420 TH_UNINT = 0x08 1421 TH_TERMINATE = 0x10 1422 TH_TERMINATE2 = 0x20 1423 TH_WAIT_REPORT = 0x40 1424 TH_IDLE = 0x80 1425 if (s & TH_WAIT): 1426 retval.append("TH_WAIT") 1427 if (s & TH_SUSP): 1428 retval.append("TH_SUSP") 1429 if (s & TH_RUN): 1430 retval.append("TH_RUN") 1431 if (s & TH_UNINT): 1432 retval.append("TH_UNINT") 1433 if (s & TH_TERMINATE): 1434 retval.append("TH_TERMINATE") 1435 if (s & TH_TERMINATE2): 1436 retval.append("TH_TERMINATE2") 1437 if (s & TH_WAIT_REPORT): 1438 retval.append("TH_WAIT_REPORT") 1439 if (s & TH_IDLE): 1440 retval.append("TH_IDLE") 1441 return retval 1442 1443 1444def format_uuid(elementValues): 1445 # sometimes we get string like "25A926D8-F742-3E5E..." 1446 if isinstance(elementValues, six.string_types): 1447 return elementValues 1448 return ''.join("%02x" % i for i in elementValues) 1449 1450kThreadWaitNone = 0x00 1451kThreadWaitKernelMutex = 0x01 1452kThreadWaitPortReceive = 0x02 1453kThreadWaitPortSetReceive = 0x03 1454kThreadWaitPortSend = 0x04 1455kThreadWaitPortSendInTransit = 0x05 1456kThreadWaitSemaphore = 0x06 1457kThreadWaitKernelRWLockRead = 0x07 1458kThreadWaitKernelRWLockWrite = 0x08 1459kThreadWaitKernelRWLockUpgrade = 0x09 1460kThreadWaitUserLock = 0x0a 1461kThreadWaitPThreadMutex = 0x0b 1462kThreadWaitPThreadRWLockRead = 0x0c 1463kThreadWaitPThreadRWLockWrite = 0x0d 1464kThreadWaitPThreadCondVar = 0x0e 1465kThreadWaitParkedWorkQueue = 0x0f 1466kThreadWaitWorkloopSyncWait = 0x10 1467kThreadWaitOnProcess = 0x11 1468kThreadWaitSleepWithInheritor = 0x12 1469kThreadWaitEventlink = 0x13 1470kThreadWaitCompressor = 0x14 1471 1472 1473UINT64_MAX = 0xffffffffffffffff 1474STACKSHOT_WAITOWNER_KERNEL = (UINT64_MAX - 1) 1475STACKSHOT_WAITOWNER_PORT_LOCKED = (UINT64_MAX - 2) 1476STACKSHOT_WAITOWNER_PSET_LOCKED = (UINT64_MAX - 3) 1477STACKSHOT_WAITOWNER_INTRANSIT = (UINT64_MAX - 4) 1478STACKSHOT_WAITOWNER_MTXSPIN = (UINT64_MAX - 5) 1479STACKSHOT_WAITOWNER_THREQUESTED = (UINT64_MAX - 6) 1480STACKSHOT_WAITOWNER_SUSPENDED = (UINT64_MAX - 7) 1481 1482STACKSHOT_TURNSTILE_STATUS_UNKNOWN = 0x01 1483STACKSHOT_TURNSTILE_STATUS_LOCKED_WAITQ = 0x02 1484STACKSHOT_TURNSTILE_STATUS_WORKQUEUE = 0x04 1485STACKSHOT_TURNSTILE_STATUS_THREAD = 0x08 1486STACKSHOT_TURNSTILE_STATUS_BLOCKED_ON_TASK = 0x10 1487STACKSHOT_TURNSTILE_STATUS_HELD_IPLOCK = 0x20 1488 1489def formatWaitInfo(info, wantHex): 1490 base='#x' if wantHex else 'd' 1491 s = 'thread {0:{base}}: '.format(info['waiter'], base=base) 1492 type = info['wait_type'] 1493 context = info['context'] 1494 owner = info['owner'] 1495 ownerThread = "{0:{base}}".format(owner, base=base) 1496 if type == kThreadWaitKernelMutex: 1497 s += 'kernel mutex %x' % context 1498 if owner == STACKSHOT_WAITOWNER_MTXSPIN: 1499 s += " in spin mode" 1500 elif owner: 1501 s += " owned by thread %s" % ownerThread 1502 else: 1503 s += "with unknown owner" 1504 elif type == kThreadWaitPortReceive: 1505 s += "mach_msg receive on " 1506 if owner == STACKSHOT_WAITOWNER_PORT_LOCKED: 1507 s += "locked port %x" % context 1508 elif owner == STACKSHOT_WAITOWNER_INTRANSIT: 1509 s += "intransit port %x" % context 1510 elif owner: 1511 s += "port %x name %x" % (context, owner) 1512 else: 1513 s += "port %x" % context 1514 elif type == kThreadWaitPortSetReceive: 1515 if owner == STACKSHOT_WAITOWNER_PSET_LOCKED: 1516 s += "mach_msg receive on locked port set %x" % context 1517 else: 1518 s += "mach_msg receive on port set %x" % context 1519 elif type == kThreadWaitPortSend: 1520 s += "mach_msg send on " 1521 if owner == STACKSHOT_WAITOWNER_PORT_LOCKED: 1522 s += "locked port %x" % context 1523 elif owner == STACKSHOT_WAITOWNER_INTRANSIT: 1524 s += "intransit port %x" % context 1525 elif owner == STACKSHOT_WAITOWNER_KERNEL: 1526 s += "port %x owned by kernel" % context 1527 elif owner: 1528 s += "port %x owned by pid %d" % (context, owner) 1529 else: 1530 s += "port %x with unknown owner" % context 1531 elif type == kThreadWaitPortSendInTransit: 1532 s += "mach_msg send on port %x in transit to " % context 1533 if owner: 1534 s += "port %x" % owner 1535 else: 1536 s += "unknown port" 1537 elif type == kThreadWaitSemaphore: 1538 s += "semaphore port %x " % context 1539 if owner: 1540 s += "owned by pid %d" % owner 1541 else: 1542 s += "with unknown owner" 1543 elif type == kThreadWaitKernelRWLockRead: 1544 s += "krwlock %x for reading" % context 1545 elif type == kThreadWaitKernelRWLockWrite: 1546 s += "krwlock %x for writing" % context 1547 elif type == kThreadWaitKernelRWLockUpgrade: 1548 s += "krwlock %x for upgrading" % context 1549 elif type == kThreadWaitUserLock: 1550 if owner: 1551 s += "unfair lock %x owned by thread %s" % (context, ownerThread) 1552 else: 1553 s += "spin lock %x" % context 1554 elif type == kThreadWaitPThreadMutex: 1555 s += "pthread mutex %x" % context 1556 if owner: 1557 s += " owned by thread %s" % ownerThread 1558 else: 1559 s += " with unknown owner" 1560 elif type == kThreadWaitPThreadRWLockRead: 1561 s += "pthread rwlock %x for reading" % context 1562 elif type == kThreadWaitPThreadRWLockWrite: 1563 s += "pthread rwlock %x for writing" % context 1564 elif type == kThreadWaitPThreadCondVar: 1565 s += "pthread condvar %x" % context 1566 elif type == kThreadWaitWorkloopSyncWait: 1567 s += "workloop sync wait" 1568 if owner == STACKSHOT_WAITOWNER_SUSPENDED: 1569 s += ", suspended" 1570 elif owner == STACKSHOT_WAITOWNER_THREQUESTED: 1571 s += ", thread requested" 1572 elif owner != 0: 1573 s += ", owned by thread %s" % ownerThread 1574 else: 1575 s += ", unknown owner" 1576 s += ", workloop id %x" % context 1577 elif type == kThreadWaitOnProcess: 1578 if owner == 2**64-1: 1579 s += "waitpid, for any children" 1580 elif 2**32 <= owner and owner < 2**64-1: 1581 s += "waitpid, for process group %d" % abs(owner - 2**64) 1582 else: 1583 s += "waitpid, for pid %d" % owner 1584 elif type == kThreadWaitSleepWithInheritor: 1585 if owner == 0: 1586 s += "turnstile, held waitq" 1587 else: 1588 s += "turnstile, pushing thread %s" % ownerThread 1589 elif type == kThreadWaitEventlink: 1590 if owner == 0: 1591 s += "eventlink, held waitq" 1592 else: 1593 s += "eventlink, signaled by thread %s" % ownerThread 1594 elif type == kThreadWaitCompressor: 1595 s += "in compressor segment %x, busy for thread %s" % (context, ownerThread) 1596 1597 else: 1598 s += "unknown type %d (owner %s, context %x)" % (type, ownerThread, context) 1599 1600 return s 1601 1602def formatTurnstileInfo(ti): 1603 if ti is None: 1604 return " [no turnstile]" 1605 1606 ts_flags = int(ti['turnstile_flags']) 1607 ctx = int(ti['turnstile_context']) 1608 hop = int(ti['number_of_hops']) 1609 prio = int(ti['turnstile_priority']) 1610 if ts_flags & STACKSHOT_TURNSTILE_STATUS_HELD_IPLOCK: 1611 return " [turnstile blocked on task, but ip_lock was held]" 1612 if ts_flags & STACKSHOT_TURNSTILE_STATUS_BLOCKED_ON_TASK: 1613 return " [turnstile blocked on task pid %d, hops: %d, priority: %d]" % (ctx, hop, prio) 1614 if ts_flags & STACKSHOT_TURNSTILE_STATUS_LOCKED_WAITQ: 1615 return " [turnstile was in process of being updated]" 1616 if ts_flags & STACKSHOT_TURNSTILE_STATUS_WORKQUEUE: 1617 return " [blocked on workqueue: 0x%x, hops: %x, priority: %d]" % (ctx, hop, prio) 1618 if ts_flags & STACKSHOT_TURNSTILE_STATUS_THREAD: 1619 return " [blocked on: %d, hops: %x, priority: %d]" % (ctx, hop, prio) 1620 if ts_flags & STACKSHOT_TURNSTILE_STATUS_UNKNOWN: 1621 return " [turnstile with unknown inheritor]" 1622 1623 return " [unknown turnstile status!]" 1624 1625def formatWaitInfoWithTurnstiles(waitinfos, tsinfos): 1626 wis_tis = [] 1627 for w in waitinfos: 1628 found_pair = False 1629 for t in tsinfos: 1630 if int(w['waiter']) == int(t['waiter']): 1631 wis_tis.append((w, t)) 1632 found_pair = True 1633 break 1634 if not found_pair: 1635 wis_tis.append((w, None)) 1636 1637 return list(map(lambda x: formatWaitInfo(x[0], False) + formatTurnstileInfo(x[1]), wis_tis)) 1638 1639def SaveStackshotReport(j, outfile_name, incomplete): 1640 import time 1641 from operator import itemgetter, attrgetter 1642 ss = j.get('kcdata_stackshot') 1643 if not ss: 1644 print("No KCDATA_BUFFER_BEGIN_STACKSHOT object found. Skipping writing report.") 1645 return 1646 1647 timestamp = ss.get('usecs_since_epoch') 1648 try: 1649 timestamp = time.strftime("%Y-%m-%d %H:%M:%S +0000",time.gmtime(timestamp // 1000000 if timestamp else None)) 1650 except ValueError as e: 1651 print("couldn't convert timestamp:", str(e)) 1652 timestamp = None 1653 1654 os_version = ss.get('osversion', 'Unknown') 1655 timebase = ss.get('mach_timebase_info', {"denom": 1, "numer": 1}) 1656 1657 sc_note = None 1658 extra_note = None 1659 dsc_common = None 1660 shared_cache_info = ss.get('shared_cache_dyld_load_info') 1661 if shared_cache_info: 1662 shared_cache_base_addr = shared_cache_info['imageSlidBaseAddress'] 1663 # If we have a slidFirstMapping and it's >= base_address, use that. 1664 # 1665 # Otherwise we're processing a stackshot from before the slidFirstMapping 1666 # field was introduced and corrected. On ARM the SlidBaseAddress is the 1667 # same, but on x86 it's off by 0x20000000. We use 'X86_64' in the 1668 # kernel version string plus checking kern_page_size == 4k' as 1669 # proxy for x86_64, and only adjust SlidBaseAddress if the unslid 1670 # address is precisely the expected incorrect value. 1671 # 1672 is_intel = ('X86_64' in ss.get('osversion', "") and 1673 ss.get('kernel_page_size', 0) == 4096) 1674 slidFirstMapping = shared_cache_info.get(SC_SLID_FIRSTMAPPING_KEY, -1); 1675 if slidFirstMapping >= shared_cache_base_addr: 1676 shared_cache_base_addr = slidFirstMapping 1677 sc_note = "base-accurate" 1678 1679 elif is_intel: 1680 sc_slide = shared_cache_info['imageLoadAddress'] 1681 if (shared_cache_base_addr - sc_slide) == 0x7fff00000000: 1682 shared_cache_base_addr += 0x20000000 1683 sc_note = "base-x86-adjusted" 1684 extra_note = "Shared cache base adjusted for x86. " 1685 else: 1686 sc_note = "base-x86-unknown" 1687 1688 dsc_common = [format_uuid(shared_cache_info['imageUUID']), 1689 shared_cache_base_addr, "S" ] 1690 print("Shared cache UUID found from the binary data is <%s> " % str(dsc_common[0])) 1691 1692 dsc_layout = ss.get('system_shared_cache_layout') 1693 1694 dsc_libs = [] 1695 if dsc_layout: 1696 print("Found in memory system shared cache layout with {} images".format(len(dsc_layout))) 1697 slide = ss.get('shared_cache_dyld_load_info')['imageLoadAddress'] 1698 1699 for image in dsc_layout: 1700 dsc_libs.append([format_uuid(image['imageUUID']), image['imageLoadAddress'] + slide, "C"]) 1701 1702 AllImageCatalog = [] 1703 obj = {} 1704 obj["kernel"] = os_version 1705 if timestamp is not None: 1706 obj["date"] = timestamp 1707 obj["reason"] = "kernel panic stackshot" 1708 obj["incident"] = "ABCDEFGH-1234-56IJ-789K-0LMNOPQRSTUV" 1709 obj["crashReporterKey"] = "12ab34cd45aabbccdd6712ab34cd45aabbccdd67" 1710 obj["bootArgs"] = ss.get('boot_args','') 1711 obj["frontmostPids"] = [0] 1712 obj["exception"] = "0xDEADF157" 1713 obj["processByPid"] = {} 1714 if sc_note is not None: 1715 obj["sharedCacheNote"] = sc_note 1716 1717 if incomplete: 1718 obj["reason"] = "!!!INCOMPLETE!!! kernel panic stackshot" 1719 obj["notes"] = "Generated by xnu kcdata.py from incomplete data! Some information is missing! " 1720 else: 1721 obj["notes"] = "Generated by xnu kcdata.py. " 1722 1723 if extra_note is not None: 1724 obj["notes"] = obj["notes"] + extra_note 1725 1726 processByPid = obj["processByPid"] 1727 ssplist = ss.get('task_snapshots', {}) 1728 kern_load_info = [] 1729 if "0" in ssplist: 1730 kc_uuid = ssplist["0"].get('kernelcache_load_info', None) 1731 if kc_uuid: 1732 kernelcache_uuid = [format_uuid(kc_uuid['imageUUID']), kc_uuid['imageLoadAddress'], "U" ] 1733 kern_load_info.append(kernelcache_uuid) 1734 1735 kl_infos = ssplist["0"].get("dyld_load_info", []) 1736 for dlinfo in kl_infos: 1737 kern_load_info.append([format_uuid(dlinfo['imageUUID']), dlinfo['imageLoadAddress'], "K"]) 1738 1739 kl_infos_text_exec = ssplist["0"].get("dyld_load_info_text_exec", []) 1740 for dlinfo in kl_infos_text_exec: 1741 kern_load_info.append([format_uuid(dlinfo['imageUUID']), dlinfo['imageLoadAddress'], "T"]) 1742 1743 for pid,piddata in list(ssplist.items()): 1744 processByPid[str(pid)] = {} 1745 tsnap = processByPid[str(pid)] 1746 pr_lib_dsc = dsc_common 1747 1748 # see if there's an alternate shared cache 1749 scd = piddata.get('shared_cache_dyld_load_info') 1750 if scd is not None: 1751 if 'imageSlidBaseAddress' not in scd: 1752 print("Specific task shared cache format does not include slid shared cache base address. Skipping writing report.") 1753 return 1754 1755 scd_uuid = format_uuid(scd['imageUUID']) 1756 scd_base_addr = scd['imageSlidBaseAddress'] 1757 pr_lib_dsc = [scd_uuid, scd_base_addr, "S"] 1758 1759 pr_libs = [] 1760 if len(dsc_libs) == 0 and pr_lib_dsc: 1761 pr_libs.append(pr_lib_dsc) 1762 _lib_type = "P" 1763 if int(pid) == 0: 1764 _lib_type = "K" 1765 pr_libs = [] 1766 else: 1767 for dlinfo in piddata.get('dyld_load_info',[]): 1768 pr_libs.append([format_uuid(dlinfo['imageUUID']), dlinfo['imageLoadAddress'], _lib_type]) 1769 1770 pr_libs.extend(kern_load_info) 1771 pr_libs.extend(dsc_libs) 1772 1773 pr_libs.sort(key=itemgetter(1)) 1774 1775 if 'task_snapshot' not in piddata: 1776 continue 1777 tasksnap = piddata['task_snapshot'] 1778 tsnap["pid"] = tasksnap["ts_pid"] 1779 if 'ts_asid' in piddata: 1780 tsnap["asid"] = piddata["ts_asid"] 1781 1782 if 'ts_pagetable' in piddata: 1783 pagetables = [] 1784 for tte in piddata["ts_pagetable"]: 1785 pagetables.append(tte) 1786 tsnap["pageTables"] = pagetables 1787 1788 tsnap["residentMemoryBytes"] = tasksnap["ts_task_size"] 1789 tsnap["timesDidThrottle"] = tasksnap["ts_did_throttle"] 1790 tsnap["systemTimeTask"] = GetSecondsFromMATime(tasksnap["ts_system_time_in_terminated_th"], timebase) 1791 tsnap["pageIns"] = tasksnap["ts_pageins"] 1792 tsnap["pageFaults"] = tasksnap["ts_faults"] 1793 tsnap["userTimeTask"] = GetSecondsFromMATime(tasksnap[ "ts_user_time_in_terminated_thre"], timebase) 1794 tsnap["procname"] = tasksnap["ts_p_comm"] 1795 tsnap["copyOnWriteFaults"] = tasksnap["ts_cow_faults"] 1796 tsnap["timesThrottled"] = tasksnap["ts_was_throttled"] 1797 tsnap["threadById"] = {} 1798 threadByID = tsnap["threadById"] 1799 thlist = piddata.get('thread_snapshots', {}) 1800 for tid,thdata in list(thlist.items()): 1801 threadByID[str(tid)] = {} 1802 thsnap = threadByID[str(tid)] 1803 if "thread_snapshot" not in thdata: 1804 print("Found broken thread state for thread ID: %s." % tid) 1805 break 1806 threadsnap = thdata["thread_snapshot"] 1807 thsnap["userTime"] = GetSecondsFromMATime(threadsnap["ths_user_time"], timebase) 1808 thsnap["id"] = threadsnap["ths_thread_id"] 1809 thsnap["basePriority"] = threadsnap["ths_base_priority"] 1810 thsnap["systemTime"] = GetSecondsFromMATime(threadsnap["ths_sys_time"], timebase) 1811 thsnap["schedPriority"] = threadsnap["ths_sched_priority"] 1812 thsnap["state"] = GetStateDescription(threadsnap['ths_state']) 1813 thsnap["qosEffective"] = threadsnap["ths_eqos"] 1814 thsnap["qosRequested"] = threadsnap["ths_rqos"] 1815 1816 if "pth_name" in thdata: 1817 thsnap["name"] = thdata["pth_name"]; 1818 1819 if threadsnap['ths_continuation']: 1820 thsnap["continuation"] = GetSymbolInfoForFrame(AllImageCatalog, pr_libs, threadsnap['ths_continuation']) 1821 if "kernel_stack_frames" in thdata: 1822 kuserframes = [] 1823 for f in thdata["kernel_stack_frames"]: 1824 kuserframes.append(GetSymbolInfoForFrame(AllImageCatalog, pr_libs, f['lr'])) 1825 thsnap["kernelFrames"] = kuserframes 1826 1827 if "user_stack_frames" in thdata: 1828 uframes = [] 1829 for f in thdata["user_stack_frames"]: 1830 uframes.append(GetSymbolInfoForFrame(AllImageCatalog, pr_libs, f['lr'])) 1831 thsnap["userFrames"] = uframes 1832 1833 if "user_stacktop" in thdata: 1834 (address,) = struct.unpack("<Q", struct.pack("B"*8, *thdata["user_stacktop"]["stack_contents"])) 1835 thsnap["userStacktop"] = GetSymbolInfoForFrame(AllImageCatalog, pr_libs, address) 1836 1837 if threadsnap['ths_wait_event']: 1838 thsnap["waitEvent"] = GetSymbolInfoForFrame(AllImageCatalog, pr_libs, threadsnap['ths_wait_event']) 1839 1840 if 'thread_waitinfo' in piddata and 'thread_turnstileinfo' in piddata: 1841 tsnap['waitInfo'] = formatWaitInfoWithTurnstiles(piddata['thread_waitinfo'] , piddata['thread_turnstileinfo']) 1842 elif 'thread_waitinfo' in piddata: 1843 tsnap['waitInfo'] = [formatWaitInfo(x, False) for x in piddata['thread_waitinfo']] 1844 1845 obj['binaryImages'] = AllImageCatalog 1846 if outfile_name == '-': 1847 fh = sys.stdout 1848 else: 1849 fh = open(outfile_name, "w") 1850 1851 header = {} 1852 header['bug_type'] = 288 1853 if timestamp is not None: 1854 header['timestamp'] = timestamp 1855 header['os_version'] = os_version 1856 fh.write(json.dumps(header)) 1857 fh.write("\n") 1858 1859 fh.write(json.dumps(obj, sort_keys=False, indent=2, separators=(',', ': '))) 1860 fh.close() 1861 1862## Base utils for interacting with shell ## 1863def RunCommand(bash_cmd_string, get_stderr = True): 1864 """ 1865 returns: (int,str) : exit_code and output_str 1866 """ 1867 print("RUNNING: %s" % bash_cmd_string) 1868 cmd_args = shlex.split(bash_cmd_string) 1869 output_str = "" 1870 exit_code = 0 1871 try: 1872 if get_stderr: 1873 output_str = subprocess.check_output(cmd_args, stderr=subprocess.STDOUT) 1874 else: 1875 output_str = subprocess.check_output(cmd_args, stderr=None) 1876 except subprocess.CalledProcessError as e: 1877 exit_code = e.returncode 1878 finally: 1879 return (exit_code, output_str) 1880 1881 1882@contextlib.contextmanager 1883def data_from_stream(stream): 1884 try: 1885 fmap = mmap.mmap(stream.fileno(), 0, mmap.MAP_SHARED, mmap.PROT_READ) 1886 except: 1887 yield stream.read() 1888 else: 1889 try: 1890 yield fmap 1891 finally: 1892 fmap.close() 1893 1894def iterate_kcdatas(kcdata_file): 1895 with data_from_stream(kcdata_file) as data: 1896 iterator = kcdata_item_iterator(data) 1897 kcdata_buffer = KCObject.FromKCItem(six.next(iterator)) 1898 1899 if isinstance(kcdata_buffer, KCCompressedBufferObject): 1900 kcdata_buffer.ReadItems(iterator) 1901 decompressed = kcdata_buffer.Decompress(data) 1902 iterator = kcdata_item_iterator(decompressed) 1903 kcdata_buffer = KCObject.FromKCItem(six.next(iterator)) 1904 1905 if not isinstance(kcdata_buffer, KCBufferObject): 1906 # ktrace stackshot chunk 1907 iterator = kcdata_item_iterator(data[16:]) 1908 kcdata_buffer = KCObject.FromKCItem(six.next(iterator)) 1909 1910 if not isinstance(kcdata_buffer, KCBufferObject): 1911 try: 1912 decoded = base64.b64decode(data) 1913 except: 1914 pass 1915 else: 1916 iterator = kcdata_item_iterator(decoded) 1917 kcdata_buffer = KCObject.FromKCItem(six.next(iterator)) 1918 if not isinstance(kcdata_buffer, KCBufferObject): 1919 import gzip 1920 from io import BytesIO 1921 try: 1922 decompressed = gzip.GzipFile(fileobj=BytesIO(data[:])).read() 1923 except: 1924 pass 1925 else: 1926 iterator = kcdata_item_iterator(decompressed) 1927 kcdata_buffer = KCObject.FromKCItem(six.next(iterator)) 1928 1929 if not isinstance(kcdata_buffer, KCBufferObject): 1930 raise Exception("unknown file type") 1931 1932 1933 kcdata_buffer.ReadItems(iterator) 1934 yield kcdata_buffer 1935 1936 for magic in iterator: 1937 kcdata_buffer = KCObject.FromKCItem(magic) 1938 if kcdata_buffer.i_type == 0: 1939 continue 1940 if not isinstance(kcdata_buffer, KCBufferObject): 1941 raise Exception("unknown file type") 1942 kcdata_buffer.ReadItems(iterator) 1943 yield kcdata_buffer 1944 1945# 1946# Values for various flag fields. Each entry's key is the key seen in the 1947# processed kcdata, the value is an array of bits, from low (0x1) to high, with 1948# either a string flag name or None for unused holes. 1949# 1950# Only put flags in here which are stable - this is run against stackshots 1951# of all different versions. For anything unstable, we'll need a decoder ring 1952# added to the stackshot. 1953# 1954PRETTIFY_FLAGS = { 1955 'jcs_flags': [ 1956 'kCoalitionTermRequested', 1957 'kCoalitionTerminated', 1958 'kCoalitionReaped', 1959 'kCoalitionPrivileged', 1960 ], 1961 'stackshot_in_flags': [ # STACKSHOT_*, also stackshot_out_flags 1962 'get_dq', 1963 'save_loadinfo', 1964 'get_global_mem_stats', 1965 'save_kext_loadinfo', 1966 None, 1967 None, 1968 None, 1969 None, 1970 'active_kernel_threads_only', 1971 'get_boot_profile', 1972 'do_compress', 1973 None, 1974 None, 1975 'save_imp_donation_pids', 1976 'save_in_kernel_buffer', 1977 'retrieve_existing_buffer', 1978 'kcdata_format', 1979 'enable_bt_faulting', 1980 'collect_delta_snapshot', 1981 'collect_sharedcache_layout', 1982 'trylock', 1983 'enable_uuid_faulting', 1984 'from_panic', 1985 'no_io_stats', 1986 'thread_waitinfo', 1987 'thread_group', 1988 'save_jetsam_coalitions', 1989 'instrs_cycles', 1990 'asid', 1991 'page_tables', 1992 'disable_latency_info', 1993 ], 1994 'system_state_flags': [ 1995 'kUser64_p', 1996 'kKern64_p', 1997 ], 1998 'tgs_flags': [ 1999 'kThreadGroupEfficient', 2000 'kThreadGroupUIApp', 2001 ], 2002 'ths_ss_flags': [ 2003 'kUser64_p', 2004 'kKern64_p', 2005 'kHasDispatchSerial', 2006 'kStacksPCOnly', 2007 'kThreadDarwinBG', 2008 'kThreadIOPassive', 2009 'kThreadSuspended', 2010 'kThreadTruncatedBT', 2011 'kGlobalForcedIdle', 2012 'kThreadFaultedBT', 2013 'kThreadTriedFaultBT', 2014 'kThreadOnCore', 2015 'kThreadIdleWorker', 2016 'kThreadMain', 2017 'kThreadTruncKernBT', 2018 'kThreadTruncUserBT', 2019 'kThreadTruncUserAsyncBT', 2020 ], 2021 'ths_state': [ 2022 'TH_WAIT', 2023 'TH_SUSP', 2024 'TH_RUN', 2025 'TH_UNINT', 2026 'TH_TERMINATE', 2027 'TH_TERMINATE2', 2028 'TH_WAIT_REPORT', 2029 'TH_IDLE', 2030 ], 2031 'ts_ss_flags': [ 2032 'kUser64_p', 2033 'kKern64_p', 2034 'kTaskRsrcFlagged', 2035 'kTerminatedSnapshot', 2036 'kPidSuspended', 2037 'kFrozen', 2038 'kTaskDarwinBG', 2039 'kTaskExtDarwinBG', 2040 'kTaskVisVisible', 2041 'kTaskVisNonvisible', 2042 'kTaskIsForeground', 2043 'kTaskIsBoosted', 2044 'kTaskIsSuppressed', 2045 'kTaskIsTimerThrottled', 2046 'kTaskIsImpDonor', 2047 'kTaskIsLiveImpDonor', 2048 'kTaskIsDirty', 2049 'kTaskWqExceededConstrainedThreadLimit', 2050 'kTaskWqExceededTotalThreadLimit', 2051 'kTaskWqFlagsAvailable', 2052 'kTaskUUIDInfoFaultedIn', 2053 'kTaskUUIDInfoMissing', 2054 'kTaskUUIDInfoTriedFault', 2055 'kTaskSharedRegionInfoUnavailable', 2056 'kTaskTALEngaged', 2057 None, 2058 'kTaskIsDirtyTracked', 2059 'kTaskAllowIdleExit', 2060 'kTaskIsTranslated', 2061 'kTaskSharedRegionNone', 2062 'kTaskSharedRegionSystem', 2063 'kTaskSharedRegionOther', 2064 ], 2065 'turnstile_flags': [ 2066 'turnstile_status_unknown', 2067 'turnstile_status_locked_waitq', 2068 'turnstile_status_workqueue', 2069 'turnstile_status_thread', 2070 'turnstile_status_blocked_on_task', 2071 'turnstile_status_held_iplock', 2072 ], 2073} 2074PRETTIFY_FLAGS['stackshot_out_flags'] = PRETTIFY_FLAGS['stackshot_in_flags'] 2075 2076# Fields which should never be hexified 2077PRETTIFY_DONTHEX = { 2078 'stackshot_in_pid': True, 2079 'tts_pid': True, 2080 'ts_pid': True, 2081 'donating_pids': True, 2082 'ppid': True, 2083} 2084 2085# Only hex() the value if it is multiple digits 2086def prettify_hex(v): 2087 if v < -9 or v > 9: 2088 return hex(v) 2089 return str(v) 2090 2091def prettify_flags(v, flags): 2092 output="" 2093 seen = 0 2094 if v == 0: 2095 return "0" 2096 for (s, n) in zip(range(len(flags)),flags): 2097 if n is None: 2098 continue 2099 if (v & (2 ** s)): 2100 output += "|" + n 2101 seen |= 2 ** s 2102 if output == "": 2103 return prettify_hex(v) 2104 rest = (v & ~seen) 2105 if (rest != 0): 2106 output += "|" + prettify_hex(rest) 2107 return prettify_hex(v) + " (" + output[1:] + ")" 2108 2109def prettify_core(data, mosthex, key): 2110 if key == 'stack_contents': 2111 (address,) = struct.unpack("<Q", struct.pack("B"*8, *data)) 2112 return '0x%X' % address 2113 2114 elif isinstance(data, list): 2115 if 'uuid' in key.lower() and len(data) == 16: 2116 return '%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X' % tuple(data) 2117 2118 return [prettify_core(x, mosthex, key) for x in data] 2119 2120 elif key == 'thread_waitinfo': 2121 return formatWaitInfo(data, mosthex) 2122 2123 elif isinstance(data, dict): 2124 newdata = dict() 2125 for key, value in data.items(): 2126 if mosthex and key != 'task_snapshots' and len(key) > 0 and key.isnumeric(): 2127 key = prettify_hex(int(key)) 2128 newdata[key] = prettify_core(value, mosthex, key) 2129 return newdata 2130 2131 elif 'address' in key.lower() and isinstance(data, (int, long)): 2132 return '0x%X' % data 2133 elif key == 'lr' or key == SC_SLID_FIRSTMAPPING_KEY: 2134 return '0x%X' % data 2135 elif key in PRETTIFY_FLAGS and isinstance(data, (int, long)): 2136 return prettify_flags(data, PRETTIFY_FLAGS[key]) 2137 elif key.endswith('_flags') and isinstance(data, (int, long)): 2138 return prettify_hex(data) 2139 2140 elif mosthex and not PRETTIFY_DONTHEX.get(key, False): 2141 if isinstance(data, (int, long)): 2142 return prettify_hex(data) 2143 elif isinstance(data, six.string_types) and len(data) > 0 and data.isnumeric(): 2144 return prettify_hex(int(data)) 2145 return data 2146 2147 else: 2148 return data 2149 2150def prettify(data, mosthex): 2151 return prettify_core(data, mosthex, "") 2152 2153if __name__ == '__main__': 2154 parser = argparse.ArgumentParser(description="Decode a kcdata binary file.") 2155 parser.add_argument("-l", "--listtypes", action="store_true", required=False, default=False, 2156 help="List all known types", 2157 dest="list_known_types") 2158 2159 parser.add_argument("-s", "--stackshot", required=False, default=False, 2160 help="Generate a stackshot report file", 2161 dest="stackshot_file") 2162 2163 parser.add_argument("--multiple", help="look for multiple stackshots in a single file", action='store_true') 2164 2165 parser.add_argument("-p", "--plist", required=False, default=False, 2166 help="output as plist", action="store_true") 2167 2168 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") 2169 parser.add_argument("-P", "--pretty", default=False, action='store_true', help="make the output a little more human readable") 2170 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") 2171 parser.add_argument("--incomplete", action='store_true', help="accept incomplete data") 2172 parser.add_argument("kcdata_file", type=argparse.FileType('r'), help="Path to a kcdata binary file.") 2173 2174 class VerboseAction(argparse.Action): 2175 def __call__(self, parser, namespace, values, option_string=None): 2176 logging.basicConfig(level=logging.INFO, stream=sys.stderr, format='%(message)s') 2177 parser.add_argument('-v', "--verbose", action=VerboseAction, nargs=0) 2178 2179 args = parser.parse_args() 2180 2181 if args.multiple and args.stackshot_file: 2182 raise NotImplementedError 2183 2184 if args.list_known_types: 2185 for (n, t) in KNOWN_TYPES_COLLECTION.items(): 2186 print("%d : %s " % (n, str(t))) 2187 sys.exit(1) 2188 2189 if args.incomplete or args.stackshot_file: 2190 G.accept_incomplete_data = True 2191 2192 for i,kcdata_buffer in enumerate(iterate_kcdatas(args.kcdata_file)): 2193 if i > 0 and not args.multiple: 2194 break 2195 2196 str_data = "{" + kcdata_buffer.GetJsonRepr() + "}" 2197 str_data = str_data.replace("\t", " ") 2198 2199 try: 2200 json_obj = json.loads(str_data) 2201 except: 2202 print("JSON reparsing failed! Printing string data!\n", file=sys.stderr) 2203 import textwrap 2204 print(textwrap.fill(str_data, 100)) 2205 raise 2206 2207 if args.prettyhex: 2208 json_obj = prettify(json_obj, True) 2209 elif args.pretty: 2210 json_obj = prettify(json_obj, False) 2211 2212 if args.stackshot_file: 2213 SaveStackshotReport(json_obj, args.stackshot_file, G.data_was_incomplete) 2214 elif args.plist: 2215 import Foundation 2216 plist = Foundation.NSPropertyListSerialization.dataWithPropertyList_format_options_error_( 2217 json_obj, Foundation.NSPropertyListXMLFormat_v1_0, 0, None)[0].bytes().tobytes() 2218 #sigh. on some pythons long integers are getting output with L's in the plist. 2219 plist = re.sub(r'^(\s*<integer>\d+)L(</integer>\s*)$', r"\1\2", BytesToString(plist), flags=re.MULTILINE) 2220 print(plist,) 2221 else: 2222 print(json.dumps(json_obj, sort_keys=True, indent=4, separators=(',', ': '))) 2223