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