mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-20 03:23:23 +08:00
[0.2.x] added : loadDump, isKernelDebugging, isDumpAnalyzing routines
git-svn-id: https://pykd.svn.codeplex.com/svn@78810 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
parent
ced206cc0a
commit
02228e6714
1125
pykd/context.cpp
1125
pykd/context.cpp
File diff suppressed because it is too large
Load Diff
@ -1,10 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <CvConst.h>
|
//#include <CvConst.h>
|
||||||
|
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
#include "dbgobj.h"
|
|
||||||
#include "dbgexcept.h"
|
#include "dbgexcept.h"
|
||||||
|
|
||||||
namespace pykd {
|
namespace pykd {
|
||||||
@ -24,72 +23,77 @@ std::string processorToStr(ULONG processorMode);
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
class ThreadContext : private DbgObject
|
class ThreadContext
|
||||||
{
|
{
|
||||||
public:
|
//public:
|
||||||
typedef std::map<ULONG, ULONG64> RegValues;
|
//typedef std::map<ULONG, ULONG64> RegValues;
|
||||||
|
|
||||||
ThreadContext( IDebugClient4 *client );
|
//ThreadContext();
|
||||||
static ContextPtr getWow64Context( IDebugClient4 *client );
|
////static ContextPtr getWow64Context();
|
||||||
|
|
||||||
// get register value by ID
|
//// get register value by ID
|
||||||
ULONG64 getValue(ULONG cvRegId) const;
|
//ULONG64 getValue(ULONG cvRegId) const;
|
||||||
ULONG64 getValueByName( const std::string ®Name ) const;
|
//ULONG64 getValueByName( const std::string ®Name ) const;
|
||||||
bool getValueNoThrow(ULONG cvRegId, ULONG64 &val) const;
|
//bool getValueNoThrow(ULONG cvRegId, ULONG64 &val) const;
|
||||||
|
|
||||||
// get @$ip pseudo register
|
//// get @$ip pseudo register
|
||||||
ULONG64 getIp() const;
|
//ULONG64 getIp() const;
|
||||||
|
|
||||||
// get @$retreg pseudo register
|
//// get @$retreg pseudo register
|
||||||
ULONG64 getRetReg() const;
|
//ULONG64 getRetReg() const;
|
||||||
|
|
||||||
// get @$csp pseudo register
|
//// get @$csp pseudo register
|
||||||
ULONG64 getSp() const;
|
//ULONG64 getSp() const;
|
||||||
|
|
||||||
// enumerate register values: tuple<CV_REG_ID, VALUE>
|
//// enumerate register values: tuple<CV_REG_ID, VALUE>
|
||||||
ULONG getCount() const {
|
//ULONG getCount() const {
|
||||||
return static_cast<ULONG>( m_regValues.size() );
|
// return static_cast<ULONG>( m_regValues.size() );
|
||||||
}
|
//}
|
||||||
|
|
||||||
python::object getByIndex(ULONG ind) const;
|
//python::object getByIndex(ULONG ind) const;
|
||||||
|
|
||||||
// get processor type
|
//// get processor type
|
||||||
std::string getProcessorType() const {
|
//std::string getProcessorType() const {
|
||||||
return pykd::processorToStr(m_processorType);
|
// return pykd::processorToStr(m_processorType);
|
||||||
}
|
//}
|
||||||
|
|
||||||
ContextPtr forkByStackFrame(const StackFrame &stkFrmae) const;
|
//ContextPtr forkByStackFrame(const StackFrame &stkFrmae) const;
|
||||||
|
|
||||||
std::string print() const;
|
//std::string print() const;
|
||||||
|
|
||||||
protected:
|
//protected:
|
||||||
ThreadContext(
|
//ThreadContext(
|
||||||
IDebugClient4 *client,
|
// ULONG processorType
|
||||||
ULONG processorType
|
//);
|
||||||
);
|
|
||||||
|
|
||||||
void queryRegisters(
|
//void queryRegisters(
|
||||||
const CvRegName *regs,
|
// const CvRegName *regs,
|
||||||
ULONG countOfRegs
|
// ULONG countOfRegs
|
||||||
);
|
//);
|
||||||
|
|
||||||
// query i386 registers
|
//// query i386 registers
|
||||||
void getI386Context();
|
//void getI386Context();
|
||||||
|
|
||||||
// query AMD64 registers
|
//// query AMD64 registers
|
||||||
void getAmd64Context();
|
//void getAmd64Context();
|
||||||
|
|
||||||
// try query as "sub-register"
|
//// try query as "sub-register"
|
||||||
bool getSubValue(ULONG cvRegId, ULONG64 &val) const;
|
//bool getSubValue(ULONG cvRegId, ULONG64 &val) const;
|
||||||
|
|
||||||
void __declspec(noreturn) throwUnsupportedProcessor(PCSTR szFunction) const;
|
//void __declspec(noreturn) throwUnsupportedProcessor(PCSTR szFunction) const;
|
||||||
|
|
||||||
private:
|
//private:
|
||||||
RegValues m_regValues;
|
//RegValues m_regValues;
|
||||||
|
|
||||||
ULONG m_processorType;
|
//ULONG m_processorType;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
//ContextPtr getThreadContext();
|
||||||
|
//
|
||||||
|
//python::dict getLocals( ContextPtr ctx = getThreadContext() );
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,11 @@ ULONG startProcess( const std::wstring &processName );
|
|||||||
void detachProcess( ULONG processId = -1);
|
void detachProcess( ULONG processId = -1);
|
||||||
void terminateProcess( ULONG processId = -1);
|
void terminateProcess( ULONG processId = -1);
|
||||||
|
|
||||||
|
void loadDump( const std::wstring &fileName );
|
||||||
|
|
||||||
|
bool isDumpAnalyzing();
|
||||||
|
bool isKernelDebugging();
|
||||||
|
|
||||||
void debugGo();
|
void debugGo();
|
||||||
|
|
||||||
// system properties
|
// system properties
|
||||||
|
214
pykd/livevar.cpp
214
pykd/livevar.cpp
@ -1,214 +0,0 @@
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include <stdafx.h>
|
|
||||||
|
|
||||||
#include "dbgclient.h"
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
namespace pykd {
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
namespace impl {
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
struct addLocals {
|
|
||||||
python::dict &m_locals;
|
|
||||||
const ModulePtr m_module;
|
|
||||||
ULONG m_rva;
|
|
||||||
ContextPtr m_ctx;
|
|
||||||
IDebugClient4 *m_client;
|
|
||||||
ULONG m_formalNameCounter;
|
|
||||||
CComPtr< IDebugDataSpaces4 > m_dataSpaces;
|
|
||||||
|
|
||||||
void append(pyDia::SymbolPtr symParent);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void appendVar(pyDia::SymbolPtr symData);
|
|
||||||
|
|
||||||
void generateUniqueName(std::string &varName);
|
|
||||||
|
|
||||||
TypedVarPtr getTypeVarByOffset(
|
|
||||||
pyDia::SymbolPtr symData,
|
|
||||||
ULONG64 varOffset
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
struct Exception : public DbgException {
|
|
||||||
Exception() : DbgException("build list of locals: internal exception")
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void addLocals::append(pyDia::SymbolPtr symParent)
|
|
||||||
{
|
|
||||||
// add all local variables
|
|
||||||
pyDia::SymbolPtrList lstLocals = symParent->findChildrenImpl(SymTagData);
|
|
||||||
pyDia::SymbolPtrList::iterator it = lstLocals.begin();
|
|
||||||
while (it != lstLocals.end())
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
appendVar(*it);
|
|
||||||
}
|
|
||||||
catch (const DbgException &e)
|
|
||||||
{
|
|
||||||
DBG_UNREFERENCED_LOCAL_VARIABLE(e);
|
|
||||||
}
|
|
||||||
++it;
|
|
||||||
}
|
|
||||||
|
|
||||||
// process all scopes
|
|
||||||
pyDia::SymbolPtrList lstScopes = symParent->findChildrenImpl(SymTagBlock);
|
|
||||||
it = lstScopes.begin();
|
|
||||||
while ( it != lstScopes.end() )
|
|
||||||
{
|
|
||||||
const ULONG scopeRva = (*it)->getRva();
|
|
||||||
if ( (scopeRva <= m_rva) && (scopeRva + (*it)->getSize() > m_rva) )
|
|
||||||
append(*it);
|
|
||||||
++it;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void addLocals::appendVar(pyDia::SymbolPtr symData)
|
|
||||||
{
|
|
||||||
TypedVarPtr typedVar;
|
|
||||||
|
|
||||||
std::string varName = symData->getName();
|
|
||||||
|
|
||||||
// check name for unique. f.e. may be may be somewhat parameters
|
|
||||||
// with name "__formal"
|
|
||||||
generateUniqueName(varName);
|
|
||||||
|
|
||||||
switch (symData->getLocType())
|
|
||||||
{
|
|
||||||
case LocIsStatic:
|
|
||||||
typedVar =
|
|
||||||
getTypeVarByOffset(
|
|
||||||
symData,
|
|
||||||
m_module->getBase() + symData->getRva() );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LocIsRegRel:
|
|
||||||
typedVar =
|
|
||||||
getTypeVarByOffset(
|
|
||||||
symData,
|
|
||||||
m_ctx->getValue( symData->getRegisterId() )+ symData->getOffset() );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LocIsEnregistered: // FIXME
|
|
||||||
default:
|
|
||||||
throw ImplementException(__FILE__,__LINE__,"Fix ME");
|
|
||||||
}
|
|
||||||
typedVar->setDataKind( symData->getDataKind() );
|
|
||||||
m_locals[varName] = typedVar;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void addLocals::generateUniqueName(std::string &varName)
|
|
||||||
{
|
|
||||||
if ( !m_locals.has_key(varName) )
|
|
||||||
return;
|
|
||||||
|
|
||||||
std::string origVarName = varName;
|
|
||||||
while ( m_locals.has_key(varName) )
|
|
||||||
{
|
|
||||||
std::stringstream sstream;
|
|
||||||
sstream << origVarName << ++m_formalNameCounter;
|
|
||||||
varName = sstream.str();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
TypedVarPtr addLocals::getTypeVarByOffset(
|
|
||||||
pyDia::SymbolPtr symData,
|
|
||||||
ULONG64 varOffset
|
|
||||||
)
|
|
||||||
{
|
|
||||||
pyDia::SymbolPtr symType = symData->getType();
|
|
||||||
|
|
||||||
TypeInfoPtr typeInfo = TypeInfo::getTypeInfo( symType );
|
|
||||||
|
|
||||||
return TypedVar::getTypedVar( m_client, typeInfo, VarDataMemory::factory(m_dataSpaces, varOffset) );
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
static ULONG getUnnamedChildRva(
|
|
||||||
pyDia::SymbolPtr symParent,
|
|
||||||
ULONG SymTag
|
|
||||||
)
|
|
||||||
{
|
|
||||||
pyDia::SymbolPtrList childs = symParent->findChildrenImpl(SymTag);
|
|
||||||
if (childs.empty())
|
|
||||||
throw Exception();
|
|
||||||
|
|
||||||
return (*childs.begin())->getRva();
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
static bool isOutOfDebugRange(
|
|
||||||
ULONG rva,
|
|
||||||
pyDia::SymbolPtr symFunc
|
|
||||||
)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (rva < getUnnamedChildRva(symFunc, SymTagFuncDebugStart))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (rva > getUnnamedChildRva(symFunc, SymTagFuncDebugEnd))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
catch (const DbgException &)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
python::dict DebugClient::getLocals(ContextPtr ctx OPTIONAL)
|
|
||||||
{
|
|
||||||
if (!ctx)
|
|
||||||
ctx = getThreadContext();
|
|
||||||
|
|
||||||
const ULONG64 instrPtr = ctx->getIp();
|
|
||||||
|
|
||||||
ModulePtr mod = loadModuleByOffset( instrPtr );
|
|
||||||
const ULONG rva = static_cast<ULONG>( instrPtr - mod->getBase() );
|
|
||||||
|
|
||||||
pyDia::GlobalScopePtr globScope = mod->getDia();
|
|
||||||
LONG funcDispl;
|
|
||||||
pyDia::SymbolPtr symFunc =
|
|
||||||
globScope->findByRvaImpl(rva, SymTagFunction, funcDispl);
|
|
||||||
if (impl::isOutOfDebugRange(rva, symFunc))
|
|
||||||
return python::dict(); // out of function debug range
|
|
||||||
|
|
||||||
python::dict locals;
|
|
||||||
impl::addLocals Locals = { locals, mod, rva, ctx, m_client, 0, m_dataSpaces };
|
|
||||||
|
|
||||||
Locals.append(symFunc);
|
|
||||||
|
|
||||||
return locals;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
30
pykd/localvar.cpp
Normal file
30
pykd/localvar.cpp
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
|
||||||
|
#include <stdafx.h>
|
||||||
|
|
||||||
|
#include "localvar.h"
|
||||||
|
#include "module.h"
|
||||||
|
#include "symengine.h"
|
||||||
|
#include "dbgengine.h"
|
||||||
|
#include "typedvar.h"
|
||||||
|
|
||||||
|
namespace pykd {
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
python::dict getLocals()
|
||||||
|
{
|
||||||
|
return getLocalsByFrame( getCurrentStackFrame() );
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
python::dict getLocalsByFrame( StackFrame &frame )
|
||||||
|
{
|
||||||
|
python::dict dct;
|
||||||
|
return dct;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
} //end pykd namespace
|
||||||
|
|
@ -193,4 +193,16 @@ python::list Module::getTypedVarListByTypeName( ULONG64 listHeadAddress, const s
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
SymbolPtr Module::getSymbolByVa( ULONG64 offset, ULONG symTag, LONG* displacment )
|
||||||
|
{
|
||||||
|
offset = addr64(offset);
|
||||||
|
|
||||||
|
if ( offset < m_base || offset > getEnd() )
|
||||||
|
throw DbgException( "address is out of the module space" );
|
||||||
|
|
||||||
|
return getSymSession()->findByRva( (ULONG)(offset - m_base ), symTag, displacment );
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
}; // end of namespace pykd
|
}; // end of namespace pykd
|
||||||
|
@ -93,6 +93,8 @@ public:
|
|||||||
|
|
||||||
ULONG64 getSymbolSize( const std::string &symName );
|
ULONG64 getSymbolSize( const std::string &symName );
|
||||||
|
|
||||||
|
SymbolPtr getSymbolByVa( ULONG64 offset, ULONG symTag, LONG* displacemnt );
|
||||||
|
|
||||||
std::string print();
|
std::string print();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -369,6 +369,10 @@
|
|||||||
RelativePath=".\disasm.cpp"
|
RelativePath=".\disasm.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\localvar.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\module.cpp"
|
RelativePath=".\module.cpp"
|
||||||
>
|
>
|
||||||
@ -467,6 +471,10 @@
|
|||||||
RelativePath=".\disasmengine.h"
|
RelativePath=".\disasmengine.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\localvar.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\module.h"
|
RelativePath=".\module.h"
|
||||||
>
|
>
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "cpureg.h"
|
#include "cpureg.h"
|
||||||
#include "disasm.h"
|
#include "disasm.h"
|
||||||
#include "stkframe.h"
|
#include "stkframe.h"
|
||||||
|
#include "localvar.h"
|
||||||
|
|
||||||
using namespace pykd;
|
using namespace pykd;
|
||||||
|
|
||||||
@ -44,8 +45,6 @@ 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_MEMBER_FUNCTION_OVERLOADS( StackFrame_getLocals, StackFrame::getLocals, 0, 1 );
|
|
||||||
|
|
||||||
BOOST_PYTHON_MODULE( pykd )
|
BOOST_PYTHON_MODULE( pykd )
|
||||||
{
|
{
|
||||||
python::scope().attr("version") = pykdVersion;
|
python::scope().attr("version") = pykdVersion;
|
||||||
@ -58,6 +57,12 @@ BOOST_PYTHON_MODULE( pykd )
|
|||||||
"Stop process debugging");
|
"Stop process debugging");
|
||||||
python::def( "killProcess", &terminateProcess,
|
python::def( "killProcess", &terminateProcess,
|
||||||
"Stop debugging and terminate current process" );
|
"Stop debugging and terminate current process" );
|
||||||
|
python::def( "loadDump", &loadDump,
|
||||||
|
"Load crash dump");
|
||||||
|
python::def( "isDumpAnalyzing", &isDumpAnalyzing,
|
||||||
|
"Check if it is a dump analyzing ( not living debuggee )" );
|
||||||
|
python::def( "isKernelDebugging", &isKernelDebugging,
|
||||||
|
"Check if kernel dubugging is running" );
|
||||||
|
|
||||||
python::def( "go", &debugGo,
|
python::def( "go", &debugGo,
|
||||||
"Go debugging" );
|
"Go debugging" );
|
||||||
@ -162,7 +167,7 @@ BOOST_PYTHON_MODULE( pykd )
|
|||||||
// 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" );
|
||||||
|
python::def( "getLocals", &getLocals, "Get list of local variables" );
|
||||||
|
|
||||||
python::class_<intBase>( "intBase", "intBase", python::no_init )
|
python::class_<intBase>( "intBase", "intBase", python::no_init )
|
||||||
.def( python::init<python::object&>() )
|
.def( python::init<python::object&>() )
|
||||||
@ -318,6 +323,33 @@ BOOST_PYTHON_MODULE( pykd )
|
|||||||
.def( "__str__", &StackFrame::print,
|
.def( "__str__", &StackFrame::print,
|
||||||
"Return stacks frame as a string");
|
"Return stacks frame as a string");
|
||||||
|
|
||||||
|
//python::class_<ThreadContext, ContextPtr>(
|
||||||
|
// "Context", "Context of thread (register values)", python::no_init )
|
||||||
|
// .def( "ip", &ThreadContext::getIp,
|
||||||
|
// "Get instruction pointer register" )
|
||||||
|
// .def( "retreg", &ThreadContext::getRetReg,
|
||||||
|
// "Get primary return value register" )
|
||||||
|
// .def( "csp", &ThreadContext::getSp,
|
||||||
|
// "Get current stack pointer" )
|
||||||
|
// .def( "get", &ThreadContext::getValue,
|
||||||
|
// "Get register value by ID (CV_REG_XXX)" )
|
||||||
|
// .def( "get", &ThreadContext::getValueByName,
|
||||||
|
// "Get register value by name" )
|
||||||
|
// .def( "processorType", &ThreadContext::getProcessorType,
|
||||||
|
// "Get processor ThreadContext as string")
|
||||||
|
// .def( "fork", &ThreadContext::forkByStackFrame,
|
||||||
|
// "Create new thread context by stackFrame")
|
||||||
|
// .def("__len__", &ThreadContext::getCount,
|
||||||
|
// "Return count of registers")
|
||||||
|
// .def("__getitem__", &ThreadContext::getByIndex,
|
||||||
|
// "Return tuple<ID, NAME, VALUE> by index")
|
||||||
|
// .def("__getitem__", &ThreadContext::getValueByName,
|
||||||
|
// "Return register value by name" )
|
||||||
|
// .def("__getattr__", &ThreadContext::getValueByName,
|
||||||
|
// "Return register value as a attribute of the Context" )
|
||||||
|
// .def("__str__", &ThreadContext::print,
|
||||||
|
// "Return context as a string" );
|
||||||
|
|
||||||
python::class_<Disasm>("disasm", "Class disassemble a processor instructions" )
|
python::class_<Disasm>("disasm", "Class disassemble a processor instructions" )
|
||||||
.def( python::init<>( "constructor" ) )
|
.def( python::init<>( "constructor" ) )
|
||||||
.def( python::init<ULONG64>( boost::python::args("offset"), "constructor" ) )
|
.def( python::init<ULONG64>( boost::python::args("offset"), "constructor" ) )
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "stkframe.h"
|
#include "stkframe.h"
|
||||||
#include "dbgengine.h"
|
#include "dbgengine.h"
|
||||||
|
#include "localvar.h"
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@ -40,6 +41,13 @@ std::string StackFrame::print() const
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
python::dict StackFrame::getLocals()
|
||||||
|
{
|
||||||
|
return getLocalsByFrame( *this );
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
python::list getCurrentStack()
|
python::list getCurrentStack()
|
||||||
{
|
{
|
||||||
ULONG frameCount = getStackTraceFrameCount();
|
ULONG frameCount = getStackTraceFrameCount();
|
||||||
@ -62,6 +70,19 @@ python::list getCurrentStack()
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
StackFrame getCurrentStackFrame()
|
||||||
|
{
|
||||||
|
ULONG frameCount = getStackTraceFrameCount();
|
||||||
|
|
||||||
|
std::vector<STACK_FRAME_DESC> frames(frameCount);
|
||||||
|
|
||||||
|
getStackTrace( &frames[0], frameCount );
|
||||||
|
|
||||||
|
return frames[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
} // namespace pykd
|
} // namespace pykd
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "dbgengine.h"
|
#include "dbgengine.h"
|
||||||
|
#include "context.h"
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@ -17,7 +18,7 @@ class StackFrame
|
|||||||
public:
|
public:
|
||||||
StackFrame( const STACK_FRAME_DESC& desc );
|
StackFrame( const STACK_FRAME_DESC& desc );
|
||||||
|
|
||||||
// python::dict getLocals(ContextPtr ctx = ContextPtr());
|
python::dict getLocals();
|
||||||
|
|
||||||
std::string print() const;
|
std::string print() const;
|
||||||
|
|
||||||
@ -33,6 +34,8 @@ public:
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
StackFrame getCurrentStackFrame();
|
||||||
|
|
||||||
python::list getCurrentStack();
|
python::list getCurrentStack();
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -91,6 +91,58 @@ void terminateProcess( ULONG processId )
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void loadDump( const std::wstring &fileName )
|
||||||
|
{
|
||||||
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
||||||
|
|
||||||
|
HRESULT hres;
|
||||||
|
|
||||||
|
hres = g_dbgEng->client->OpenDumpFileWide( fileName.c_str(), NULL );
|
||||||
|
if ( FAILED( hres ) )
|
||||||
|
throw DbgException( "IDebugClient4::OpenDumpFileWide failed" );
|
||||||
|
|
||||||
|
hres = g_dbgEng->control->WaitForEvent(DEBUG_WAIT_DEFAULT, INFINITE);
|
||||||
|
if ( FAILED( hres ) )
|
||||||
|
throw DbgException( "IDebugControl::WaitForEvent failed" );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool isDumpAnalyzing()
|
||||||
|
{
|
||||||
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
||||||
|
|
||||||
|
HRESULT hres;
|
||||||
|
ULONG debugClass, debugQualifier;
|
||||||
|
|
||||||
|
hres = g_dbgEng->control->GetDebuggeeType( &debugClass, &debugQualifier );
|
||||||
|
|
||||||
|
if ( FAILED( hres ) )
|
||||||
|
throw DbgException( "IDebugControl::GetDebuggeeType failed" );
|
||||||
|
|
||||||
|
return debugQualifier >= DEBUG_DUMP_SMALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool isKernelDebugging()
|
||||||
|
{
|
||||||
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
||||||
|
|
||||||
|
HRESULT hres;
|
||||||
|
ULONG debugClass, debugQualifier;
|
||||||
|
|
||||||
|
hres = g_dbgEng->control->GetDebuggeeType( &debugClass, &debugQualifier );
|
||||||
|
|
||||||
|
if ( FAILED( hres ) )
|
||||||
|
throw DbgException( "IDebugControl::GetDebuggeeType failed" );
|
||||||
|
|
||||||
|
return debugClass == DEBUG_CLASS_KERNEL;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void debugGo()
|
void debugGo()
|
||||||
{
|
{
|
||||||
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
||||||
|
@ -48,9 +48,7 @@ if __name__ == "__main__":
|
|||||||
target.module.reload();
|
target.module.reload();
|
||||||
|
|
||||||
pykd.go()
|
pykd.go()
|
||||||
|
|
||||||
unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run(getTestSuite( "typedvar.TypedVarTest.testPrint" ) )
|
|
||||||
|
|
||||||
unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run( getTestSuite() )
|
unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run( getTestSuite() )
|
||||||
|
|
||||||
pykd.killProcess( processId )
|
pykd.killProcess( processId )
|
||||||
|
Loading…
Reference in New Issue
Block a user