'STACKSHOT_KCCONTAINER_THREAD': 0x904,
'STACKSHOT_KCTYPE_DONATING_PIDS': 0x907,
'STACKSHOT_KCTYPE_SHAREDCACHE_LOADINFO': 0x908,
+ 'STACKSHOT_KCTYPE_THREAD_NAME': 0x909,
'STACKSHOT_KCTYPE_KERN_STACKFRAME': 0x90A,
'STACKSHOT_KCTYPE_KERN_STACKFRAME64': 0x90B,
'STACKSHOT_KCTYPE_USER_STACKFRAME': 0x90C,
'STACKSHOT_KCTYPE_ASID' : 0x925,
'STACKSHOT_KCTYPE_PAGE_TABLES' : 0x926,
'STACKSHOT_KCTYPE_SYS_SHAREDCACHE_LAYOUT' : 0x927,
+ 'STACKSHOT_KCTYPE_THREAD_DISPATCH_QUEUE_LABEL' : 0x928,
+ 'STACKSHOT_KCTYPE_THREAD_TURNSTILEINFO' : 0x929,
'STACKSHOT_KCTYPE_TASK_DELTA_SNAPSHOT': 0x940,
'STACKSHOT_KCTYPE_THREAD_DELTA_SNAPSHOT': 0x941,
legacy_size = 0x68
)
+KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_THREAD_DISPATCH_QUEUE_LABEL')] = KCSubTypeElement('dispatch_queue_label', KCSUBTYPE_TYPE.KC_ST_CHAR,
+ KCSubTypeElement.GetSizeForArray(64, 1), 0, 1)
+
KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_THREAD_DELTA_SNAPSHOT')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_THREAD_DELTA_SNAPSHOT'), (
KCSubTypeElement.FromBasicCtype('tds_thread_id', KCSUBTYPE_TYPE.KC_ST_UINT64, 0),
KCSubTypeElement.FromBasicCtype('tds_voucher_identifier', KCSUBTYPE_TYPE.KC_ST_UINT64, 8),
)
-KNOWN_TYPES_COLLECTION[0x909] = KCSubTypeElement('pth_name', KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(64, 1), 0, 1)
+KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_THREAD_NAME')] = KCSubTypeElement('pth_name', KCSUBTYPE_TYPE.KC_ST_CHAR, KCSubTypeElement.GetSizeForArray(64, 1), 0, 1)
KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_SYS_SHAREDCACHE_LAYOUT')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_SYS_SHAREDCACHE_LAYOUT'), (
KCSubTypeElement('imageLoadAddress', KCSUBTYPE_TYPE.KC_ST_UINT64, 8, 0, 0),
),
'thread_waitinfo')
+KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_THREAD_TURNSTILEINFO')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_THREAD_TURNSTILEINFO'),
+ (
+ KCSubTypeElement.FromBasicCtype('waiter', KCSUBTYPE_TYPE.KC_ST_UINT64, 0),
+ KCSubTypeElement.FromBasicCtype('turnstile_context', KCSUBTYPE_TYPE.KC_ST_UINT64, 8),
+ KCSubTypeElement.FromBasicCtype('turnstile_priority', KCSUBTYPE_TYPE.KC_ST_UINT8, 16),
+ KCSubTypeElement.FromBasicCtype('number_of_hops', KCSUBTYPE_TYPE.KC_ST_UINT8, 17),
+ KCSubTypeElement.FromBasicCtype('turnstile_flags', KCSUBTYPE_TYPE.KC_ST_UINT64, 18),
+ ),
+ 'thread_turnstileinfo')
+
KNOWN_TYPES_COLLECTION[GetTypeForName('STACKSHOT_KCTYPE_THREAD_GROUP_SNAPSHOT')] = KCTypeDescription(GetTypeForName('STACKSHOT_KCTYPE_THREAD_GROUP'),
(
KCSubTypeElement.FromBasicCtype('tgs_id', KCSUBTYPE_TYPE.KC_ST_UINT64, 0),
)
def GetSecondsFromMATime(mat, tb):
- return (float(mat) * tb['numer']) / tb['denom']
+ return (float(long(mat) * tb['numer']) / tb['denom']) / 1e9
def FindLibraryForAddress(liblist, address):
current_lib = None
STACKSHOT_WAITOWNER_THREQUESTED = (UINT64_MAX - 6)
STACKSHOT_WAITOWNER_SUSPENDED = (UINT64_MAX - 7)
+STACKSHOT_TURNSTILE_STATUS_UNKNOWN = 0x01
+STACKSHOT_TURNSTILE_STATUS_LOCKED_WAITQ = 0x02
+STACKSHOT_TURNSTILE_STATUS_WORKQUEUE = 0x04
+STACKSHOT_TURNSTILE_STATUS_THREAD = 0x08
+
def formatWaitInfo(info):
s = 'thread %d: ' % info['waiter'];
type = info['wait_type']
s += ", unknown owner"
s += ", workloop id %x" % context
elif type == kThreadWaitOnProcess:
- s += "waitpid, for pid %d" % owner
+ if owner == 2**64-1:
+ s += "waitpid, for any children"
+ elif 2**32 <= owner and owner < 2**64-1:
+ s += "waitpid, for process group %d" % abs(owner - 2**64)
+ else:
+ s += "waitpid, for pid %d" % owner
else:
s += "unknown type %d (owner %d, context %x)" % (type, owner, context)
return s
+
+def formatTurnstileInfo(ti):
+ if ti is None:
+ return " [no turnstile]"
+
+ ts_flags = int(ti['turnstile_flags'])
+ ctx = int(ti['turnstile_context'])
+ hop = int(ti['number_of_hops'])
+ prio = int(ti['turnstile_priority'])
+ if ts_flags & STACKSHOT_TURNSTILE_STATUS_LOCKED_WAITQ:
+ return " [turnstile was in process of being updated]"
+ if ts_flags & STACKSHOT_TURNSTILE_STATUS_WORKQUEUE:
+ return " [blocked on workqueue: 0x%x, hops: %x, priority: %d]" % (ctx, hop, prio)
+ if ts_flags & STACKSHOT_TURNSTILE_STATUS_THREAD:
+ return " [blocked on: %d, hops: %x, priority: %d]" % (ctx, hop, prio)
+ if ts_flags & STACKSHOT_TURNSTILE_STATUS_UNKNOWN:
+ return " [turnstile with unknown inheritor]"
+
+ return " [unknown turnstile status!]"
+def formatWaitInfoWithTurnstiles(waitinfos, tsinfos):
+ wis_tis = []
+ for w in waitinfos:
+ found_pair = False
+ for t in tsinfos:
+ if int(w['waiter']) == int(t['waiter']):
+ wis_tis.append((w, t))
+ found_pair = True
+ break
+ if not found_pair:
+ wis_tis.append((w, None))
+
+ return map(lambda (wi, ti): formatWaitInfo(wi) + formatTurnstileInfo(ti), wis_tis)
def SaveStackshotReport(j, outfile_name, incomplete):
import time
thsnap["qosEffective"] = threadsnap["ths_eqos"]
thsnap["qosRequested"] = threadsnap["ths_rqos"]
+ if "pth_name" in thdata:
+ thsnap["name"] = thdata["pth_name"];
+
if threadsnap['ths_continuation']:
thsnap["continuation"] = GetSymbolInfoForFrame(AllImageCatalog, pr_libs, threadsnap['ths_continuation'])
if "kernel_stack_frames" in thdata:
if threadsnap['ths_wait_event']:
thsnap["waitEvent"] = GetSymbolInfoForFrame(AllImageCatalog, pr_libs, threadsnap['ths_wait_event'])
- if 'thread_waitinfo' in piddata:
+ if 'thread_waitinfo' in piddata and 'thread_turnstileinfo' in piddata:
+ tsnap['waitInfo'] = formatWaitInfoWithTurnstiles(piddata['thread_waitinfo'] , piddata['thread_turnstileinfo'])
+ elif 'thread_waitinfo' in piddata:
tsnap['waitInfo'] = map(formatWaitInfo, piddata['thread_waitinfo'])
obj['binaryImages'] = AllImageCatalog
with data_from_stream(kcdata_file) as data:
iterator = kcdata_item_iterator(data)
kcdata_buffer = KCObject.FromKCItem(iterator.next())
+ if not isinstance(kcdata_buffer, KCBufferObject):
+ iterator = kcdata_item_iterator(data[16:])
+ kcdata_buffer = KCObject.FromKCItem(iterator.next())
if not isinstance(kcdata_buffer, KCBufferObject):
try:
decoded = base64.b64decode(data)
for magic in iterator:
kcdata_buffer = KCObject.FromKCItem(magic)
+ if kcdata_buffer.i_type == 0:
+ continue
if not isinstance(kcdata_buffer, KCBufferObject):
raise Exception, "unknown file type"
kcdata_buffer.ReadItems(iterator)