diff --git a/pykd/dbgclient.cpp b/pykd/dbgclient.cpp index 29a2918..fe202de 100644 --- a/pykd/dbgclient.cpp +++ b/pykd/dbgclient.cpp @@ -668,4 +668,50 @@ python::list getTypedVarArrayByTypeName( ULONG64 addr, const std::string &typeN /////////////////////////////////////////////////////////////////////////////////// +python::tuple DebugClient::getSourceLine( ULONG64 offset ) +{ + HRESULT hres; + + if ( offset == 0 ) + { + hres = m_registers->GetInstructionOffset( &offset ); + if ( FAILED( hres ) ) + throw DbgException( "IDebugRegisters::GetInstructionOffset failed" ); + } + + ULONG fileNameLength = 0; + + m_symbols->GetLineByOffset( + offset, + NULL, + NULL, + 0, + &fileNameLength, + NULL ); + + if ( fileNameLength == 0 ) + throw DbgException( "Failed to find source file" ); + + std::vector fileNameBuf( fileNameLength ); + + ULONG lineNo; + ULONG64 displacement; + + hres = + m_symbols->GetLineByOffset( + offset, + &lineNo, + &fileNameBuf[0], + fileNameLength, + NULL, + &displacement ); + + if ( FAILED( hres ) ) + throw DbgException( "IDebugSymbol::GetLineByOffset method failed" ); + + return python::make_tuple( std::string( &fileNameBuf[0] ), lineNo, displacement ); +} + +/////////////////////////////////////////////////////////////////////////////////// + }; // end of namespace pykd diff --git a/pykd/dbgclient.h b/pykd/dbgclient.h index 24db2c3..f7fb8d2 100644 --- a/pykd/dbgclient.h +++ b/pykd/dbgclient.h @@ -138,6 +138,8 @@ public: std::string dbgSymPath(); + python::tuple getSourceLine( ULONG64 offset = 0); + python::list getThreadList(); template @@ -505,7 +507,10 @@ void changeDebuggerStatus() g_dbgClient->changeDebuggerStatus(); } - +inline python::tuple getSourceLine( ULONG64 offset = 0 ) +{ + return g_dbgClient->getSourceLine(offset); +} ///////////////////////////////////////////////////////////////////////////////// diff --git a/pykd/pymod.cpp b/pykd/pymod.cpp index 9af80be..f4d9081 100644 --- a/pykd/pymod.cpp +++ b/pykd/pymod.cpp @@ -68,6 +68,7 @@ BOOST_PYTHON_FUNCTION_OVERLOADS( getLocals_, getLocals, 0, 1 ); BOOST_PYTHON_FUNCTION_OVERLOADS( setSoftwareBp_, setSoftwareBp, 1, 2 ); BOOST_PYTHON_FUNCTION_OVERLOADS( setHardwareBp_, setHardwareBp, 3, 4 ); BOOST_PYTHON_FUNCTION_OVERLOADS( pyDia_GlobalScope_loadExe, pyDia::GlobalScope::loadExe, 1, 2 ); +BOOST_PYTHON_FUNCTION_OVERLOADS( getSourceLine_, getSourceLine, 0, 1 ); BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( DebugClient_loadChars, DebugClient::loadChars, 2, 3 ); BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( DebugClient_loadWChars, DebugClient::loadWChars, 2, 3 ); @@ -83,9 +84,11 @@ BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( DebugClient_compareMemory, DebugClient:: BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( DebugClient_getLocals, DebugClient::getLocals, 0, 1 ); BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( DebugClient_setSoftwareBp, DebugClient::setSoftwareBp, 1, 2 ); BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( DebugClient_setHardwareBp, DebugClient::setHardwareBp, 3, 4 ); +BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( DebugClient_getSourceLine, DebugClient::getSourceLine, 0, 1 ); BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( StackFrame_getLocals, StackFrame::getLocals, 0, 1 ); BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( pyDia_Symbol_findChildrenEx, pyDia::Symbol::findChildrenEx, 1, 3 ); + #define DEF_PY_CONST_ULONG(x) \ python::scope().attr(#x) = ULONG(##x) @@ -179,6 +182,8 @@ BOOST_PYTHON_MODULE( pykd ) "Return current processor mode as string: X86, ARM, IA64 or X64" ) .def( "getProcessorType", &DebugClient::getProcessorType, "Return type of physical processor: X86, ARM, IA64 or X64" ) + .def( "getSourceLine", &DebugClient::getSourceLine, DebugClient_getSourceLine( python::args( "offset"), + "Return source file name, lin and displacement by the specified offset" ) ) .def( "getThreadList", &DebugClient::getThreadList, "Return list of threads (each item is numeric identifier of thread)" ) .def( "go", &DebugClient::changeDebuggerStatus, @@ -374,6 +379,8 @@ BOOST_PYTHON_MODULE( pykd ) "Return current processor mode as string: X86, ARM, IA64 or X64" ); python::def( "getProcessorType", &getProcessorType, "Return type of physical processor: X86, ARM, IA64 or X64" ); + python::def( "getSourceLine", &getSourceLine, getSourceLine_( python::args( "offset"), + "Return source file name, line and displacement by the specified offset" ) ); python::def( "getThreadList", &getThreadList, "Return list of threads (each item is numeric identifier of thread)" ); python::def( "is64bitSystem", &is64bitSystem,