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 KCSubTypeElement.FromBasicCtype('eas_asroot', KCSUBTYPE_TYPE.KC_ST_UINT64, 32), 1485 ), 'exclave_addressspace_info') 1486 1487KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_EXCLAVE_ADDRESSSPACE_NAME')] = KCSubTypeElement('exclave_addressspace_name', KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(64, 1), 0, 1) 1488 1489KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_EXCLAVE_TEXTLAYOUT_INFO')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_EXCLAVE_TEXTLAYOUT_INFO'), 1490 ( 1491 KCSubTypeElement.FromBasicCtype('layout_id', KCSUBTYPE_TYPE.KC_ST_UINT64, 0), 1492 KCSubTypeElement.FromBasicCtype('etl_flags', KCSUBTYPE_TYPE.KC_ST_UINT64, 8), 1493 ), 'exclave_textlayout_info') 1494 1495KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_EXCLAVE_TEXTLAYOUT_SEGMENTS')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_EXCLAVE_TEXTLAYOUT_SEGMENTS'), 1496 ( 1497 KCSubTypeElement('layoutSegment_uuid', KCSUBTYPE_TYPE.KC_ST_UINT8, KCSubTypeElement.GetSizeForArray(16, 1), 0, 1), 1498 KCSubTypeElement.FromBasicCtype('layoutSegment_loadAddress', KCSUBTYPE_TYPE.KC_ST_UINT64, 16), 1499 ), 'exclave_textlayout_segments') 1500 1501def GetSecondsFromMATime(mat, tb): 1502 return (float(long(mat) * tb['numer']) / tb['denom']) / 1e9 1503 1504def GetLongForAddress(address): 1505 if isinstance(address, str): 1506 if '0x' in address.lower(): 1507 address = long(address, 16) 1508 else: 1509 address = long(address) 1510 return address 1511 1512def FindLibraryForAddress(liblist, address): 1513 current_lib = None 1514 for l in liblist: 1515 l_addr = GetLongForAddress(l[1]) 1516 if address >= l_addr: 1517 current_lib = l 1518 return current_lib 1519 1520def FindIndexOfLibInCatalog(catalog, lib): 1521 index = None 1522 i = 0 1523 for l in catalog: 1524 if l[0] == lib[0] and l[1] == lib[1]: 1525 index = i 1526 break 1527 i += 1 1528 1529 if index is None: 1530 catalog.append(lib) 1531 index = len(catalog) - 1 1532 1533 return index 1534 1535def GetOffsetOfAddressForLib(lib, address): 1536 return (address - GetLongForAddress(lib[1])) 1537 1538def GetSymbolInfoForFrame(catalog, liblist, address): 1539 address = GetLongForAddress(address) 1540 lib = FindLibraryForAddress(liblist, address) 1541 if not lib: 1542 lib = ["00000000000000000000000000000000",0,"A"] 1543 offset = GetOffsetOfAddressForLib(lib, address) 1544 index = FindIndexOfLibInCatalog(catalog, lib) 1545 return [index, offset] 1546 1547def GetStateDescription(s): 1548 retval = [] 1549 TH_WAIT = 0x01 1550 TH_SUSP = 0x02 1551 TH_RUN = 0x04 1552 TH_UNINT = 0x08 1553 TH_TERMINATE = 0x10 1554 TH_TERMINATE2 = 0x20 1555 TH_WAIT_REPORT = 0x40 1556 TH_IDLE = 0x80 1557 if (s & TH_WAIT): 1558 retval.append("TH_WAIT") 1559 if (s & TH_SUSP): 1560 retval.append("TH_SUSP") 1561 if (s & TH_RUN): 1562 retval.append("TH_RUN") 1563 if (s & TH_UNINT): 1564 retval.append("TH_UNINT") 1565 if (s & TH_TERMINATE): 1566 retval.append("TH_TERMINATE") 1567 if (s & TH_TERMINATE2): 1568 retval.append("TH_TERMINATE2") 1569 if (s & TH_WAIT_REPORT): 1570 retval.append("TH_WAIT_REPORT") 1571 if (s & TH_IDLE): 1572 retval.append("TH_IDLE") 1573 return retval 1574 1575 1576def format_uuid(elementValues): 1577 # sometimes we get string like "25A926D8-F742-3E5E..." 1578 if isinstance(elementValues, str): 1579 return elementValues 1580 return ''.join("%02x" % i for i in elementValues) 1581 1582kThreadWaitNone = 0x00 1583kThreadWaitKernelMutex = 0x01 1584kThreadWaitPortReceive = 0x02 1585kThreadWaitPortSetReceive = 0x03 1586kThreadWaitPortSend = 0x04 1587kThreadWaitPortSendInTransit = 0x05 1588kThreadWaitSemaphore = 0x06 1589kThreadWaitKernelRWLockRead = 0x07 1590kThreadWaitKernelRWLockWrite = 0x08 1591kThreadWaitKernelRWLockUpgrade = 0x09 1592kThreadWaitUserLock = 0x0a 1593kThreadWaitPThreadMutex = 0x0b 1594kThreadWaitPThreadRWLockRead = 0x0c 1595kThreadWaitPThreadRWLockWrite = 0x0d 1596kThreadWaitPThreadCondVar = 0x0e 1597kThreadWaitParkedWorkQueue = 0x0f 1598kThreadWaitWorkloopSyncWait = 0x10 1599kThreadWaitOnProcess = 0x11 1600kThreadWaitSleepWithInheritor = 0x12 1601kThreadWaitEventlink = 0x13 1602kThreadWaitCompressor = 0x14 1603 1604 1605UINT64_MAX = 0xffffffffffffffff 1606STACKSHOT_WAITOWNER_KERNEL = (UINT64_MAX - 1) 1607STACKSHOT_WAITOWNER_PORT_LOCKED = (UINT64_MAX - 2) 1608STACKSHOT_WAITOWNER_PSET_LOCKED = (UINT64_MAX - 3) 1609STACKSHOT_WAITOWNER_INTRANSIT = (UINT64_MAX - 4) 1610STACKSHOT_WAITOWNER_MTXSPIN = (UINT64_MAX - 5) 1611STACKSHOT_WAITOWNER_THREQUESTED = (UINT64_MAX - 6) 1612STACKSHOT_WAITOWNER_SUSPENDED = (UINT64_MAX - 7) 1613 1614STACKSHOT_TURNSTILE_STATUS_UNKNOWN = 0x01 1615STACKSHOT_TURNSTILE_STATUS_LOCKED_WAITQ = 0x02 1616STACKSHOT_TURNSTILE_STATUS_WORKQUEUE = 0x04 1617STACKSHOT_TURNSTILE_STATUS_THREAD = 0x08 1618STACKSHOT_TURNSTILE_STATUS_BLOCKED_ON_TASK = 0x10 1619STACKSHOT_TURNSTILE_STATUS_HELD_IPLOCK = 0x20 1620STACKSHOT_TURNSTILE_STATUS_SENDPORT = 0x40 1621STACKSHOT_TURNSTILE_STATUS_RECEIVEPORT = 0x80 1622 1623# 1624# These come from xpc_domain_type_t in <xpc/launch_private.h> 1625PORTLABEL_DOMAINS = { 1626 1: 'system', # XPC_DOMAIN_SYSTEM 1627 2: 'user', # XPC_DOMAIN_USER 1628 5: 'pid', # XPC_DOMAIN_PID 1629 7: 'port', # XPC_DOMAIN_PORT 1630} 1631def portlabel_domain(x): 1632 if x is None: 1633 return "unknown" 1634 return PORTLABEL_DOMAINS.get(x, "unknown.{}".format(x)) 1635 1636STACKSHOT_WAITINFO_FLAGS_SPECIALREPLY = 0x1 1637STACKSHOT_PORTLABEL_THROTTLED = 0x2 1638 1639def portThrottledSuffix(portlabel_flags): 1640 if (portlabel_flags & STACKSHOT_PORTLABEL_THROTTLED): 1641 return " (service port throttled by launchd)" 1642 else: 1643 return "" 1644 1645def formatPortLabelID(portlabel_id, portlabels): 1646 portlabel = {} 1647 if portlabel_id > 0: 1648 if portlabels is not None: 1649 portlabel = portlabels.get(str(portlabel_id), {}) 1650 portlabel_name = portlabel_domain(portlabel.get('portlabel_domain')) + " " 1651 portlabel_name += portlabel.get("portlabel_name", "!!!unknown, ID {} !!!".format(portlabel_id)); 1652 return " {" + portlabel_name + portThrottledSuffix(portlabel.get('portlabel_flags', 0)) + "}" 1653 if portlabel_id < 0: 1654 return " {labeled, info truncated" + portThrottledSuffix(portlabel.get('portlabel_flags', 0)) + "}" 1655 return "" 1656 1657def formatWaitInfo(info, wantHex, portlabels): 1658 base='#x' if wantHex else 'd' 1659 s = 'thread {0:{base}}: '.format(info['waiter'], base=base) 1660 type = info['wait_type'] 1661 context = info['context'] 1662 owner = info['owner'] 1663 ownerThread = "{0:{base}}".format(owner, base=base) 1664 portlabel_id = info.get('portlabel_id', 0) 1665 flags = info.get('wait_flags', 0) 1666 1667 if type == kThreadWaitKernelMutex: 1668 s += 'kernel mutex %x' % context 1669 if owner == STACKSHOT_WAITOWNER_MTXSPIN: 1670 s += " in spin mode" 1671 elif owner: 1672 s += " owned by thread %s" % ownerThread 1673 else: 1674 s += "with unknown owner" 1675 elif type == kThreadWaitPortReceive: 1676 s += "mach_msg receive on " 1677 if flags & STACKSHOT_WAITINFO_FLAGS_SPECIALREPLY: 1678 s += "REPLY " 1679 flags = flags - STACKSHOT_WAITINFO_FLAGS_SPECIALREPLY 1680 if owner == STACKSHOT_WAITOWNER_PORT_LOCKED: 1681 s += "locked port %x" % context 1682 elif owner == STACKSHOT_WAITOWNER_INTRANSIT: 1683 s += "intransit port %x" % context 1684 elif owner: 1685 s += "port %x name %x" % (context, owner) 1686 else: 1687 s += "port %x" % context 1688 elif type == kThreadWaitPortSetReceive: 1689 if owner == STACKSHOT_WAITOWNER_PSET_LOCKED: 1690 s += "mach_msg receive on locked port set %x" % context 1691 else: 1692 s += "mach_msg receive on port set %x" % context 1693 elif type == kThreadWaitPortSend: 1694 s += "mach_msg send on " 1695 if owner == STACKSHOT_WAITOWNER_PORT_LOCKED: 1696 s += "locked port %x" % context 1697 elif owner == STACKSHOT_WAITOWNER_INTRANSIT: 1698 s += "intransit port %x" % context 1699 elif owner == STACKSHOT_WAITOWNER_KERNEL: 1700 s += "port %x owned by kernel" % context 1701 elif owner: 1702 s += "port %x owned by pid %d" % (context, owner) 1703 else: 1704 s += "port %x with unknown owner" % context 1705 elif type == kThreadWaitPortSendInTransit: 1706 s += "mach_msg send on port %x in transit to " % context 1707 if owner: 1708 s += "port %x" % owner 1709 else: 1710 s += "unknown port" 1711 elif type == kThreadWaitSemaphore: 1712 s += "semaphore port %x " % context 1713 if owner: 1714 s += "owned by pid %d" % owner 1715 else: 1716 s += "with unknown owner" 1717 elif type == kThreadWaitKernelRWLockRead: 1718 s += "krwlock %x for reading" % context 1719 if owner: 1720 s += " owned by thread %s" % ownerThread 1721 elif type == kThreadWaitKernelRWLockWrite: 1722 s += "krwlock %x for writing" % context 1723 if owner: 1724 s += " owned by thread %s" % ownerThread 1725 elif type == kThreadWaitKernelRWLockUpgrade: 1726 s += "krwlock %x for upgrading" % context 1727 if owner: 1728 s += " owned by thread %s" % ownerThread 1729 elif type == kThreadWaitUserLock: 1730 if owner: 1731 s += "unfair lock %x owned by thread %s" % (context, ownerThread) 1732 else: 1733 s += "spin lock %x" % context 1734 elif type == kThreadWaitPThreadMutex: 1735 s += "pthread mutex %x" % context 1736 if owner: 1737 s += " owned by thread %s" % ownerThread 1738 else: 1739 s += " with unknown owner" 1740 elif type == kThreadWaitPThreadRWLockRead: 1741 s += "pthread rwlock %x for reading" % context 1742 elif type == kThreadWaitPThreadRWLockWrite: 1743 s += "pthread rwlock %x for writing" % context 1744 elif type == kThreadWaitPThreadCondVar: 1745 s += "pthread condvar %x" % context 1746 elif type == kThreadWaitWorkloopSyncWait: 1747 s += "workloop sync wait" 1748 if owner == STACKSHOT_WAITOWNER_SUSPENDED: 1749 s += ", suspended" 1750 elif owner == STACKSHOT_WAITOWNER_THREQUESTED: 1751 s += ", thread requested" 1752 elif owner != 0: 1753 s += ", owned by thread %s" % ownerThread 1754 else: 1755 s += ", unknown owner" 1756 s += ", workloop id %x" % context 1757 elif type == kThreadWaitOnProcess: 1758 if owner == 2**64-1: 1759 s += "waitpid, for any children" 1760 elif 2**32 <= owner and owner < 2**64-1: 1761 s += "waitpid, for process group %d" % abs(owner - 2**64) 1762 else: 1763 s += "waitpid, for pid %d" % owner 1764 elif type == kThreadWaitSleepWithInheritor: 1765 if owner == 0: 1766 s += "turnstile, held waitq" 1767 else: 1768 s += "turnstile, pushing thread %s" % ownerThread 1769 elif type == kThreadWaitEventlink: 1770 if owner == 0: 1771 s += "eventlink, held waitq" 1772 else: 1773 s += "eventlink, signaled by thread %s" % ownerThread 1774 elif type == kThreadWaitCompressor: 1775 s += "in compressor segment %x, busy for thread %s" % (context, ownerThread) 1776 1777 else: 1778 s += "unknown type %d (owner %s, context %x)" % (type, ownerThread, context) 1779 1780 s += formatPortLabelID(portlabel_id, portlabels) 1781 1782 if flags != 0: 1783 s += "flags {}".format(hex(flags)) 1784 return s 1785 1786def formatTurnstileInfo(ti, wi_portlabel_id, portlabels): 1787 if ti is None: 1788 return " [no turnstile]" 1789 1790 ts_flags = int(ti['turnstile_flags']) 1791 ctx = int(ti['turnstile_context']) 1792 hop = int(ti['number_of_hops']) 1793 prio = int(ti['turnstile_priority']) 1794 portlabel_id = ti.get("portlabel_id", 0) 1795 1796 portlabel_summary = "" 1797 if portlabel_id != 0 and portlabel_id != wi_portlabel_id: 1798 portlabel_summary += formatPortLabelID(portlabel_id, portlabels) 1799 1800 if ts_flags & STACKSHOT_TURNSTILE_STATUS_HELD_IPLOCK: 1801 return " [turnstile blocked on task, but ip_lock was held]" + portlabel_summary 1802 if ts_flags & STACKSHOT_TURNSTILE_STATUS_BLOCKED_ON_TASK: 1803 return " [turnstile blocked on task pid %d, hops: %d, priority: %d]%s" % (ctx, hop, prio, portlabel_summary) 1804 if ts_flags & STACKSHOT_TURNSTILE_STATUS_LOCKED_WAITQ: 1805 return " [turnstile was in process of being updated]" + portlabel_summary 1806 if ts_flags & STACKSHOT_TURNSTILE_STATUS_WORKQUEUE: 1807 return " [blocked on workqueue: 0x%x, hops: %x, priority: %d]%s" % (ctx, hop, prio, portlabel_summary) 1808 if ts_flags & STACKSHOT_TURNSTILE_STATUS_THREAD: 1809 return " [blocked on: %d, hops: %x, priority: %d]%s" % (ctx, hop, prio, portlabel_summary) 1810 if ts_flags & STACKSHOT_TURNSTILE_STATUS_UNKNOWN: 1811 return " [turnstile with unknown inheritor]" + portlabel_summary 1812 1813 return " [unknown turnstile status!]" + portlabel_summary 1814 1815def formatWaitInfoWithTurnstiles(waitinfos, tsinfos, portlabels): 1816 wis_tis = [] 1817 for w in waitinfos: 1818 found_pair = False 1819 for t in tsinfos: 1820 if int(w['waiter']) == int(t['waiter']): 1821 wis_tis.append((w, t)) 1822 found_pair = True 1823 break 1824 if not found_pair: 1825 wis_tis.append((w, None)) 1826 1827 return [formatWaitInfo(wi, False, portlabels) + formatTurnstileInfo(ti, wi.get('portlabel_id', 0), portlabels) for (wi, ti) in wis_tis] 1828 1829 1830def FindTextLayout(text_layouts, text_layout_id): 1831 for layout in text_layouts.values(): 1832 if layout['exclave_textlayout_info']['layout_id'] == text_layout_id: 1833 return layout 1834 return None 1835 1836 1837def GetExclaveLibs(text_layouts, text_layout_id): 1838 from operator import itemgetter 1839 textlayout = FindTextLayout(text_layouts, text_layout_id) 1840 exclave_libs = [ [format_uuid(layout['layoutSegment_uuid']), layout['layoutSegment_loadAddress'], 'P'] for layout in textlayout['exclave_textlayout_segments'] ] 1841 exclave_libs.sort(key=itemgetter(1)) 1842 return exclave_libs 1843 1844 1845# kcdata is json at path 'kcdata_stackshot/threads_exclave/0' 1846def GetEASFrames(AllImageCatalog, kcdata, ipc_entry, notes, scid): 1847 info = ipc_entry['exclave_ipcstackentry_info'] 1848 asid = info['eise_asid'] 1849 1850 address_spaces = kcdata['exclave_addressspace'] 1851 as_info = address_spaces.get(str(asid)) 1852 if not as_info: 1853 notes.warn("PID ${PID} TID ${TID} SCID %d Missing address space info for ASID 0x%x" % (scid, asid)) 1854 return [] 1855 text_layout_id = as_info['exclave_addressspace_info']['eas_layoutid'] 1856 addr_space_name = as_info['exclave_addressspace_name'] 1857 1858 exclave_libs = GetExclaveLibs(kcdata['exclave_textlayout'], text_layout_id) 1859 1860 frames = [] 1861 stack = ipc_entry['secure_ecstack_entry'] 1862 for stack_item in stack: 1863 lr = GetLongForAddress(stack_item['lr']) 1864 # this is a buggy value of unknown origin 1865 # rdar://123508690 (Some Exclave Stackshot frames ends with invalid value 0xFFFF000000000000) 1866 if lr == 0xFFFF000000000000: 1867 continue 1868 frames.append(GetSymbolInfoForFrame(AllImageCatalog, exclave_libs, lr)) 1869 1870 if frames: 1871 frame_info = "frames %d to %d" % (notes.offset, notes.offset + len(frames) - 1) 1872 else: 1873 frame_info = "no frames" 1874 notes.info("PID ${PID} TID ${TID} SCID %d ASID 0x%x has address space name '%s' (%s)" % (scid, asid, addr_space_name, frame_info)) 1875 notes.addToOffset(len(frames)) 1876 return frames 1877 1878 1879def GetExclavesFrames(AllImageCatalog, json, scid, notes): 1880 kcdata = json['kcdata_stackshot'] 1881 threads_exclave = kcdata.get('threads_exclave') 1882 if not threads_exclave: 1883 notes.warn("PID ${PID} TID ${TID} no threads_exclave info found, skipping exclaves frames") 1884 return [] 1885 1886 exclaves_content = threads_exclave.get('0') 1887 if not exclaves_content: 1888 notes.warn("PID ${PID} TID ${TID} threads_exclave data not found, skipping exclaves frames") 1889 return [] 1890 1891 threads_info = exclaves_content.get('thread_exclave') 1892 if not threads_info: 1893 notes.warn("PID ${PID} TID ${TID} no thread_exclave info found, skipping exclaves frames") 1894 return [] 1895 1896 scid_info = threads_info.get(str(scid)) 1897 if not scid_info: 1898 notes.warn("PID ${PID} TID ${TID} no exclaves info available for SCID %d, skipping exclaves frames" % scid) 1899 return [] 1900 1901 frames = [] 1902 1903 ipc_stack = scid_info["exclave_ipcstackentry"] 1904 notes.info("\nPID ${PID} TID ${TID} SCID %d has IPC chain with %d items:" % (scid, len(ipc_stack))) 1905 for i in reversed(range(len(ipc_stack))): 1906 ipc_entry = ipc_stack[str(i)] 1907 entry_frames = GetEASFrames(AllImageCatalog, exclaves_content, ipc_entry, notes, scid) 1908 frames.extend(entry_frames) 1909 1910 return frames 1911 1912 1913def InsertExclavesFrames(AllImageCatalog, json, thdata, notes, kernel_frames): 1914 thread_info = thdata.get('exclaves_thread_info') 1915 if not thread_info: 1916 # this is not exclave thread 1917 return 1918 1919 scid = thread_info["tei_scid"] 1920 offset = thread_info["tei_thread_offset"] 1921 notes.offset = offset 1922 1923 exclaves_frames = GetExclavesFrames(AllImageCatalog, json, scid, notes) 1924 1925 # insert exclaves frames to offset 1926 for i in range(len(exclaves_frames)): 1927 kernel_frames.insert(offset + i, exclaves_frames[i]) 1928 1929class NotesBuilder: 1930 1931 notes = [] 1932 pid = None 1933 tis = None 1934 offset = 0 1935 1936 def __init__(self, pid, tid): 1937 self.pid = pid 1938 self.tid = tid 1939 self.notes = [] 1940 self.offset = 0 # offset of next IPC stack in kernel stack 1941 1942 # Replace ${PID} with a PID and ${TID} with TID and add newline 1943 def format(self, note): 1944 note = note.replace('${PID}', str(self.pid)) 1945 note = note.replace('${TID}', str(self.tid)) 1946 return note + '\n' 1947 1948 def warn(self, note): 1949 note = self.format(note) 1950 sys.stdout.write(note) 1951 self.notes.append(note) 1952 1953 def info(self, note): 1954 note = self.format(note) 1955 self.notes.append(note) 1956 1957 def isEmpty(self): 1958 return len(self.notes) == 0 1959 1960 def text(self): 1961 return ''.join(self.notes) 1962 1963 def addToOffset(self, frame_count): 1964 self.offset += frame_count 1965 1966def SaveStackshotReport(j, outfile_name, incomplete): 1967 import time 1968 from operator import itemgetter, attrgetter 1969 ss = j.get('kcdata_stackshot') 1970 if not ss: 1971 print("No KCDATA_BUFFER_BEGIN_STACKSHOT object found. Skipping writing report.") 1972 return 1973 1974 timestamp = ss.get('usecs_since_epoch') 1975 try: 1976 timestamp = time.strftime("%Y-%m-%d %H:%M:%S +0000",time.gmtime(timestamp // 1000000 if timestamp else None)) 1977 except ValueError as e: 1978 print("couldn't convert timestamp:", str(e)) 1979 timestamp = None 1980 1981 os_version = ss.get('osversion', 'Unknown') 1982 timebase = ss.get('mach_timebase_info', {"denom": 1, "numer": 1}) 1983 1984 sc_note = None 1985 extra_note = None 1986 dsc_common = None 1987 shared_cache_info = ss.get('shared_cache_dyld_load_info') 1988 if shared_cache_info: 1989 shared_cache_base_addr = shared_cache_info['imageSlidBaseAddress'] 1990 # If we have a slidFirstMapping and it's >= base_address, use that. 1991 # 1992 # Otherwise we're processing a stackshot from before the slidFirstMapping 1993 # field was introduced and corrected. On ARM the SlidBaseAddress is the 1994 # same, but on x86 it's off by 0x20000000. We use 'X86_64' in the 1995 # kernel version string plus checking kern_page_size == 4k' as 1996 # proxy for x86_64, and only adjust SlidBaseAddress if the unslid 1997 # address is precisely the expected incorrect value. 1998 # 1999 is_intel = ('X86_64' in ss.get('osversion', "") and 2000 ss.get('kernel_page_size', 0) == 4096) 2001 slidFirstMapping = shared_cache_info.get(SC_SLID_FIRSTMAPPING_KEY, -1); 2002 if slidFirstMapping >= shared_cache_base_addr: 2003 shared_cache_base_addr = slidFirstMapping 2004 sc_note = "base-accurate" 2005 2006 elif is_intel: 2007 sc_slide = shared_cache_info['imageLoadAddress'] 2008 if (shared_cache_base_addr - sc_slide) == 0x7fff00000000: 2009 shared_cache_base_addr += 0x20000000 2010 sc_note = "base-x86-adjusted" 2011 extra_note = "Shared cache base adjusted for x86. " 2012 else: 2013 sc_note = "base-x86-unknown" 2014 2015 dsc_common = [format_uuid(shared_cache_info['imageUUID']), 2016 shared_cache_base_addr, "S" ] 2017 print("Shared cache UUID found from the binary data is <%s> " % str(dsc_common[0])) 2018 2019 dsc_layout = ss.get('system_shared_cache_layout') 2020 2021 dsc_libs = [] 2022 if dsc_layout: 2023 print("Found in memory system shared cache layout with {} images".format(len(dsc_layout))) 2024 slide = ss.get('shared_cache_dyld_load_info')['imageLoadAddress'] 2025 2026 for image in dsc_layout: 2027 dsc_libs.append([format_uuid(image['imageUUID']), image['imageLoadAddress'] + slide, "C"]) 2028 2029 AllImageCatalog = [] 2030 obj = {} 2031 obj["kernel"] = os_version 2032 if timestamp is not None: 2033 obj["date"] = timestamp 2034 obj["reason"] = "kernel panic stackshot" 2035 obj["incident"] = "ABCDEFGH-1234-56IJ-789K-0LMNOPQRSTUV" 2036 obj["crashReporterKey"] = "12ab34cd45aabbccdd6712ab34cd45aabbccdd67" 2037 obj["bootArgs"] = ss.get('boot_args','') 2038 obj["frontmostPids"] = [0] 2039 obj["exception"] = "0xDEADF157" 2040 obj["processByPid"] = {} 2041 if sc_note is not None: 2042 obj["sharedCacheNote"] = sc_note 2043 2044 if incomplete: 2045 obj["reason"] = "!!!INCOMPLETE!!! kernel panic stackshot" 2046 obj["notes"] = "Generated by xnu kcdata.py from incomplete data! Some information is missing! " 2047 else: 2048 obj["notes"] = "Generated by xnu kcdata.py. " 2049 2050 if extra_note is not None: 2051 obj["notes"] = obj["notes"] + extra_note 2052 2053 processByPid = obj["processByPid"] 2054 ssplist = ss.get('task_snapshots', {}) 2055 ssplist.update(ss.get('transitioning_task_snapshots', {})) 2056 kern_load_info = [] 2057 if "0" in ssplist: 2058 kc_uuid = ssplist["0"].get('kernelcache_load_info', None) 2059 if kc_uuid: 2060 kernelcache_uuid = [format_uuid(kc_uuid['imageUUID']), kc_uuid['imageLoadAddress'], "U" ] 2061 kern_load_info.append(kernelcache_uuid) 2062 2063 kl_infos = ssplist["0"].get("dyld_load_info", []) 2064 for dlinfo in kl_infos: 2065 kern_load_info.append([format_uuid(dlinfo['imageUUID']), dlinfo['imageLoadAddress'], "K"]) 2066 2067 kl_infos_text_exec = ssplist["0"].get("dyld_load_info_text_exec", []) 2068 for dlinfo in kl_infos_text_exec: 2069 kern_load_info.append([format_uuid(dlinfo['imageUUID']), dlinfo['imageLoadAddress'], "T"]) 2070 2071 for pid,piddata in sorted(ssplist.items()): 2072 processByPid[str(pid)] = {} 2073 tsnap = processByPid[str(pid)] 2074 pr_lib_dsc = dsc_common 2075 2076 # see if there's an alternate shared cache 2077 scd = piddata.get('shared_cache_dyld_load_info') 2078 if scd is not None: 2079 if 'imageSlidBaseAddress' not in scd: 2080 print("Specific task shared cache format does not include slid shared cache base address. Skipping writing report.") 2081 return 2082 2083 scd_uuid = format_uuid(scd['imageUUID']) 2084 scd_base_addr = scd['imageSlidBaseAddress'] 2085 pr_lib_dsc = [scd_uuid, scd_base_addr, "S"] 2086 2087 pr_libs = [] 2088 if len(dsc_libs) == 0 and pr_lib_dsc: 2089 pr_libs.append(pr_lib_dsc) 2090 _lib_type = "P" 2091 if int(pid) == 0: 2092 _lib_type = "K" 2093 pr_libs = [] 2094 else: 2095 for dlinfo in piddata.get('dyld_load_info',[]): 2096 pr_libs.append([format_uuid(dlinfo['imageUUID']), dlinfo['imageLoadAddress'], _lib_type]) 2097 2098 pr_libs.extend(kern_load_info) 2099 pr_libs.extend(dsc_libs) 2100 2101 pr_libs.sort(key=itemgetter(1)) 2102 2103 ttsnap = piddata.get('transitioning_task_snapshot', None) 2104 if ttsnap is not None: 2105 # Transitioning task snapshots have "tts_" prefixes; change them to 2106 # "ts_". 2107 ttsnap = { key[1:] : value for key,value in ttsnap.items() } 2108 # Add a note to let people know 2109 obj["notes"] = obj["notes"] + "PID {} is a transitioning (exiting) task. ".format(pid) 2110 tasksnap = piddata.get('task_snapshot', ttsnap); 2111 if tasksnap is None: 2112 continue; 2113 tsnap["pid"] = tasksnap["ts_pid"] 2114 if 'ts_asid' in piddata: 2115 tsnap["asid"] = piddata["ts_asid"] 2116 2117 if 'ts_pagetable' in piddata: 2118 pagetables = [] 2119 for tte in piddata["ts_pagetable"]: 2120 pagetables.append(tte) 2121 tsnap["pageTables"] = pagetables 2122 2123 # Some fields are missing from transitioning_task snapshots. 2124 if ttsnap is None: 2125 tsnap["residentMemoryBytes"] = tasksnap["ts_task_size"] 2126 tsnap["timesDidThrottle"] = tasksnap["ts_did_throttle"] 2127 tsnap["systemTimeTask"] = GetSecondsFromMATime(tasksnap["ts_system_time_in_terminated_th"], timebase) 2128 tsnap["pageIns"] = tasksnap["ts_pageins"] 2129 tsnap["pageFaults"] = tasksnap["ts_faults"] 2130 tsnap["userTimeTask"] = GetSecondsFromMATime(tasksnap["ts_user_time_in_terminated_thre"], timebase) 2131 tsnap["procname"] = tasksnap["ts_p_comm"] 2132 if ttsnap is None: 2133 tsnap["copyOnWriteFaults"] = tasksnap["ts_cow_faults"] 2134 tsnap["timesThrottled"] = tasksnap["ts_was_throttled"] 2135 tsnap["threadById"] = {} 2136 threadByID = tsnap["threadById"] 2137 thlist = piddata.get('thread_snapshots', {}) 2138 for tid,thdata in sorted(thlist.items()): 2139 threadByID[str(tid)] = {} 2140 thsnap = threadByID[str(tid)] 2141 if "thread_snapshot" not in thdata: 2142 print("Found broken thread state for thread ID: %s." % tid) 2143 break 2144 threadsnap = thdata["thread_snapshot"] 2145 thsnap["userTime"] = GetSecondsFromMATime(threadsnap["ths_user_time"], timebase) 2146 thsnap["id"] = threadsnap["ths_thread_id"] 2147 thsnap["basePriority"] = threadsnap["ths_base_priority"] 2148 thsnap["systemTime"] = GetSecondsFromMATime(threadsnap["ths_sys_time"], timebase) 2149 thsnap["schedPriority"] = threadsnap["ths_sched_priority"] 2150 thsnap["state"] = GetStateDescription(threadsnap['ths_state']) 2151 thsnap["qosEffective"] = threadsnap["ths_eqos"] 2152 thsnap["qosRequested"] = threadsnap["ths_rqos"] 2153 2154 if "pth_name" in thdata: 2155 thsnap["name"] = thdata["pth_name"]; 2156 2157 if threadsnap['ths_continuation']: 2158 thsnap["continuation"] = GetSymbolInfoForFrame(AllImageCatalog, pr_libs, threadsnap['ths_continuation']) 2159 if "kernel_stack_frames" in thdata: 2160 kuserframes = [] 2161 for f in thdata["kernel_stack_frames"]: 2162 kuserframes.append(GetSymbolInfoForFrame(AllImageCatalog, pr_libs, f['lr'])) 2163 notesBuilder = NotesBuilder(pid, tid) 2164 InsertExclavesFrames(AllImageCatalog, j, thdata, notesBuilder, kuserframes) 2165 if not notesBuilder.isEmpty(): 2166 obj['notes'] += notesBuilder.text() 2167 thsnap["kernelFrames"] = kuserframes 2168 2169 if "user_stack_frames" in thdata: 2170 uframes = [] 2171 for f in thdata["user_stack_frames"]: 2172 uframes.append(GetSymbolInfoForFrame(AllImageCatalog, pr_libs, f['lr'])) 2173 thsnap["userFrames"] = uframes 2174 2175 if "user_stacktop" in thdata: 2176 (address,) = struct.unpack("<Q", struct.pack("B"*8, *thdata["user_stacktop"]["stack_contents"])) 2177 thsnap["userStacktop"] = GetSymbolInfoForFrame(AllImageCatalog, pr_libs, address) 2178 2179 if threadsnap['ths_wait_event']: 2180 thsnap["waitEvent"] = GetSymbolInfoForFrame(AllImageCatalog, pr_libs, threadsnap['ths_wait_event']) 2181 2182 if 'thread_waitinfo' in piddata and 'thread_turnstileinfo' in piddata: 2183 tsnap['waitInfo'] = formatWaitInfoWithTurnstiles(piddata['thread_waitinfo'], piddata['thread_turnstileinfo'], piddata.get('portlabels', None)) 2184 elif 'thread_waitinfo' in piddata: 2185 portlabels = ss.get('portlabels', None) 2186 tsnap['waitInfo'] = [formatWaitInfo(x, False, portlabels) for x in piddata['thread_waitinfo']] 2187 if 'stackshot_task_codesigning_info' in piddata: 2188 csinfo = piddata.get('stackshot_task_codesigning_info', {}) 2189 tsnap['csflags'] = csinfo['csflags'] 2190 tsnap['cs_trust_level'] = csinfo['cs_trust_level'] 2191 if 'suspension_info' in piddata: 2192 suspinfo = piddata.get('suspension_info', {}) 2193 tsnap['suspension_count'] = suspinfo['tss_count'] 2194 tsnap['suspension_duration_secs'] = GetSecondsFromMATime(suspinfo['tss_duration'], timebase) 2195 tsnap['suspension_last_start'] = GetSecondsFromMATime(suspinfo['tss_last_start'], timebase) 2196 tsnap['suspension_last_end'] = GetSecondsFromMATime(suspinfo['tss_last_end'], timebase) 2197 2198 suspsources = piddata.get('suspension_source', []) 2199 suspension_sources = [] 2200 for source in filter(lambda x: x['tss_time'] != 0, suspsources): 2201 suspension_sources.append({ 2202 'suspension_time': GetSecondsFromMATime(source['tss_time'], timebase), 2203 'suspension_tid': source['tss_tid'], 2204 'suspension_pid': source['tss_pid'], 2205 'suspension_procname': source['tss_procname'], 2206 }) 2207 tsnap['suspension_sources'] = suspension_sources 2208 2209 # check if process is currently suspended 2210 if tsnap['suspension_last_start'] > tsnap['suspension_last_end']: 2211 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']) 2212 for source in suspension_sources: 2213 obj['notes'] += "From PID {} TID {} ({}) - at {}\n".format(source['suspension_pid'], source['suspension_tid'], source['suspension_procname'], source['suspension_time']) 2214 2215 obj['binaryImages'] = AllImageCatalog 2216 if outfile_name == '-': 2217 fh = sys.stdout 2218 else: 2219 fh = open(outfile_name, "w") 2220 2221 header = {} 2222 header['bug_type'] = 288 2223 if timestamp is not None: 2224 header['timestamp'] = timestamp 2225 header['os_version'] = os_version 2226 fh.write(json.dumps(header, sort_keys=True)) 2227 fh.write("\n") 2228 2229 fh.write(json.dumps(obj, sort_keys=True, indent=2, separators=(',', ': '))) 2230 fh.close() 2231 2232 2233@contextlib.contextmanager 2234def data_from_stream(stream): 2235 try: 2236 fmap = mmap.mmap(stream.fileno(), 0, mmap.MAP_SHARED, mmap.PROT_READ) 2237 except: 2238 yield stream.buffer.read() 2239 else: 2240 try: 2241 yield fmap 2242 finally: 2243 fmap.close() 2244 2245def iterate_kcdatas(kcdata_file): 2246 with data_from_stream(kcdata_file) as data: 2247 iterator = kcdata_item_iterator(data) 2248 kcdata_buffer = KCObject.FromKCItem(next(iterator)) 2249 2250 if isinstance(kcdata_buffer, KCCompressedBufferObject): 2251 kcdata_buffer.ReadItems(iterator) 2252 decompressed = kcdata_buffer.Decompress(data) 2253 iterator = kcdata_item_iterator(decompressed) 2254 kcdata_buffer = KCObject.FromKCItem(next(iterator)) 2255 2256 if not isinstance(kcdata_buffer, KCBufferObject): 2257 # ktrace stackshot chunk 2258 iterator = kcdata_item_iterator(data[16:]) 2259 kcdata_buffer = KCObject.FromKCItem(next(iterator)) 2260 2261 if not isinstance(kcdata_buffer, KCBufferObject): 2262 try: 2263 decoded = base64.b64decode(data) 2264 except: 2265 pass 2266 else: 2267 iterator = kcdata_item_iterator(decoded) 2268 kcdata_buffer = KCObject.FromKCItem(next(iterator)) 2269 if not isinstance(kcdata_buffer, KCBufferObject): 2270 import gzip 2271 from io import BytesIO 2272 try: 2273 decompressed = gzip.GzipFile(fileobj=BytesIO(data[:])).read() 2274 except: 2275 pass 2276 else: 2277 iterator = kcdata_item_iterator(decompressed) 2278 kcdata_buffer = KCObject.FromKCItem(next(iterator)) 2279 2280 if not isinstance(kcdata_buffer, KCBufferObject): 2281 raise Exception("unknown file type") 2282 2283 2284 kcdata_buffer.ReadItems(iterator) 2285 yield kcdata_buffer 2286 2287 for magic in iterator: 2288 kcdata_buffer = KCObject.FromKCItem(magic) 2289 if kcdata_buffer.i_type == 0: 2290 continue 2291 if not isinstance(kcdata_buffer, KCBufferObject): 2292 raise Exception("unknown file type") 2293 kcdata_buffer.ReadItems(iterator) 2294 yield kcdata_buffer 2295 2296# 2297# Values for various flag fields. Each entry's key is the key seen in the 2298# processed kcdata, the value is an array of bits, from low (0x1) to high, with 2299# either a string flag name or None for unused holes. 2300# 2301# Only put flags in here which are stable - this is run against stackshots 2302# of all different versions. For anything unstable, we'll need a decoder ring 2303# added to the stackshot. 2304# 2305PRETTIFY_FLAGS = { 2306 'jcs_flags': [ 2307 'kCoalitionTermRequested', 2308 'kCoalitionTerminated', 2309 'kCoalitionReaped', 2310 'kCoalitionPrivileged', 2311 ], 2312 'sharedCacheFlags': [ 2313 'kSharedCacheSystemPrimary', 2314 'kSharedCacheDriverkit' 2315 'kSharedCacheAOT', 2316 ], 2317 'stackshot_in_flags': [ # STACKSHOT_*, also stackshot_out_flags 2318 'get_dq', 2319 'save_loadinfo', 2320 'get_global_mem_stats', 2321 'save_kext_loadinfo', 2322 None, 2323 None, 2324 None, 2325 None, 2326 'active_kernel_threads_only', 2327 'get_boot_profile', 2328 'do_compress', 2329 None, 2330 None, 2331 'save_imp_donation_pids', 2332 'save_in_kernel_buffer', 2333 'retrieve_existing_buffer', 2334 'kcdata_format', 2335 'enable_bt_faulting', 2336 'collect_delta_snapshot', 2337 'collect_sharedcache_layout', 2338 'trylock', 2339 'enable_uuid_faulting', 2340 'from_panic', 2341 'no_io_stats', 2342 'thread_waitinfo', 2343 'thread_group', 2344 'save_jetsam_coalitions', 2345 'instrs_cycles', 2346 'asid', 2347 'page_tables', 2348 'disable_latency_info', 2349 'save_dyld_compactinfo', 2350 'include_driver_threads_in_kernel', 2351 'exclaves', 2352 ], 2353 'system_state_flags': [ 2354 'kUser64_p', 2355 'kKern64_p', 2356 ], 2357 'tgs_flags': [ 2358 'kThreadGroupEfficient', 2359 'kThreadGroupApplication', 2360 'kThreadGroupCritical', 2361 'kThreadGroupBestEffort', 2362 None, 2363 None, 2364 None, 2365 None, 2366 'kThreadGroupUIApplication', 2367 'kThreadGroupManaged', 2368 'kThreadGroupStrictTimers', 2369 ], 2370 'ths_ss_flags': [ 2371 'kUser64_p', 2372 'kKern64_p', 2373 'kHasDispatchSerial', 2374 'kStacksPCOnly', 2375 'kThreadDarwinBG', 2376 'kThreadIOPassive', 2377 'kThreadSuspended', 2378 'kThreadTruncatedBT', 2379 'kGlobalForcedIdle', 2380 'kThreadFaultedBT', 2381 'kThreadTriedFaultBT', 2382 'kThreadOnCore', 2383 'kThreadIdleWorker', 2384 'kThreadMain', 2385 'kThreadTruncKernBT', 2386 'kThreadTruncUserBT', 2387 'kThreadTruncUserAsyncBT', 2388 'kThreadExclaveRPCActive', 2389 'kThreadExclaveUpcallActive', 2390 'kThreadExclaveSchedulerRequest', 2391 ], 2392 'ths_state': [ 2393 'TH_WAIT', 2394 'TH_SUSP', 2395 'TH_RUN', 2396 'TH_UNINT', 2397 'TH_TERMINATE', 2398 'TH_TERMINATE2', 2399 'TH_WAIT_REPORT', 2400 'TH_IDLE', 2401 ], 2402 'ts_ss_flags': [ 2403 'kUser64_p', 2404 'kKern64_p', 2405 'kTaskRsrcFlagged', 2406 'kTerminatedSnapshot', 2407 'kPidSuspended', 2408 'kFrozen', 2409 'kTaskDarwinBG', 2410 'kTaskExtDarwinBG', 2411 'kTaskVisVisible', 2412 'kTaskVisNonvisible', 2413 'kTaskIsForeground', 2414 'kTaskIsBoosted', 2415 'kTaskIsSuppressed', 2416 'kTaskIsTimerThrottled', 2417 'kTaskIsImpDonor', 2418 'kTaskIsLiveImpDonor', 2419 'kTaskIsDirty', 2420 'kTaskWqExceededConstrainedThreadLimit', 2421 'kTaskWqExceededTotalThreadLimit', 2422 'kTaskWqFlagsAvailable', 2423 'kTaskUUIDInfoFaultedIn', 2424 'kTaskUUIDInfoMissing', 2425 'kTaskUUIDInfoTriedFault', 2426 'kTaskSharedRegionInfoUnavailable', 2427 'kTaskTALEngaged', 2428 None, 2429 'kTaskIsDirtyTracked', 2430 'kTaskAllowIdleExit', 2431 'kTaskIsTranslated', 2432 'kTaskSharedRegionNone', 2433 'kTaskSharedRegionSystem', 2434 'kTaskSharedRegionOther', 2435 'kTaskDyldCompactInfoNone', 2436 'kTaskDyldCompactInfoTooBig', 2437 'kTaskDyldCompactInfoFaultedIn', 2438 'kTaskDyldCompactInfoMissing', 2439 'kTaskDyldCompactInfoTriedFault', 2440 ], 2441 'turnstile_flags': [ 2442 'turnstile_status_unknown', 2443 'turnstile_status_locked_waitq', 2444 'turnstile_status_workqueue', 2445 'turnstile_status_thread', 2446 'turnstile_status_blocked_on_task', 2447 'turnstile_status_held_iplock', 2448 ], 2449 'portlabel_flags': [ 2450 'label_read_failed', 2451 'service_throttled', 2452 ], 2453 'esc_flags': [ 2454 'kExclaveScresultHaveIPCStack', 2455 ], 2456 'eise_flags': [ 2457 'kExclaveIpcStackEntryHaveInvocationID', 2458 'kExclaveIpcStackEntryHaveStack', 2459 ], 2460 'eas_flags': [ 2461 'kExclaveAddressSpaceHaveSlide', 2462 ], 2463 'etl_flags': [ 2464 'kExclaveTextLayoutLoadAddressesSynthetic', 2465 'kExclaveTextLayoutLoadAddressesUnslid', 2466 ], 2467} 2468PRETTIFY_FLAGS['stackshot_out_flags'] = PRETTIFY_FLAGS['stackshot_in_flags'] 2469PRETTIFY_FLAGS['tts_ss_flags'] = PRETTIFY_FLAGS['ts_ss_flags'] 2470 2471# Fields which should never be hexified 2472PRETTIFY_DONTHEX = { 2473 'stackshot_in_pid': True, 2474 'tts_pid': True, 2475 'ts_pid': True, 2476 'donating_pids': True, 2477 'ppid': True, 2478} 2479 2480# Only hex() the value if it is multiple digits 2481def prettify_hex(v): 2482 if v < -9 or v > 9: 2483 return hex(v) 2484 return str(v) 2485 2486def prettify_flags(v, flags): 2487 output="" 2488 seen = 0 2489 if v == 0: 2490 return "0" 2491 for (s, n) in zip(range(len(flags)),flags): 2492 if n is None: 2493 continue 2494 if (v & (2 ** s)): 2495 output += "|" + n 2496 seen |= 2 ** s 2497 if output == "": 2498 return prettify_hex(v) 2499 rest = (v & ~seen) 2500 if (rest != 0): 2501 output += "|" + prettify_hex(rest) 2502 return prettify_hex(v) + " (" + output[1:] + ")" 2503 2504def prettify_core(data, mosthex, key, portlabels): 2505 if key == 'stack_contents': 2506 (address,) = struct.unpack("<Q", struct.pack("B"*8, *data)) 2507 return '0x%X' % address 2508 2509 elif isinstance(data, list): 2510 if 'uuid' in key.lower() and len(data) == 16: 2511 return '%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X' % tuple(data) 2512 2513 return [prettify_core(x, mosthex, key, portlabels) for x in data] 2514 2515 elif key == 'thread_waitinfo': 2516 return formatWaitInfo(data, mosthex, portlabels) 2517 2518 elif isinstance(data, dict): 2519 if 'portlabels' in data: 2520 portlabels = data['portlabels'] 2521 newdata = dict() 2522 for key, value in data.items(): 2523 if mosthex and key != 'task_snapshots' and len(key) > 0 and key.isnumeric(): 2524 key = prettify_hex(int(key)) 2525 newdata[key] = prettify_core(value, mosthex, key, portlabels) 2526 return newdata 2527 2528 elif 'address' in key.lower() and isinstance(data, (int, long)): 2529 return '0x%X' % data 2530 elif key == 'lr' or key == SC_SLID_FIRSTMAPPING_KEY: 2531 return '0x%X' % data 2532 elif key in PRETTIFY_FLAGS and isinstance(data, (int, long)): 2533 return prettify_flags(data, PRETTIFY_FLAGS[key]) 2534 elif key.endswith('_flags') and isinstance(data, (int, long)): 2535 return prettify_hex(data) 2536 2537 elif mosthex and not PRETTIFY_DONTHEX.get(key, False): 2538 if isinstance(data, (int, long)): 2539 return prettify_hex(data) 2540 elif isinstance(data, str) and len(data) > 0 and data.isnumeric(): 2541 return prettify_hex(int(data)) 2542 return data 2543 2544 else: 2545 return data 2546 2547def prettify(data, mosthex): 2548 return prettify_core(data, mosthex, "", None) 2549 2550# N.B.: This is called directly from `xnu.py` for `panicdata -S XXX.ips`'s implementation. 2551def decode_kcdata_file(kcdata_file, stackshot_file, multiple=False, prettyhex=False, pretty=False, output_as_plist=False): 2552 for i,kcdata_buffer in enumerate(iterate_kcdatas(kcdata_file)): 2553 if i > 0 and not multiple: 2554 break 2555 2556 str_data = "{" + kcdata_buffer.GetJsonRepr() + "}" 2557 str_data = str_data.replace("\t", " ") 2558 2559 try: 2560 json_obj = json.loads(str_data) 2561 except: 2562 print("JSON reparsing failed! Printing string data!\n", file=sys.stderr) 2563 import textwrap 2564 print(textwrap.fill(str_data, 100)) 2565 raise 2566 2567 if prettyhex: 2568 json_obj = prettify(json_obj, True) 2569 elif pretty: 2570 json_obj = prettify(json_obj, False) 2571 2572 if stackshot_file: 2573 SaveStackshotReport(json_obj, stackshot_file, G.data_was_incomplete) 2574 elif output_as_plist: 2575 import Foundation 2576 plist = Foundation.NSPropertyListSerialization.dataWithPropertyList_format_options_error_( 2577 json_obj, Foundation.NSPropertyListXMLFormat_v1_0, 0, None)[0].bytes().tobytes() 2578 #sigh. on some pythons long integers are getting output with L's in the plist. 2579 plist = re.sub(r'^(\s*<integer>\d+)L(</integer>\s*)$', r"\1\2", BytesToString(plist), flags=re.MULTILINE) 2580 print(plist,) 2581 else: 2582 print(json.dumps(json_obj, sort_keys=True, indent=4, separators=(',', ': '))) 2583 2584if __name__ == '__main__': 2585 parser = argparse.ArgumentParser(description="Decode a kcdata binary file.") 2586 parser.add_argument("-l", "--listtypes", action="store_true", required=False, default=False, 2587 help="List all known types", 2588 dest="list_known_types") 2589 2590 parser.add_argument("-s", "--stackshot", required=False, default=False, 2591 help="Generate a stackshot report file", 2592 dest="stackshot_file") 2593 2594 parser.add_argument("--multiple", help="look for multiple stackshots in a single file", action='store_true') 2595 2596 parser.add_argument("-p", "--plist", required=False, default=False, 2597 help="output as plist", action="store_true") 2598 2599 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") 2600 parser.add_argument("-P", "--pretty", default=False, action='store_true', help="make the output a little more human readable") 2601 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") 2602 parser.add_argument("--incomplete", action='store_true', help="accept incomplete data") 2603 parser.add_argument("kcdata_file", type=argparse.FileType('r'), help="Path to a kcdata binary file.") 2604 2605 class VerboseAction(argparse.Action): 2606 def __call__(self, parser, namespace, values, option_string=None): 2607 logging.basicConfig(level=logging.INFO, stream=sys.stderr, format='%(message)s') 2608 parser.add_argument('-v', "--verbose", action=VerboseAction, nargs=0) 2609 2610 args = parser.parse_args() 2611 2612 if args.multiple and args.stackshot_file: 2613 raise NotImplementedError 2614 2615 if args.pretty and args.stackshot_file: 2616 raise NotImplementedError 2617 2618 if args.list_known_types: 2619 for (n, t) in KNOWN_TYPES_COLLECTION.items(): 2620 print("%d : %s " % (n, str(t))) 2621 sys.exit(1) 2622 2623 if args.incomplete or args.stackshot_file: 2624 G.accept_incomplete_data = True 2625 2626 decode_kcdata_file(args.kcdata_file, args.stackshot_file, args.multiple, args.prettyhex, args.pretty, args.plist) 2627