mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-20 03:23:23 +08:00
[0.1.x]
+ get local variables dict {name: typedVar, ....} ~ DiaSymbol::findEx add default params ~ re-query pdb-file name for module + dataKind for typedVar git-svn-id: https://pykd.svn.codeplex.com/svn@73103 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
parent
43cc22a89f
commit
b708cfefe4
@ -193,7 +193,7 @@ void DebugClient::startProcess( const std::wstring &processName )
|
||||
if ( FAILED( hres ) )
|
||||
throw DbgException( "IDebugControl::SetEngineOptions failed" );
|
||||
|
||||
std::vector< std::wstring::value_type> cmdLine( processName.size() + 1 );
|
||||
std::vector< std::wstring::value_type > cmdLine( processName.size() + 1 );
|
||||
wcscpy_s( &cmdLine[0], cmdLine.size(), processName.c_str() );
|
||||
|
||||
hres = m_client->CreateProcessWide( 0, &cmdLine[0], DEBUG_PROCESS | DETACHED_PROCESS );
|
||||
|
@ -240,6 +240,9 @@ public:
|
||||
);
|
||||
}
|
||||
|
||||
python::dict getLocals(
|
||||
Ctx::ContextPtr ctx = Ctx::ContextPtr( reinterpret_cast<Ctx::Registers *>(0) )
|
||||
);
|
||||
public:
|
||||
|
||||
CComPtr<IDebugClient4>&
|
||||
@ -398,6 +401,13 @@ inline Ctx::ContextPtr getThreadContext() {
|
||||
return g_dbgClient->getThreadContext();
|
||||
}
|
||||
|
||||
inline python::dict getLocals(
|
||||
Ctx::ContextPtr ctx = Ctx::ContextPtr( reinterpret_cast<Ctx::Registers *>(0) )
|
||||
)
|
||||
{
|
||||
return g_dbgClient->getLocals(ctx);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<ULONG status>
|
||||
|
@ -78,6 +78,7 @@ BOOST_PYTHON_FUNCTION_OVERLOADS( loadSignWords_, loadSignWords, 2, 3 );
|
||||
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( getLocals_, getLocals, 0, 1 );
|
||||
|
||||
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( DebugClient_loadChars, DebugClient::loadChars, 2, 3 );
|
||||
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( DebugClient_loadWChars, DebugClient::loadWChars, 2, 3 );
|
||||
@ -90,7 +91,8 @@ BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( DebugClient_loadSignWords, DebugClient::
|
||||
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( DebugClient_loadSignDWords, DebugClient::loadSignDWords, 2, 3 );
|
||||
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( DebugClient_loadSignQWords, DebugClient::loadSignQWords, 2, 3 );
|
||||
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( DebugClient_compareMemory, DebugClient::compareMemory, 3, 4 );
|
||||
|
||||
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( DebugClient_getLocals, DebugClient::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)
|
||||
@ -287,6 +289,8 @@ BOOST_PYTHON_MODULE( pykd )
|
||||
"Get the page size for the currently executing processor context" )
|
||||
.def( "getContext", &DebugClient::getThreadContext,
|
||||
"Get context of current thread (register values)" )
|
||||
.def( "getLocals", &DebugClient::getLocals, DebugClient_getLocals( python::args( "ctx" ),
|
||||
"Get list of local variables" ) )
|
||||
.def( "addSynSymbol", &DebugClient::addSyntheticSymbol,
|
||||
"Add new synthetic symbol for virtual address" )
|
||||
.def( "delAllSynSymbols", &DebugClient::delAllSyntheticSymbols,
|
||||
@ -460,6 +464,8 @@ BOOST_PYTHON_MODULE( pykd )
|
||||
"Get the page size for the currently executing processor context" );
|
||||
python::def( "getContext", &getThreadContext,
|
||||
"Get context of current thread (register values)" );
|
||||
python::def( "getLocals", &getLocals, getLocals_( python::args( "ctx" ),
|
||||
"Get list of local variables" ) );
|
||||
|
||||
python::class_<TypeInfo, TypeInfoPtr, python::bases<intBase>, boost::noncopyable >("typeInfo", "Class representing typeInfo", python::no_init )
|
||||
.def( "name", &TypeInfo::getName )
|
||||
@ -483,6 +489,8 @@ BOOST_PYTHON_MODULE( pykd )
|
||||
"Return offset to parent" )
|
||||
.def("field", &TypedVar::getField,
|
||||
"Return field of structure as an object attribute" )
|
||||
.def( "dataKind", &TypedVar::getDataKind,
|
||||
"Retrieves the variable classification of a data: DataIsXxx")
|
||||
.def("deref", &TypedVar::deref,
|
||||
"Return value by pointer" )
|
||||
.def("__getattr__", &TypedVar::getField,
|
||||
@ -615,12 +623,12 @@ BOOST_PYTHON_MODULE( pykd )
|
||||
"Return tuple<ID, VALUE> by index");
|
||||
|
||||
python::def( "diaLoadPdb", &pyDia::GlobalScope::loadPdb,
|
||||
"Open pdb file for quering debug symbols. Return DiaSymbol of global scope");
|
||||
"Open pdb file for querying debug symbols. Return DiaSymbol of global scope");
|
||||
|
||||
python::class_<pyDia::Symbol, pyDia::SymbolPtr>(
|
||||
"DiaSymbol", "class wrapper for MS DIA Symbol", python::no_init )
|
||||
.def( "findEx", &pyDia::Symbol::findChildrenEx,
|
||||
"Retrieves the children of the symbol" )
|
||||
.def( "findEx", &pyDia::Symbol::findChildrenEx, pyDia_Symbol_findChildrenEx( python::args( "symTag", "name", "cmpFlags" ) ,
|
||||
"Retrieves the children of the symbol" ) )
|
||||
.def( "find", &pyDia::Symbol::findChildren,
|
||||
"Retrieves the children of the symbol" )
|
||||
.def( "size", &pyDia::Symbol::getSize,
|
||||
|
@ -59,7 +59,7 @@ void Exception::exceptionTranslate( const Exception &e )
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::list< SymbolPtr > Symbol::findChildrenImpl(
|
||||
SymbolPtrList Symbol::findChildrenImpl(
|
||||
ULONG symTag,
|
||||
const std::string &name,
|
||||
DWORD nameCmpFlags
|
||||
@ -89,7 +89,7 @@ std::list< SymbolPtr > Symbol::findChildrenImpl(
|
||||
if (S_OK != hres)
|
||||
throw Exception("Call IDiaSymbol::findChildren", hres);
|
||||
|
||||
std::list< SymbolPtr > childList;
|
||||
SymbolPtrList childList;
|
||||
|
||||
DiaSymbolPtr child;
|
||||
ULONG celt;
|
||||
|
@ -55,6 +55,7 @@ private:
|
||||
|
||||
class Symbol;
|
||||
typedef boost::shared_ptr< Symbol > SymbolPtr;
|
||||
typedef std::list< SymbolPtr > SymbolPtrList;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Symbol
|
||||
@ -77,16 +78,16 @@ public:
|
||||
}
|
||||
|
||||
|
||||
std::list< SymbolPtr > findChildrenImpl(
|
||||
SymbolPtrList findChildrenImpl(
|
||||
ULONG symTag,
|
||||
const std::string &name,
|
||||
DWORD nameCmpFlags
|
||||
const std::string &name = "",
|
||||
DWORD nameCmpFlags = 0
|
||||
);
|
||||
|
||||
python::list findChildrenEx(
|
||||
ULONG symTag,
|
||||
const std::string &name,
|
||||
DWORD nameCmpFlags
|
||||
const std::string &name = "",
|
||||
DWORD nameCmpFlags = 0
|
||||
)
|
||||
{
|
||||
return toPyList( findChildrenImpl(symTag, name, nameCmpFlags) );
|
||||
|
190
pykd/livevar.cpp
Normal file
190
pykd/livevar.cpp
Normal file
@ -0,0 +1,190 @@
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdafx.h>
|
||||
|
||||
#include "dbgclient.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace pykd {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace impl {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct addLocals {
|
||||
python::dict &m_locals;
|
||||
const Module &m_module;
|
||||
ULONG m_rva;
|
||||
Ctx::ContextPtr m_ctx;
|
||||
IDebugClient4 *m_client;
|
||||
|
||||
void append(pyDia::SymbolPtr symParent);
|
||||
|
||||
private:
|
||||
void appendVar(pyDia::SymbolPtr symData);
|
||||
|
||||
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();
|
||||
|
||||
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 Exception();
|
||||
}
|
||||
typedVar->setDataKind( symData->getDataKind() );
|
||||
m_locals[varName] = typedVar;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TypedVarPtr addLocals::getTypeVarByOffset(
|
||||
pyDia::SymbolPtr symData,
|
||||
ULONG64 varOffset
|
||||
)
|
||||
{
|
||||
pyDia::SymbolPtr symType = symData->getType();
|
||||
|
||||
TypeInfoPtr typeInfo = TypeInfo::getTypeInfo( symType );
|
||||
|
||||
return TypedVar::getTypedVar( m_client, typeInfo, 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(Ctx::ContextPtr ctx OPTIONAL)
|
||||
{
|
||||
if (!ctx)
|
||||
ctx = getThreadContext();
|
||||
|
||||
const ULONG64 instrPtr = ctx->getIp();
|
||||
|
||||
Module 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 };
|
||||
|
||||
Locals.append(symFunc);
|
||||
|
||||
return locals;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
@ -135,6 +135,24 @@ Module::getPdbName()
|
||||
if ( FAILED( hres ) )
|
||||
throw DbgException( "IDebugAdvanced2::GetSymbolInformation failed" );
|
||||
|
||||
if (!*moduleInfo.LoadedPdbName)
|
||||
{
|
||||
reloadSymbols();
|
||||
hres = m_advanced->GetSymbolInformation(
|
||||
DEBUG_SYMINFO_IMAGEHLP_MODULEW64,
|
||||
m_base,
|
||||
0,
|
||||
&moduleInfo,
|
||||
sizeof(moduleInfo),
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
NULL );
|
||||
|
||||
if ( FAILED( hres ) )
|
||||
throw DbgException( "IDebugAdvanced2::GetSymbolInformation failed" );
|
||||
}
|
||||
|
||||
char pdbName[ 256 ];
|
||||
WideCharToMultiByte( CP_ACP, 0, moduleInfo.LoadedPdbName, 256, pdbName, 256, NULL, NULL );
|
||||
|
||||
|
@ -28,15 +28,15 @@ public:
|
||||
return m_imageName;
|
||||
}
|
||||
|
||||
ULONG64 getBase() {
|
||||
ULONG64 getBase() const {
|
||||
return m_base;
|
||||
}
|
||||
|
||||
ULONG64 getEnd() {
|
||||
ULONG64 getEnd() const {
|
||||
return m_base + m_size;
|
||||
}
|
||||
|
||||
ULONG getSize() {
|
||||
ULONG getSize() const {
|
||||
return m_size;
|
||||
}
|
||||
|
||||
@ -80,17 +80,16 @@ public:
|
||||
|
||||
python::list getTypedVarArrayByType( ULONG64 addr, const TypeInfoPtr &typeInfo, ULONG number );
|
||||
|
||||
|
||||
private:
|
||||
|
||||
ULONG getRvaByName(const std::string &symName);
|
||||
|
||||
pyDia::GlobalScopePtr& getDia() {
|
||||
if (!m_dia)
|
||||
m_dia = pyDia::GlobalScope::loadPdb( getPdbName() );
|
||||
return m_dia;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
ULONG getRvaByName(const std::string &symName);
|
||||
|
||||
BaseTypeVariant getValue() {
|
||||
return BaseTypeVariant(m_base);
|
||||
}
|
||||
|
@ -409,6 +409,10 @@
|
||||
RelativePath=".\inteventhandler.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\livevar.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\module.cpp"
|
||||
>
|
||||
|
@ -57,7 +57,8 @@ TypedVarPtr TypedVar::getTypedVar( IDebugClient4 *client, const TypeInfoPtr& t
|
||||
TypedVar::TypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64 offset ) :
|
||||
DbgObject( client ),
|
||||
m_typeInfo( typeInfo ),
|
||||
m_offset( offset )
|
||||
m_offset( offset ),
|
||||
m_dataKind( DataIsGlobal )
|
||||
{
|
||||
m_size = m_typeInfo->getSize();
|
||||
}
|
||||
|
@ -61,6 +61,14 @@ public:
|
||||
return getElementByIndex( boost::apply_visitor( VariantToULong(), tv->getValue() ) );
|
||||
}
|
||||
|
||||
ULONG getDataKind() const {
|
||||
return m_dataKind;
|
||||
}
|
||||
|
||||
void setDataKind(ULONG dataKind) {
|
||||
m_dataKind = dataKind;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
TypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64 offset );
|
||||
@ -74,6 +82,8 @@ protected:
|
||||
ULONG64 m_offset;
|
||||
|
||||
ULONG m_size;
|
||||
|
||||
ULONG m_dataKind;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -65,7 +65,7 @@ BaseTypeVariant TypeInfo::getValue()
|
||||
return (LONG64)m_constantValue.llVal;
|
||||
}
|
||||
|
||||
throw DbgException( "Failed to convert constatnt type" );
|
||||
throw DbgException( "Failed to convert constant type" );
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -392,11 +392,11 @@ TypeInfoPtr TypeInfo::getRecurciveComplexType( TypeInfoPtr &lowestType, std::str
|
||||
|
||||
python::dict EnumTypeInfo::asMap()
|
||||
{
|
||||
python::dict dct;
|
||||
python::dict dct;
|
||||
|
||||
std::list< pyDia::SymbolPtr > symbolsList = m_dia->findChildrenImpl(SymTagData, "", nsfCaseSensitive );
|
||||
pyDia::SymbolPtrList symbolsList = m_dia->findChildrenImpl(SymTagData, "", nsfCaseSensitive );
|
||||
|
||||
for ( std::list< pyDia::SymbolPtr >::iterator it = symbolsList.begin(); it != symbolsList.end(); it++ )
|
||||
for ( pyDia::SymbolPtrList::iterator it = symbolsList.begin(); it != symbolsList.end(); it++ )
|
||||
{
|
||||
CComVariant val;
|
||||
|
||||
|
@ -21,30 +21,6 @@ class DbgClientTest( unittest.TestCase ):
|
||||
"""Size of memory page must be >= 4kb"""
|
||||
self.assertTrue( pykd.getPageSize() >= 4*1024 )
|
||||
|
||||
def testCurrentThreadContext( self ):
|
||||
"""Some check of current thread context content"""
|
||||
ctx = pykd.getContext()
|
||||
# for reg in ctx:
|
||||
# regName = ""
|
||||
# if ctx.processorType() == "X86":
|
||||
# regName = pykd.diaI386Regs[ reg[0] ]
|
||||
# else:
|
||||
# regName = pykd.diaAmd64Regs[ reg[0] ]
|
||||
# pykd.dprint( "\n" + regName + ": 0x%x " % reg[1])
|
||||
self.assertNotEqual( 0, len(ctx) )
|
||||
self.assertNotEqual( 0, ctx.ip() )
|
||||
self.assertNotEqual( 0, ctx.csp() )
|
||||
|
||||
self.assertEqual( (ctx.get(pykd.CV_REG_AH) << 8) | ctx.get(pykd.CV_REG_AL), ctx.get(pykd.CV_REG_AX) )
|
||||
self.assertEqual( ctx.get(pykd.CV_REG_AX), ctx.get(pykd.CV_REG_EAX) & 0xffff )
|
||||
if ctx.processorType() == "X64":
|
||||
self.assertEqual( ctx.get(pykd.CV_REG_EAX), ctx.get(pykd.CV_AMD64_RAX) & 0xffffffff )
|
||||
|
||||
self.assertEqual( (ctx.get(pykd.CV_REG_DH) << 8) | ctx.get(pykd.CV_REG_DL), ctx.get(pykd.CV_REG_DX) )
|
||||
self.assertEqual( ctx.get(pykd.CV_REG_DX), ctx.get(pykd.CV_REG_EDX) & 0xffff )
|
||||
if ctx.processorType() == "X64":
|
||||
self.assertEqual( ctx.get(pykd.CV_REG_EDX), ctx.get(pykd.CV_AMD64_RDX) & 0xffffffff )
|
||||
|
||||
def testIsDumpAnalyzing( self ):
|
||||
self.assertFalse( pykd.isDumpAnalyzing() )
|
||||
|
||||
|
32
test/scripts/localstest.py
Normal file
32
test/scripts/localstest.py
Normal file
@ -0,0 +1,32 @@
|
||||
"""Local variables tests"""
|
||||
|
||||
import unittest
|
||||
import target
|
||||
import pykd
|
||||
|
||||
class LocalVarsTest(unittest.TestCase):
|
||||
def testLocalVariable(self):
|
||||
"""Start new process and break in targetapp!EnumWindowsProc"""
|
||||
|
||||
testClient = pykd.createDbgClient()
|
||||
testClient.startProcess( target.appPath + " -testEnumWindows" )
|
||||
|
||||
testClient.go() # initial breakpoint -> wmain
|
||||
testClient.go() # wmain -> targetapp!EnumWindowsProc
|
||||
# pykd.dprint( "\n" + testClient.dbgCommand("u") )
|
||||
|
||||
locals = testClient.getLocals()
|
||||
|
||||
self.assertNotEqual( 0, locals["hWindow"] )
|
||||
self.assertEqual( pykd.DataIsParam, locals["hWindow"].dataKind() )
|
||||
|
||||
self.assertEqual( 6, locals["lParam"] )
|
||||
self.assertEqual( pykd.DataIsParam, locals["lParam"].dataKind() )
|
||||
|
||||
self.assertNotEqual( 0, locals["dwProccessId"] )
|
||||
self.assertEqual( pykd.DataIsLocal, locals["dwProccessId"].dataKind() )
|
||||
|
||||
self.assertNotEqual( 0, locals["staticVar"] )
|
||||
self.assertEqual( pykd.DataIsStaticLocal, locals["staticVar"].dataKind() )
|
||||
|
||||
self.assertEqual( locals["dwProccessId"], locals["staticVar"] )
|
@ -24,6 +24,8 @@ import memtest
|
||||
import intbase
|
||||
import synsymtest
|
||||
import ehloadtest
|
||||
import thrdctxtest
|
||||
import localstest
|
||||
|
||||
def getTestSuite( singleName = "" ):
|
||||
if singleName == "":
|
||||
@ -39,7 +41,9 @@ def getTestSuite( singleName = "" ):
|
||||
unittest.TestLoader().loadTestsFromTestCase( memtest.MemoryTest ),
|
||||
unittest.TestLoader().loadTestsFromTestCase( intbase.IntBaseTest ),
|
||||
unittest.TestLoader().loadTestsFromTestCase( synsymtest.SynSymTest ),
|
||||
unittest.TestLoader().loadTestsFromTestCase( ehloadtest.EhLoadTest )
|
||||
unittest.TestLoader().loadTestsFromTestCase( thrdctxtest.ThreadContextTest ),
|
||||
unittest.TestLoader().loadTestsFromTestCase( ehloadtest.EhLoadTest ),
|
||||
unittest.TestLoader().loadTestsFromTestCase( localstest.LocalVarsTest )
|
||||
] )
|
||||
else:
|
||||
return unittest.TestSuite( unittest.TestLoader().loadTestsFromName( singleName ) )
|
||||
@ -65,4 +69,4 @@ if __name__ == "__main__":
|
||||
|
||||
unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run( suite )
|
||||
|
||||
#a = raw_input("\npress return\n")
|
||||
#raw_input("\npress return\n")
|
||||
|
33
test/scripts/thrdctxtest.py
Normal file
33
test/scripts/thrdctxtest.py
Normal file
@ -0,0 +1,33 @@
|
||||
"""Tests of thread context"""
|
||||
|
||||
import unittest
|
||||
import target
|
||||
import pykd
|
||||
|
||||
class ThreadContextTest( unittest.TestCase ):
|
||||
def testCurrentThreadContext( self ):
|
||||
"""Some checks of current thread context content"""
|
||||
ctx = pykd.getContext()
|
||||
# for reg in ctx:
|
||||
# regName = ""
|
||||
# if ctx.processorType() == "X86":
|
||||
# regName = pykd.diaI386Regs[ reg[0] ]
|
||||
# else:
|
||||
# regName = pykd.diaAmd64Regs[ reg[0] ]
|
||||
# pykd.dprint( "\n" + regName + ": 0x%x " % reg[1])
|
||||
self.assertNotEqual( 0, len(ctx) )
|
||||
self.assertNotEqual( 0, ctx.ip() )
|
||||
self.assertNotEqual( 0, ctx.csp() )
|
||||
|
||||
def testComplexRegisters( self ):
|
||||
"""Test of "sub-"registers"""
|
||||
ctx = pykd.getContext()
|
||||
self.assertEqual( (ctx.get(pykd.CV_REG_AH) << 8) | ctx.get(pykd.CV_REG_AL), ctx.get(pykd.CV_REG_AX) )
|
||||
self.assertEqual( ctx.get(pykd.CV_REG_AX), ctx.get(pykd.CV_REG_EAX) & 0xffff )
|
||||
if ctx.processorType() == "X64":
|
||||
self.assertEqual( ctx.get(pykd.CV_REG_EAX), ctx.get(pykd.CV_AMD64_RAX) & 0xffffffff )
|
||||
|
||||
self.assertEqual( (ctx.get(pykd.CV_REG_DH) << 8) | ctx.get(pykd.CV_REG_DL), ctx.get(pykd.CV_REG_DX) )
|
||||
self.assertEqual( ctx.get(pykd.CV_REG_DX), ctx.get(pykd.CV_REG_EDX) & 0xffff )
|
||||
if ctx.processorType() == "X64":
|
||||
self.assertEqual( ctx.get(pykd.CV_REG_EDX), ctx.get(pykd.CV_AMD64_RDX) & 0xffffffff )
|
@ -21,7 +21,8 @@ class TypedVarTest( unittest.TestCase ):
|
||||
self.assertEqual( -2, target.module.typedVar( "g_shortValue" ) )
|
||||
self.assertEqual( -4, target.module.typedVar( "g_longValue" ) )
|
||||
self.assertEqual( -8, target.module.typedVar( "g_longlongValue" ) )
|
||||
self.assertEqual( True, target.module.typedVar( "g_constBoolValue" ) )
|
||||
try: self.assertEqual( True, target.module.typedVar( "g_constBoolValue" ) )
|
||||
except pykd.DiaException: self.assertTrue( False )
|
||||
|
||||
def testGetAddress( self ):
|
||||
tv = target.module.typedVar( "structTest", target.module.g_structTest )
|
||||
|
@ -261,17 +261,22 @@ void FuncWithName1(int a)
|
||||
|
||||
BOOL CALLBACK EnumWindowsProc(
|
||||
HWND hWindow,
|
||||
LPARAM lParam
|
||||
const LPARAM lParam
|
||||
)
|
||||
{
|
||||
DWORD dwProccessId = 0;
|
||||
if (hWindow)
|
||||
std::cout << lParam;
|
||||
|
||||
if (hWindow)
|
||||
{
|
||||
static ULONGLONG staticVar = 0;
|
||||
DWORD dwThreadId = ::GetWindowThreadProcessId(hWindow, &dwProccessId);
|
||||
std::cout << dwProccessId << dwThreadId;
|
||||
staticVar = dwProccessId;
|
||||
__debugbreak();
|
||||
std::cout << dwProccessId << dwThreadId << staticVar;
|
||||
}
|
||||
return FALSE;
|
||||
return hWindow ? FALSE : TRUE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -309,6 +314,9 @@ int _tmain(int argc, _TCHAR* argv[])
|
||||
// run with parameters
|
||||
if ( !_tcsicmp(argv[1], _T("-testLoadUnload")) )
|
||||
return doLoadUnload();
|
||||
|
||||
if ( !_tcsicmp(argv[1], _T("-testEnumWindows")) )
|
||||
return ::EnumWindows(&EnumWindowsProc, 6);
|
||||
}
|
||||
|
||||
__debugbreak();
|
||||
@ -316,8 +324,6 @@ int _tmain(int argc, _TCHAR* argv[])
|
||||
__debugbreak();
|
||||
FuncWithName0();
|
||||
FuncWithName1(2);
|
||||
|
||||
EnumWindows(&::EnumWindowsProc, 6);
|
||||
}
|
||||
catch(std::exception & ex)
|
||||
{
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="windows-1251"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9,00"
|
||||
Version="9.00"
|
||||
Name="targetapp"
|
||||
ProjectGUID="{C6254E16-AB8E-41EE-887D-31458E93FC68}"
|
||||
RootNamespace="targetapp"
|
||||
@ -428,6 +428,10 @@
|
||||
RelativePath="..\scripts\intbase.py"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\scripts\localstest.py"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\scripts\memtest.py"
|
||||
>
|
||||
@ -452,6 +456,10 @@
|
||||
RelativePath="..\scripts\target.py"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\scripts\thrdctxtest.py"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\scripts\typedvar.py"
|
||||
>
|
||||
|
Loading…
Reference in New Issue
Block a user