[0.2.x] added : getSourceLine routine

git-svn-id: https://pykd.svn.codeplex.com/svn@78890 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\kernelnet_cp 2012-08-16 17:20:21 +00:00 committed by Mikhail I. Izmestev
parent b91bb8ca38
commit 6b09a73cc6
9 changed files with 127 additions and 4 deletions

View File

@ -495,7 +495,45 @@ SymbolPtr DiaSession::findByRva( ULONG rva, ULONG symTag, LONG* pdisplacement )
return SymbolPtr( new DiaSymbol(child) ); 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 }; // pykd nemaspace end

View File

@ -15,6 +15,9 @@ typedef CComPtr< IDiaEnumSymbols > DiaEnumSymbolsPtr;
typedef CComPtr< IDiaDataSource > DiaDataSourcePtr; typedef CComPtr< IDiaDataSource > DiaDataSourcePtr;
typedef CComPtr< IDiaSession > DiaSessionPtr; typedef CComPtr< IDiaSession > DiaSessionPtr;
typedef CComPtr< IDiaEnumSymbolsByAddr > DiaEnumSymbolsByAddrPtr; 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 ); ULONG findRvaByName( const std::string &name );
void getSourceLine( ULONG64 offset, std::string &fileName, ULONG &lineNo, LONG &displacement );
private: private:
DiaSymbolPtr m_globalScope; DiaSymbolPtr m_globalScope;

View File

@ -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 }; // end of namespace pykd

View File

@ -98,6 +98,10 @@ public:
std::string getSymbolNameByVa( ULONG64 offset ); std::string getSymbolNameByVa( ULONG64 offset );
void getSourceLine( ULONG64 offset, std::string &fileName, ULONG &lineNo, LONG &displacement );
std::string getSourceFile( ULONG64 offset );
std::string print(); std::string print();
private: private:

View File

@ -51,6 +51,9 @@ BOOST_PYTHON_FUNCTION_OVERLOADS( loadSignDWords_, loadSignDWords, 2, 3 );
BOOST_PYTHON_FUNCTION_OVERLOADS( loadSignQWords_, loadSignQWords, 2, 3 ); BOOST_PYTHON_FUNCTION_OVERLOADS( loadSignQWords_, loadSignQWords, 2, 3 );
BOOST_PYTHON_FUNCTION_OVERLOADS( compareMemory_, compareMemory, 3, 4 ); 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 ) BOOST_PYTHON_MODULE( pykd )
{ {
python::scope().attr("version") = pykdVersion; python::scope().attr("version") = pykdVersion;
@ -70,7 +73,6 @@ BOOST_PYTHON_MODULE( pykd )
python::def( "isKernelDebugging", &isKernelDebugging, python::def( "isKernelDebugging", &isKernelDebugging,
"Check if kernel dubugging is running" ); "Check if kernel dubugging is running" );
python::def( "breakin", &debugBreak, python::def( "breakin", &debugBreak,
"Break into debugger" ); "Break into debugger" );
python::def( "expr", &evaluate, 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" ); "Read the block of the target's memory and return it as a list of pointers" );
// types and vaiables // 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, python::def( "getOffset", &TypeInfo::getOffset,
"Return traget virtual address for specified symbol" ); "Return traget virtual address for specified symbol" );
python::def( "findSymbol", &TypeInfo::findSymbol, python::def( "findSymbol", &TypeInfo::findSymbol,
@ -197,7 +203,6 @@ BOOST_PYTHON_MODULE( pykd )
python::def( "getProcessorType", &getProcessorType, python::def( "getProcessorType", &getProcessorType,
"Return type of physical processor: X86, ARM, IA64 or X64" ); "Return type of physical processor: X86, ARM, IA64 or X64" );
// stack and local variables // stack and local variables
python::def( "getCurrentStack", &getCurrentStack, python::def( "getCurrentStack", &getCurrentStack,
"Return a current stack as a list of stackFrame objects" ); "Return a current stack as a list of stackFrame objects" );

View File

@ -151,6 +151,7 @@ public:
virtual SymbolPtr findByRva( ULONG rva, ULONG symTag = SymTagNull, LONG* displacement = NULL ) = 0; 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;
}; };
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////

View File

@ -803,6 +803,40 @@ std::string EnumTypeInfo::print()
return sstr.str(); 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 }; // end namespace pykd

View File

@ -518,6 +518,10 @@ private:
void splitSymName( const std::string &fullName, std::string &moduleName, std::string &symbolName ); 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 }; // namespace pykd

View File

@ -5,6 +5,7 @@
import unittest import unittest
import target import target
import pykd import pykd
import re
class ModuleTest( unittest.TestCase ): class ModuleTest( unittest.TestCase ):
@ -52,3 +53,14 @@ class ModuleTest( unittest.TestCase ):
self.assertEqual( "structTest", target.module.type("structTest").name() ); self.assertEqual( "structTest", target.module.type("structTest").name() );
self.assertEqual( "structTest", target.module.type("g_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 )