From 3e2969ab6a587f56076978443a1e1f8cba90e0c7 Mon Sep 17 00:00:00 2001
From: "SND\\kernelnet_cp"
 <SND\kernelnet_cp@9b283d60-5439-405e-af05-b73fd8c4d996>
Date: Mon, 10 Dec 2012 09:00:29 +0000
Subject: [PATCH] [0.2.x] added : argument showDisplacement for method
 module.findSymbol ( by default showDisplacement = True )

git-svn-id: https://pykd.svn.codeplex.com/svn@81741 9b283d60-5439-405e-af05-b73fd8c4d996
---
 pykd/module.cpp            | 13 ++++++-----
 pykd/module.h              |  2 +-
 pykd/pymod.cpp             |  7 +++---
 snippets/stkdelta.py       | 18 ++++++++++-----
 snippets/stkwalk.py        | 46 ++++++++++++++++++++++++--------------
 test/scripts/moduletest.py |  4 +++-
 6 files changed, 57 insertions(+), 33 deletions(-)

diff --git a/pykd/module.cpp b/pykd/module.cpp
index ae6bc89..9ab5072 100644
--- a/pykd/module.cpp
+++ b/pykd/module.cpp
@@ -287,7 +287,7 @@ SymbolPtr Module::getSymbolByVa( ULONG64 offset, ULONG symTag, LONG* displacment
 }
 ///////////////////////////////////////////////////////////////////////////////////
 
-std::string Module::getSymbolNameByVa( ULONG64 offset )
+std::string Module::getSymbolNameByVa( ULONG64 offset, bool showDisplacement )
 {
     offset = addr64(offset);
 
@@ -302,10 +302,13 @@ std::string Module::getSymbolNameByVa( ULONG64 offset )
 
     sstr << sym->getName();
 
-    if ( displacement > 0 && displacement )
-        sstr << '+' << std::hex << displacement;
-    else if ( displacement < 0 )
-        sstr << '-' << std::hex << -displacement;
+    if ( showDisplacement )
+    {
+        if ( displacement > 0 && displacement )
+            sstr << '+' << std::hex << displacement;
+        else if ( displacement < 0 )
+            sstr << '-' << std::hex << -displacement;
+    }
 
     return sstr.str();
 }
diff --git a/pykd/module.h b/pykd/module.h
index 946774a..39a8747 100644
--- a/pykd/module.h
+++ b/pykd/module.h
@@ -125,7 +125,7 @@ public:
 
     SymbolPtr getSymbolByVa( ULONG64 offset, ULONG symTag, LONG* displacemnt = NULL );
 
-    std::string getSymbolNameByVa( ULONG64 offset );
+    std::string getSymbolNameByVa( ULONG64 offset, bool showDisplacement = true );
 
     void getSourceLine( ULONG64 offset, std::string &fileName, ULONG &lineNo, LONG &displacement );
 
diff --git a/pykd/pymod.cpp b/pykd/pymod.cpp
index 1a5f4c7..fb14efc 100644
--- a/pykd/pymod.cpp
+++ b/pykd/pymod.cpp
@@ -66,6 +66,7 @@ BOOST_PYTHON_FUNCTION_OVERLOADS( findSymbol_, TypeInfo::findSymbol, 1, 2 );
 
 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( Module_enumSymbols, Module::enumSymbols, 0, 1 );
 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( Module_enumTypes, Module::enumTypes, 0, 1 );
+BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( Module_findSymbol, Module::getSymbolNameByVa, 1, 2 );
 
 
 BOOST_PYTHON_MODULE( pykd )
@@ -208,7 +209,7 @@ BOOST_PYTHON_MODULE( pykd )
         "Return source file name, line and displacement by the specified offset" ) );
     python::def( "getOffset", &TypeInfo::getOffset,
         "Return traget virtual address for specified symbol" );
-    python::def( "findSymbol", &TypeInfo::findSymbol, findSymbol_( python::args( "offset", "safe"),
+    python::def( "findSymbol", &TypeInfo::findSymbol, findSymbol_( python::args( "offset", "safe", "showDisplacement"),
         "Find symbol by the target virtual memory offset" ) );
     python::def( "sizeof", &TypeInfo::getSymbolSize,
         "Return a size of the type or variable" );
@@ -350,8 +351,8 @@ BOOST_PYTHON_MODULE( pykd )
              "Return the full path to the module's symbol information" )
         .def("offset", &Module::getSymbolOffset,
             "Return offset of the symbol" )
-        .def("findSymbol", &Module::getSymbolNameByVa,
-            "Return symbol name by virtual address" )
+        .def("findSymbol", &Module::getSymbolNameByVa, Module_findSymbol( python::args("offset", "showDisplacement"),
+            "Return symbol name by virtual address" ) )
         .def("rva", &Module::getSymbolRva,
             "Return rva of the symbol" )
         .def("sizeof", &Module::getSymbolSize,
diff --git a/snippets/stkdelta.py b/snippets/stkdelta.py
index be63d66..499d60c 100644
--- a/snippets/stkdelta.py
+++ b/snippets/stkdelta.py
@@ -30,19 +30,21 @@ def printDeltaStat():
     for i in range( 0, len(stk) -1 ):
     
         try:
-            mname = module( stk[i].returnOffset ).name()
+            mod = module( stk[i].returnOffset )
         except BaseException:
             continue    
   
         delta = stk[i+1].frameOffset - stk[i].frameOffset
         if delta > 0:
        
-            if mname in moduleLst:
-                moduleLst[mname] = moduleLst[mname] + delta
+            moduleName = mod.name()
+       
+            if moduleName in moduleLst:
+                moduleLst[moduleName] = moduleLst[moduleName] + delta
             else:
-                moduleLst[mname] = delta
+                moduleLst[moduleName] = delta
                 
-            func = findSymbol( stk[i].returnOffset )
+            func = moduleName + "!" + mod.findSymbol( stk[i].returnOffset, showDisplacement = False )
 
             if func in funcLst:
                 funcLst[func] = funcLst[func] + delta
@@ -79,7 +81,11 @@ def printDeltaStack():
     
     for i in range( 0, len(stk) -1 ):
         dprint( "%12s\t" % long( stk[i+1].frameOffset - stk[i].frameOffset) )
-        dprintln( findSymbol( stk[i].returnOffset ) )
+        try:
+            mod = module( stk[i].returnOffset )
+            dprintln( "%s!%s"% ( mod.name(), mod.findSymbol( stk[i].returnOffset, showDisplacement = False ) ) )
+        except BaseException:
+            dprintln( findSymbol( stk[i].returnOffset ) )        
 
 def main():
 
diff --git a/snippets/stkwalk.py b/snippets/stkwalk.py
index 5176e8e..c28abf2 100644
--- a/snippets/stkwalk.py
+++ b/snippets/stkwalk.py
@@ -2,6 +2,8 @@
 from pykd import *
 from optparse import OptionParser
 from fnmatch import fnmatch
+import traceback
+import sys
 
 nt = None
 
@@ -9,27 +11,30 @@ class PrintOptions:
     def __init__(self):
         self.ignoreNotActiveThread = True
         self.ignoreNotActiveProcess = True
+        self.showWow64stack = True
 
-def applayThreadFilter( thread,moduleFilter):
+def applayThreadFilter(thread,moduleFilter,funcFilter,printopt):
+
+    if not moduleFilter and not funcFilter:
+        return True
 
     try:
         setImplicitThread(thread)
-        
+       
         stk = getStack()
         
-        moduleLst = set()
         for frame in stk:
             m = module( frame.instructionOffset )
-            if moduleFilter( m, m.name() ):
-                moduleLst.add(m)
-           
-        if len(moduleLst)==0:
-            return False
+            if moduleFilter and moduleFilter( m, m.name() ):
+                return True
+            sym = m.findSymbol( frame.instructionOffset, showDisplacement = False )
+            if funcFilter and funcFilter( sym ):
+                return True            
 
     except BaseException:
-        return False
+        pass
         
-    return True        
+    return False
     
         
 def printThread(process,thread,printopt):
@@ -53,11 +58,11 @@ def printThread(process,thread,printopt):
 
     
     
-def printProcess(process,processFilter,moduleFilter,printopt):
+def printProcess(process,processFilter,moduleFilter,funcFilter,printopt):
 
     processName = loadCStr( process.ImageFileName )
      
-    if not processFilter(process, process.UniqueProcessId, processName ):
+    if processFilter and not processFilter(process, process.UniqueProcessId, processName ):
         return
     
     try:
@@ -68,7 +73,7 @@ def printProcess(process,processFilter,moduleFilter,printopt):
         threadLst = nt.typedVarList(process.ThreadListHead, "_ETHREAD", "ThreadListEntry")
         filteredThreadLst = []
         for thread in threadLst:
-            if applayThreadFilter( thread, moduleFilter ):
+            if applayThreadFilter( thread, moduleFilter, funcFilter, printopt ):
                 filteredThreadLst.append( thread )
                 
         if filteredThreadLst == []:
@@ -104,18 +109,25 @@ def main():
         help="process filter: boolean expression with python syntax" )
     parser.add_option("-m", "--module", dest="modulefilter", 
         help="module filter: boolean expression with python syntax" )
+    parser.add_option("-f", "--function", dest="funcfilter",
+        help="function filter: boolean expression with python syntax" )
+    
     
     (options, args) = parser.parse_args()
      
-    processFilter =  lambda process, pid, name: True
-    moduleFilter = lambda module, name: True
-     
+    processFilter = None
+    moduleFilter = None
+    funcFilter = None
+    
     if options.processfilter:
         processFilter = lambda process, pid, name: eval( options.processfilter )
         
     if options.modulefilter:
         moduleFilter = lambda module, name: eval(options.modulefilter)
         
+    if options.funcfilter:
+        funcFilter = lambda name: eval( options.funcfilter)
+        
     printopt = PrintOptions()
            
     currentProcess = getCurrentProcess()
@@ -123,7 +135,7 @@ def main():
 
     processLst = nt.typedVarList( nt.PsActiveProcessHead, "_EPROCESS", "ActiveProcessLinks")  
     for process in processLst:
-        printProcess( process, processFilter, moduleFilter, printopt )  
+        printProcess( process, processFilter, moduleFilter, funcFilter, printopt )  
             
     setCurrentProcess(currentProcess)
     setImplicitThread(currentThread)
diff --git a/test/scripts/moduletest.py b/test/scripts/moduletest.py
index 729999e..83c2f05 100644
--- a/test/scripts/moduletest.py
+++ b/test/scripts/moduletest.py
@@ -52,7 +52,9 @@ class ModuleTest( unittest.TestCase ):
     def testFindSymbol( self ):
         self.assertEqual( "FuncWithName0", target.module.findSymbol( target.module.offset("FuncWithName0") ) )
         self.assertEqual( "_FuncWithName2", target.module.findSymbol( target.module.offset("_FuncWithName2") ) )
-       # self.assertEqual( "", typed)
+        
+        self.assertEqual( "_FuncWithName2+10", target.module.findSymbol( target.module.offset("_FuncWithName2") + 0x10 ) )
+        self.assertEqual( "_FuncWithName2", target.module.findSymbol( target.module.offset("_FuncWithName2") + 0x10, showDisplacement = False ) )
         
         
     def testType( self ):