mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-20 03:23:23 +08:00
[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:
parent
b91bb8ca38
commit
6b09a73cc6
@ -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
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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:
|
||||||
|
@ -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" );
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -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
|
@ -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
|
||||||
|
@ -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 )
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user