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