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