[0.2.x] added: stkwalk.py ( add --unique parameter )

git-svn-id: https://pykd.svn.codeplex.com/svn@82055 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\kernelnet_cp 2012-12-27 15:38:26 +00:00 committed by Mikhail I. Izmestev
parent 5c6d5e720c
commit e3486bc637

View File

@ -14,14 +14,23 @@ class PrintOptions:
self.showWow64stack = True self.showWow64stack = True
self.showIP = True self.showIP = True
self.showSP = True self.showSP = True
self.showUnique = False
def applayThreadFilter(thread,threadFilter,moduleFilter,funcFilter,printopt): def applayThreadFilter(thread,threadFilter,moduleFilter,funcFilter,printopt,stackHashes):
filterMatch = False
if not moduleFilter and not funcFilter and not threadFilter: if not moduleFilter and not funcFilter and not threadFilter:
return True if printopt.showUnique == False:
return True
if threadFilter and threadFilter( thread.Tcb, thread.Cid.UniqueThread ): else:
return True filterMatch = True
if threadFilter and threadFilter( thread.Tcb, thread.Cid.UniqueThread ):
if printopt.showUnique == False:
return True
else:
filterMatch = True
try: try:
@ -29,13 +38,59 @@ def applayThreadFilter(thread,threadFilter,moduleFilter,funcFilter,printopt):
stk = getStack() stk = getStack()
strStack = ""
for frame in stk: for frame in stk:
m = module( frame.instructionOffset ) m = module( frame.instructionOffset )
if moduleFilter and moduleFilter( m, m.name() ): if filterMatch == False and moduleFilter and moduleFilter( m, m.name() ):
return True filterMatch = True
if printopt.showUnique == False:
return False
sym = m.findSymbol( frame.instructionOffset, showDisplacement = False ) sym = m.findSymbol( frame.instructionOffset, showDisplacement = False )
if funcFilter and funcFilter( sym ): if filterMatch == False and funcFilter and funcFilter( sym ):
return True filterMatch = True
if printopt.showUnique == False:
return False
if printopt.showUnique == True:
strStack += sym
if is64bitSystem():
processorMode = getProcessorMode()
try:
setProcessorMode("X86")
dbgCommand( ".reload /user" )
stk = getStackWow64()
for frame in stk:
m = module( frame.instructionOffset )
if filterMatch == False and moduleFilter and moduleFilter( m, m.name() ):
filterMatch = True
if printopt.showUnique == False:
return False
sym = m.findSymbol( frame.instructionOffset, showDisplacement = False )
if filterMatch == False and funcFilter and funcFilter( sym ):
filterMatch = True
if printopt.showUnique == False:
return False
if printopt.showUnique == True:
strStack += sym
except BaseException:
pass
setProcessorMode(processorMode)
if printopt.showUnique == False or filterMatch == False:
return filterMatch
hashStack = hash( strStack )
if hashStack in stackHashes:
return False
stackHashes.add( hashStack )
return True
except BaseException: except BaseException:
pass pass
@ -66,7 +121,6 @@ def printThread(process,thread,printopt):
processorMode = getProcessorMode() processorMode = getProcessorMode()
try: try:
setProcessorMode("X86") setProcessorMode("X86")
dbgCommand( ".reload /user" )
stk = getStackWow64() stk = getStackWow64()
dprintln("\nWOW64 stack") dprintln("\nWOW64 stack")
for frame in stk: for frame in stk:
@ -97,21 +151,21 @@ def printProcess(process,processFilter,threadFilter,moduleFilter,funcFilter,prin
#setCurrentProcess(process) #setCurrentProcess(process)
dbgCommand(".process /p %x" % process ) dbgCommand(".process /p %x" % process )
dbgCommand( ".reload /user" ) dbgCommand( ".reload /user" )
reloadWow64 = False
threadLst = nt.typedVarList(process.ThreadListHead, "_ETHREAD", "ThreadListEntry") threadLst = nt.typedVarList(process.ThreadListHead, "_ETHREAD", "ThreadListEntry")
filteredThreadLst = [] filteredThreadLst = []
stackHashes = set()
for thread in threadLst: for thread in threadLst:
if applayThreadFilter( thread, threadFilter, moduleFilter, funcFilter, printopt ): if applayThreadFilter( thread, threadFilter, moduleFilter, funcFilter, printopt, stackHashes ):
filteredThreadLst.append( thread ) filteredThreadLst.append( thread )
if filteredThreadLst == []: if filteredThreadLst == []:
return return
dprintln( "Process %x" % process ) dprintln( "Process %x" % process )
dprintln( "Name: %s" % processName ) dprintln( "Name: %s Pid: %#x" % ( processName, process.UniqueProcessId ) )
dprintln( "" ) dprintln( "" )
for thread in filteredThreadLst: for thread in filteredThreadLst:
@ -144,7 +198,8 @@ def main():
help="function filter: boolean expression with python syntax" ) help="function filter: boolean expression with python syntax" )
parser.add_option("-t", "--thread", dest="threadfilter", parser.add_option("-t", "--thread", dest="threadfilter",
help="thread filter: boolean expresion with python syntax" ) help="thread filter: boolean expresion with python syntax" )
parser.add_option("-u", "--unique", action="store_true", dest="uniquestack",
help="show only unique stacks" )
(options, args) = parser.parse_args() (options, args) = parser.parse_args()
@ -166,6 +221,7 @@ def main():
threadFilter = lambda thread, tid: eval( options.threadfilter) threadFilter = lambda thread, tid: eval( options.threadfilter)
printopt = PrintOptions() printopt = PrintOptions()
printopt.showUnique = True if options.uniquestack else False
currentProcess = getCurrentProcess() currentProcess = getCurrentProcess()
currentThread = getImplicitThread() currentThread = getImplicitThread()