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