From 6b09a73cc6047f054909c8b47db094342a9b8a10 Mon Sep 17 00:00:00 2001 From: "SND\\kernelnet_cp" Date: Thu, 16 Aug 2012 17:20:21 +0000 Subject: [PATCH] [0.2.x] added : getSourceLine routine git-svn-id: https://pykd.svn.codeplex.com/svn@78890 9b283d60-5439-405e-af05-b73fd8c4d996 --- pykd/dia/diawrapper.cpp | 40 +++++++++++++++++++++++++++++++++++++- pykd/dia/diawrapper.h | 5 +++++ pykd/module.cpp | 20 +++++++++++++++++++ pykd/module.h | 4 ++++ pykd/pymod.cpp | 9 +++++++-- pykd/symengine.h | 1 + pykd/typeinfo.cpp | 36 +++++++++++++++++++++++++++++++++- pykd/typeinfo.h | 4 ++++ test/scripts/moduletest.py | 12 ++++++++++++ 9 files changed, 127 insertions(+), 4 deletions(-) diff --git a/pykd/dia/diawrapper.cpp b/pykd/dia/diawrapper.cpp index bc05b58..59f9021 100644 --- a/pykd/dia/diawrapper.cpp +++ b/pykd/dia/diawrapper.cpp @@ -495,7 +495,45 @@ SymbolPtr DiaSession::findByRva( ULONG rva, ULONG symTag, LONG* pdisplacement ) return SymbolPtr( new DiaSymbol(child) ); } -////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +void DiaSession::getSourceLine( ULONG64 offset, std::string &fileName, ULONG &lineNo, LONG &displacement ) +{ + DiaEnumLineNumbersPtr lines; + + HRESULT hres = m_session->findLinesByVA( offset, 1, &lines ); + if (S_OK != hres) + throw DiaException("failed to find source line"); + + DiaLineNumberPtr sourceLine; + hres = lines->Item( 0, &sourceLine ); + if (S_OK != hres) + throw DiaException("failed to find source line"); + + DiaSourceFilePtr sourceFile; + hres = sourceLine->get_sourceFile( &sourceFile ); + if (S_OK != hres) + throw DiaException("failed to find source line"); + + autoBstr fileNameBstr; + hres = sourceFile->get_fileName ( &fileNameBstr ); + if (S_OK != hres) + throw DiaException("failed to find source line"); + fileName = fileNameBstr.asStr(); + + hres = sourceLine->get_lineNumber( &lineNo ); + if (S_OK != hres) + throw DiaException("failed to find source line"); + + ULONGLONG va; + hres = sourceLine->get_virtualAddress ( &va ); + if (S_OK != hres) + throw DiaException("failed to find source line"); + + displacement = (LONG)( (LONGLONG)offset - (LONGLONG)va ); +} + +/////////////////////////////////////////////////////////////////////////////// }; // pykd nemaspace end diff --git a/pykd/dia/diawrapper.h b/pykd/dia/diawrapper.h index 541aeba..c76f88c 100644 --- a/pykd/dia/diawrapper.h +++ b/pykd/dia/diawrapper.h @@ -15,6 +15,9 @@ typedef CComPtr< IDiaEnumSymbols > DiaEnumSymbolsPtr; typedef CComPtr< IDiaDataSource > DiaDataSourcePtr; typedef CComPtr< IDiaSession > DiaSessionPtr; typedef CComPtr< IDiaEnumSymbolsByAddr > DiaEnumSymbolsByAddrPtr; +typedef CComPtr< IDiaEnumLineNumbers > DiaEnumLineNumbersPtr; +typedef CComPtr< IDiaLineNumber> DiaLineNumberPtr; +typedef CComPtr< IDiaSourceFile > DiaSourceFilePtr; ////////////////////////////////////////////////////////////////////////////// @@ -250,6 +253,8 @@ public: ULONG findRvaByName( const std::string &name ); + void getSourceLine( ULONG64 offset, std::string &fileName, ULONG &lineNo, LONG &displacement ); + private: DiaSymbolPtr m_globalScope; diff --git a/pykd/module.cpp b/pykd/module.cpp index 3533c17..bb61b9b 100644 --- a/pykd/module.cpp +++ b/pykd/module.cpp @@ -230,4 +230,24 @@ std::string Module::getSymbolNameByVa( ULONG64 offset ) /////////////////////////////////////////////////////////////////////////////////// +void Module::getSourceLine( ULONG64 offset, std::string &fileName, ULONG &lineNo, LONG &displacement ) +{ + getSymSession()->getSourceLine( offset, fileName, lineNo, displacement ); +} + +/////////////////////////////////////////////////////////////////////////////////// + +std::string Module::getSourceFile( ULONG64 offset ) +{ + std::string fileName; + ULONG lineNo; + LONG displacement; + + getSymSession()->getSourceLine( offset, fileName, lineNo, displacement ); + + return fileName; +} + +/////////////////////////////////////////////////////////////////////////////////// + }; // end of namespace pykd diff --git a/pykd/module.h b/pykd/module.h index d07d64b..e0c8cd5 100644 --- a/pykd/module.h +++ b/pykd/module.h @@ -98,6 +98,10 @@ public: std::string getSymbolNameByVa( ULONG64 offset ); + void getSourceLine( ULONG64 offset, std::string &fileName, ULONG &lineNo, LONG &displacement ); + + std::string getSourceFile( ULONG64 offset ); + std::string print(); private: diff --git a/pykd/pymod.cpp b/pykd/pymod.cpp index 6e10138..96420cc 100644 --- a/pykd/pymod.cpp +++ b/pykd/pymod.cpp @@ -51,6 +51,9 @@ BOOST_PYTHON_FUNCTION_OVERLOADS( loadSignDWords_, loadSignDWords, 2, 3 ); BOOST_PYTHON_FUNCTION_OVERLOADS( loadSignQWords_, loadSignQWords, 2, 3 ); BOOST_PYTHON_FUNCTION_OVERLOADS( compareMemory_, compareMemory, 3, 4 ); +BOOST_PYTHON_FUNCTION_OVERLOADS( getSourceLine_, getSourceLine, 0, 1 ); +BOOST_PYTHON_FUNCTION_OVERLOADS( getSourceFile_, getSourceFile, 0, 1 ); + BOOST_PYTHON_MODULE( pykd ) { python::scope().attr("version") = pykdVersion; @@ -70,7 +73,6 @@ BOOST_PYTHON_MODULE( pykd ) python::def( "isKernelDebugging", &isKernelDebugging, "Check if kernel dubugging is running" ); - python::def( "breakin", &debugBreak, "Break into debugger" ); python::def( "expr", &evaluate, @@ -162,6 +164,10 @@ BOOST_PYTHON_MODULE( pykd ) "Read the block of the target's memory and return it as a list of pointers" ); // types and vaiables + python::def( "getSourceFile", &getSourceFile, getSourceFile_( python::args( "offset"), + "Return source file by the specified offset" ) ); + python::def( "getSourceLine", &getSourceLine, getSourceLine_( python::args( "offset"), + "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, @@ -197,7 +203,6 @@ BOOST_PYTHON_MODULE( pykd ) python::def( "getProcessorType", &getProcessorType, "Return type of physical processor: X86, ARM, IA64 or X64" ); - // stack and local variables python::def( "getCurrentStack", &getCurrentStack, "Return a current stack as a list of stackFrame objects" ); diff --git a/pykd/symengine.h b/pykd/symengine.h index 518e2c4..c049eec 100644 --- a/pykd/symengine.h +++ b/pykd/symengine.h @@ -151,6 +151,7 @@ public: virtual SymbolPtr findByRva( ULONG rva, ULONG symTag = SymTagNull, LONG* displacement = NULL ) = 0; + virtual void getSourceLine( ULONG64 offset, std::string &fileName, ULONG &lineNo, LONG &displacement ) = 0; }; /////////////////////////////////////////////////////////////////////////////// diff --git a/pykd/typeinfo.cpp b/pykd/typeinfo.cpp index f2bb71a..965e583 100644 --- a/pykd/typeinfo.cpp +++ b/pykd/typeinfo.cpp @@ -803,6 +803,40 @@ std::string EnumTypeInfo::print() return sstr.str(); } -///////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +python::tuple getSourceLine( ULONG64 offset ) +{ + if ( offset == 0 ) + offset = getRegInstructionPointer(); + else + offset = addr64( offset ); + + ModulePtr module = Module::loadModuleByOffset( offset ); + + std::string fileName; + ULONG lineNo; + LONG displacement; + + module->getSourceLine( offset, fileName, lineNo, displacement ); + + return python::make_tuple( fileName, lineNo, displacement ); +} + +/////////////////////////////////////////////////////////////////////////////// + +std::string getSourceFile( ULONG64 offset ) +{ + if ( offset == 0 ) + offset = getRegInstructionPointer(); + else + offset = addr64( offset ); + + ModulePtr module = Module::loadModuleByOffset( offset ); + + return module->getSourceFile( offset ); +} + +/////////////////////////////////////////////////////////////////////////////// }; // end namespace pykd \ No newline at end of file diff --git a/pykd/typeinfo.h b/pykd/typeinfo.h index 74d374a..9a627eb 100644 --- a/pykd/typeinfo.h +++ b/pykd/typeinfo.h @@ -518,6 +518,10 @@ private: void splitSymName( const std::string &fullName, std::string &moduleName, std::string &symbolName ); +python::tuple getSourceLine( ULONG64 offset = 0 ); + +std::string getSourceFile( ULONG64 offset = 0 ); + /////////////////////////////////////////////////////////////////////////////////// }; // namespace pykd diff --git a/test/scripts/moduletest.py b/test/scripts/moduletest.py index 6a68e7e..a99960c 100644 --- a/test/scripts/moduletest.py +++ b/test/scripts/moduletest.py @@ -5,6 +5,7 @@ import unittest import target import pykd +import re class ModuleTest( unittest.TestCase ): @@ -51,4 +52,15 @@ class ModuleTest( unittest.TestCase ): def testType( self ): self.assertEqual( "structTest", target.module.type("structTest").name() ); self.assertEqual( "structTest", target.module.type("g_structTest").name() ); + + def testSourceFile( self ): + fileName = pykd.getSourceFile(target.module.FuncWithName0 ) + self.assertTrue( re.search('targetapp\\.cpp', fileName ) ) + fileName, lineNo, displacement = pykd.getSourceLine( target.module.FuncWithName0 + 2) + self.assertEqual( 382, lineNo ) + self.assertTrue( re.search('targetapp\\.cpp', fileName ) ) + self.assertEqual( 2, displacement ) + fileName, lineNo, displacement = pykd.getSourceLine() + self.assertEqual( 636, lineNo ) +