Skip to content

Instantly share code, notes, and snippets.

@kanru
Created April 13, 2017 20:57
Show Gist options
  • Save kanru/b6b41871db28bdcd10e4c7be792b9e58 to your computer and use it in GitHub Desktop.
Save kanru/b6b41871db28bdcd10e4c7be792b9e58 to your computer and use it in GitHub Desktop.
#!/bin/env python
import json
import sys
import cmd
from colorama import Fore, Style
skipList = [
"BaseThreadInitThunk",
"CharPrevA",
"CsrAllocateMessagePointer",
"DispatchMessageW",
"DispatchMessageWorker",
"EtwEventEnabled",
"GetCurrentThread",
"GetTickCount",
"KiFastSystemCallRet",
"MessageLoop::Run",
"MessageLoop::RunHandler",
"MsgWaitForMultipleObjects",
"MsgWaitForMultipleObjectsEx",
"NS_ProcessNextEvent",
"NS_internal_main",
"NtUserValidateHandleSecure",
"NtWaitForAlertByThreadId",
"NtWaitForMultipleObjects",
"NtWaitForSingleObject",
"PR_Lock",
"PeekMessageW",
"RealMsgWaitForMultipleObjectsEx",
"RtlAnsiStringToUnicodeString",
"RtlDeNormalizeProcessParams",
"RtlEnterCriticalSection",
"RtlLeaveCriticalSection",
"RtlUserThreadStart",
"RtlpAllocateListLookup",
"RtlpDeCommitFreeBlock",
"RtlpEnterCriticalSectionContended",
"RtlpUnWaitCriticalSection",
"RtlpWaitOnAddress",
"RtlpWaitOnAddressWithTimeout",
"RtlpWaitOnCriticalSection",
"RtlpWakeByAddress",
"UserCallWinProcCheckWow"
"ValidateHwnd",
"WaitForMultipleObjectsEx",
"WaitForMultipleObjectsExImplementation",
"WaitForSingleObjectEx",
"XRE_InitChildProcess",
"XRE_RunAppShell",
"ZwWaitForMultipleObjects",
"ZwWaitForSingleObject",
"_RtlUserThreadStart",
"__RtlUserThreadStart",
"__scrt_common_main_seh",
"content_process_main",
"mozilla::BackgroundHangMonitor::NotifyActivity",
"mozilla::BackgroundHangThread::NotifyActivity",
"mozilla::BackgroundHangThread::NotifyWait",
"mozilla::BootstrapImpl::XRE_InitChildProcess",
"mozilla::HangMonitor::NotifyActivity",
"mozilla::HangMonitor::Suspend",
"mozilla::ValidatingDispatcher::Runnable::Run",
"mozilla::detail::MutexImpl::lock",
"mozilla::ipc::MessageChannel::MessageTask::Run",
"mozilla::ipc::MessagePump::Run",
"mozilla::ipc::MessagePumpForChildProcess::Run",
"mozilla::widget::WinUtils::PeekMessageW",
"mozilla::widget::WinUtils::WaitForMessage",
"nsAppShell::ProcessNextNativeEvent",
"nsAppShell::Run",
"nsBaseAppShell::DoProcessNextNativeEvent",
"nsBaseAppShell::OnProcessNextEvent",
"nsBaseAppShell::Run",
"nsThread::DoMainThreadSpecificProcessing",
"nsThread::ProcessNextEvent",
"wmain",
"UserCallWinProcCheckWow",
"ValidateHwnd",
"0x1bc3d",
"0x1905a",
"RtlSleepConditionVariableCS",
"SleepConditionVariableCS",
"NDXGI::CDevice::GetKernelDeviceExecutionState",
"NtGdiDdDDIGetDeviceState",
]
def shouldSkip(frame):
for item in skipList:
if frame.startswith(item):
return True
return False
def filterStacks(stacks):
newstacks = []
for frame in stacks:
if shouldSkip(frame):
continue
newstacks.append(frame)
return newstacks
def hasNativeStack(record, name):
for frame in filterStacks(record['nativeStack']['symbolicatedStacks'][0]):
if name in frame:
return True
return False
def countAndSort(hangs):
buckets = {}
for record in hangs:
key = ' \n'.join(record['stack'])
if not buckets.has_key(key):
buckets[key] = 0
buckets[key] += 1
return sorted(buckets.iteritems(), key=lambda p: p[1], reverse=True)
class Repl(cmd.Cmd):
def __init__(self, hangs):
cmd.Cmd.__init__(self)
self.prompt = Style.BRIGHT+Fore.RED + "(Stacks with frame?) " + Style.RESET_ALL
self.hangs = hangs
def onecmd(self, line):
if line == '':
return
if line == 'EOF':
sys.exit(0)
matches = []
for record in self.hangs:
if hasNativeStack(record, line):
matches.append(record)
for record in countAndSort(matches):
print("{}{}{}".format(Style.BRIGHT+Fore.GREEN,
record[1],
Style.RESET_ALL))
print("{}".format(record[0]))
if __name__ == "__main__":
hangs = sys.argv[1]
data = json.load(open(hangs))
repl = Repl(data)
repl.cmdloop()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment