diff --git a/pykd/dbgclient.cpp b/pykd/dbgclient.cpp index 281b28c..f65439b 100644 --- a/pykd/dbgclient.cpp +++ b/pykd/dbgclient.cpp @@ -8,8 +8,7 @@ namespace pykd { /////////////////////////////////////////////////////////////////////////////////// -DebugClientPtr g_dbgClient( new DebugClient ); - +DebugClientPtr g_dbgClient( DebugClient::createDbgClient() ); void loadDump( const std::wstring &fileName ) { g_dbgClient->loadDump( fileName ); @@ -27,12 +26,21 @@ void attachKernel( const std::wstring ¶m ) { g_dbgClient->attachKernel( param ); } + +/////////////////////////////////////////////////////////////////////////////////// + +DebugClientPtr DebugClient::setDbgClientCurrent( DebugClientPtr newDbgClient ) { + DebugClientPtr oldClient = g_dbgClient; + g_dbgClient = newDbgClient; + return oldClient; +} + /////////////////////////////////////////////////////////////////////////////////// DebugClient::DebugClient() { HRESULT hres; - hres = DebugCreate( __uuidof(IDebugClient4), (void **)&m_client ); + hres = DebugCreate( __uuidof(IDebugClient5), (void **)&m_client ); if ( FAILED( hres ) ) throw DbgException("DebugCreate failed"); @@ -47,6 +55,25 @@ DebugClient::DebugClient() /////////////////////////////////////////////////////////////////////////////////// +DebugClient::DebugClient( IDebugClient4 *client ) +{ + HRESULT hres; + + hres = client->QueryInterface( __uuidof(IDebugClient5), (void**)&m_client ); + if ( FAILED( hres ) ) + throw DbgException("QueryInterface IDebugControl4 failed"); + + hres = client->QueryInterface( __uuidof(IDebugControl4), (void**)&m_control ); + if ( FAILED( hres ) ) + throw DbgException("QueryInterface IDebugControl4 failed"); + + hres = client->QueryInterface( __uuidof(IDebugSymbols3), (void**)&m_symbols ); + if ( FAILED( hres ) ) + throw DbgException("QueryInterface IDebugSymbols3 failed"); +} + +/////////////////////////////////////////////////////////////////////////////////// + void DebugClient::loadDump( const std::wstring &fileName ) { HRESULT hres; diff --git a/pykd/dbgclient.h b/pykd/dbgclient.h index 3dc8c49..1d8ec6b 100644 --- a/pykd/dbgclient.h +++ b/pykd/dbgclient.h @@ -24,8 +24,6 @@ class DebugClient { public: - DebugClient(); - virtual ~DebugClient() {} static @@ -33,6 +31,14 @@ public: return DebugClientPtr( new DebugClient() ); } + static + DebugClientPtr createDbgClient( IDebugClient4 *client ) { + return DebugClientPtr( new DebugClient(client) ); + } + + static + DebugClientPtr setDbgClientCurrent( DebugClientPtr newDbgClient ); + void loadDump( const std::wstring &fileName ); void startProcess( const std::wstring &processName ); @@ -53,13 +59,15 @@ public: private: + DebugClient(); + + DebugClient( IDebugClient4 *client ); + CComPtr m_client; CComPtr m_control; CComPtr m_symbols; }; - - ///////////////////////////////////////////////////////////////////////////////// extern DebugClientPtr g_dbgClient; diff --git a/pykd/dbgext.cpp b/pykd/dbgext.cpp index 07aa472..3e4d1ac 100644 --- a/pykd/dbgext.cpp +++ b/pykd/dbgext.cpp @@ -33,46 +33,6 @@ BOOL WINAPI DllMain( //////////////////////////////////////////////////////////////////////////////// -HRESULT -CALLBACK -DebugExtensionInitialize( - OUT PULONG Version, - OUT PULONG Flags ) -{ - *Version = DEBUG_EXTENSION_VERSION( 1, 0 ); - *Flags = 0; - - return S_OK; -} - -//////////////////////////////////////////////////////////////////////////////// - -VOID -CALLBACK -DebugExtensionUninitialize() -{ -} - -//////////////////////////////////////////////////////////////////////////////// - -HRESULT -CALLBACK -py( PDEBUG_CLIENT4 client, PCSTR args ) -{ - return S_OK; -} - -//////////////////////////////////////////////////////////////////////////////// - -HRESULT -CALLBACK -pycmd( PDEBUG_CLIENT4 client, PCSTR args ) -{ - return S_OK; -} - -//////////////////////////////////////////////////////////////////////////////// - static python::dict genDict(const pyDia::Symbol::ValueNameEntry srcValues[], size_t cntValues) { python::dict resDict; @@ -102,21 +62,24 @@ BOOST_PYTHON_MODULE( pykd ) .def( "findModule", &pykd::DebugClient::findModule, "Return instance of the Module class which posseses specified address" ); - boost::python::def( "createDbgClient", pykd::DebugClient::createDbgClient, - "create a new instance of the dbgClient class" ); - boost::python::def( "loadDump", &loadDump, +// python::def( "createDbgClient", pykd::DebugClient::createDbgClient, +// "create a new instance of the dbgClient class" ); + python::def( "loadDump", &loadDump, "Load crash dump (only for console)"); - boost::python::def( "startProcess", &startProcess, + python::def( "startProcess", &startProcess, "Start process for debugging (only for console)"); - boost::python::def( "attachProcess", &attachProcess, + python::def( "attachProcess", &attachProcess, "Attach debugger to a exsisting process" ); - boost::python::def( "attachKernel", &attachKernel, + python::def( "attachKernel", &attachKernel, "Attach debugger to a kernel target" ); - boost::python::def( "loadModule", &loadModule, + python::def( "loadModule", &loadModule, "Return instance of Module class" ); - boost::python::def( "findModule", &findModule, + python::def( "findModule", &findModule, "Return instance of the Module class which posseses specified address" ); + + python::class_("typeInfo", "Class representing typeInfo", python::no_init ); + python::class_("module", "Class representing executable module", python::no_init ) .def("begin", &pykd::Module::getBase, "Return start address of the module" ) @@ -136,9 +99,13 @@ BOOST_PYTHON_MODULE( pykd ) "Return offset of the symbol" ) .def("rva", &pykd::Module::getSymbolRva, "Return rva of the symbol" ) + .def("type", &pykd::Module::getTypeByName, + "Return typeInfo class by type name" ) .def("__getattr__", &pykd::Module::getSymbol, "Return address of the symbol" ); + + //.def("symbols", &pykd::Module::getSymbols, // "Return list of all symbols of the module" ); @@ -330,1109 +297,146 @@ BOOST_PYTHON_MODULE( pykd ) //////////////////////////////////////////////////////////////////////////////// +class WindbgGlobalSession +{ +public: + static + boost::python::object + global() { + return windbgGlobalSession->main.attr("__dict__"); + } + + static + VOID + StartWindbgSession() { + if ( 1 == InterlockedIncrement( &sessionCount ) ) + { + windbgGlobalSession = new WindbgGlobalSession(); + } + } + + static + VOID + StopWindbgSession() { + if ( 0 == InterlockedDecrement( &sessionCount ) ) + { + delete windbgGlobalSession; + windbgGlobalSession = NULL; + } + } + + static + bool isInit() { + return windbgGlobalSession != NULL; + } + +private: + + WindbgGlobalSession() { + + PyImport_AppendInittab("pykd", initpykd ); + + PyEval_InitThreads(); + + Py_Initialize(); + + main = boost::python::import("__main__"); + + python::object main_namespace = main.attr("__dict__"); + + // делаем аналог from pykd import * + python::object pykd = boost::python::import( "pykd" ); + + python::dict pykd_namespace( pykd.attr("__dict__") ); + + python::list iterkeys( pykd_namespace.iterkeys() ); + + for (int i = 0; i < boost::python::len(iterkeys); i++) + { + std::string key = boost::python::extract(iterkeys[i]); + + main_namespace[ key ] = pykd_namespace[ key ]; + } + } + + ~WindbgGlobalSession() { + } + + python::object main; + + static volatile LONG sessionCount; + + static WindbgGlobalSession *windbgGlobalSession; + +}; + +volatile LONG WindbgGlobalSession::sessionCount = 0; + +WindbgGlobalSession *WindbgGlobalSession::windbgGlobalSession = NULL; + +///////////////////////////////////////////////////////////////////////////////// + +HRESULT +CALLBACK +DebugExtensionInitialize( + OUT PULONG Version, + OUT PULONG Flags ) +{ + *Version = DEBUG_EXTENSION_VERSION( 1, 0 ); + *Flags = 0; + + WindbgGlobalSession::StartWindbgSession(); + + return S_OK; +} -//#include -// -//#include -// -//#include -//#include -//#include -//#include -// -//#include "dbgext.h" -//#include "dbgreg.h" -//#include "dbgtype.h" -//#include "dbgmodule.h" -//#include "dbgsym.h" -//#include "dbgmem.h" -//#include "dbgsystem.h" -//#include "dbgcmd.h" -//#include "dbgdump.h" -//#include "dbgexcept.h" -//#include "dbgeventcb.h" -//#include "dbgpath.h" -//#include "dbgprocess.h" -//#include "dbgsynsym.h" -//#include "dbgclient.h" -//#include "dbgevent.h" -//#include "dbgbreak.h" -//#include "dbgio.h" -//#include "intbase.h" -//#include "disasm.h" -// //////////////////////////////////////////////////////////////////////////////// -// -//// указатель на текущий интерфейс -//DbgExt *dbgExt = NULL; -// -//// глобальный клиент -//dbgClient g_dbgClient; -// -//// контескт исполнения нити питона -//__declspec( thread ) PyThreadStatePtr ptrPyThreadState = NULL; -// + +VOID +CALLBACK +DebugExtensionUninitialize() +{ + WindbgGlobalSession::StopWindbgSession(); +} + +//////////////////////////////////////////////////////////////////////////////// + +HRESULT +CALLBACK +py( PDEBUG_CLIENT4 client, PCSTR args ) +{ + DebugClientPtr dbgClient = DebugClient::createDbgClient( client ); + DebugClientPtr oldClient = DebugClient::setDbgClientCurrent( dbgClient ); + + PyThreadState *globalInterpreter = PyThreadState_Swap( NULL ); + PyThreadState *localInterpreter = Py_NewInterpreter(); + + try { + + + } + catch(...) + { + // dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "unexpected error" ); + } + + Py_EndInterpreter( localInterpreter ); + PyThreadState_Swap( globalInterpreter ); + + DebugClient::setDbgClientCurrent( oldClient ); + + return S_OK; +} + +//////////////////////////////////////////////////////////////////////////////// + +HRESULT +CALLBACK +pycmd( PDEBUG_CLIENT4 client, PCSTR args ) +{ + return S_OK; +} + //////////////////////////////////////////////////////////////////////////////// -// -//BOOST_PYTHON_FUNCTION_OVERLOADS( dprint, dbgPrint::dprint, 1, 2 ) -//BOOST_PYTHON_FUNCTION_OVERLOADS( dprintln, dbgPrint::dprintln, 1, 2 ) -// -//BOOST_PYTHON_FUNCTION_OVERLOADS( loadCharsOv, loadChars, 2, 3 ) -//BOOST_PYTHON_FUNCTION_OVERLOADS( loadWCharsOv, loadWChars, 2, 3 ) -//BOOST_PYTHON_FUNCTION_OVERLOADS( loadBytes, loadArray, 2, 3 ) -//BOOST_PYTHON_FUNCTION_OVERLOADS( loadWords, loadArray, 2, 3 ) -//BOOST_PYTHON_FUNCTION_OVERLOADS( loadDWords, loadArray, 2, 3 ) -//BOOST_PYTHON_FUNCTION_OVERLOADS( loadQWords, loadArray , 2, 3 ) -//BOOST_PYTHON_FUNCTION_OVERLOADS( loadSignBytes, loadArray , 2, 3 ) -//BOOST_PYTHON_FUNCTION_OVERLOADS( loadSignWords, loadArray , 2, 3 ) -//BOOST_PYTHON_FUNCTION_OVERLOADS( loadSignDWords, loadArray , 2, 3 ) -//BOOST_PYTHON_FUNCTION_OVERLOADS( loadSignQWords, loadArray<__int64>, 2, 3 ) -// -//BOOST_PYTHON_FUNCTION_OVERLOADS( compareMemoryOver, compareMemory, 3, 4 ) -// -//BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( appendOver, TypeInfo::appendField, 2, 3 ) -//BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( loadOver, TypeInfo::loadVar, 1, 2 ) -// -// -//#define DEF_PY_CONST(x) \ -// boost::python::scope().attr(#x) = ##x -// -//#define DEF_PY_GLOBAL(x,y) \ -// boost::python::scope().attr(x) = ##y -// -// -//BOOST_PYTHON_MODULE( pykd ) -//{ -// boost::python::def( "go", &setExecutionStatus, -// "Change debugger status to DEBUG_STATUS_GO" ); -// boost::python::def( "trace", &setExecutionStatus, -// "Change debugger status to DEBUG_STATUS_STEP_INTO" ); -// boost::python::def( "step", &setExecutionStatus, -// "Change debugger status to DEBUG_STATUS_STEP_OVER" ); -// boost::python::def( "breakin", &breakin, -// "Break into debugger" ); -// boost::python::def( "expr", &evaluate, -// "Evaluate windbg expression" ); -// boost::python::def( "isWindbgExt", &isWindbgExt, -// "Check if script works in windbg context" ); -// boost::python::def( "symbolsPath", &dbgSymPath, -// "Return symbol path" ); -// boost::python::def( "dprint", &dbgPrint::dprint, dprint( boost::python::args( "str", "dml" ), -// "Print out string. If dml = True string is printed with dml highlighting ( only for windbg )") ); -// boost::python::def( "dprintln", &dbgPrint::dprintln, dprintln( boost::python::args( "str", "dml" ), -// "Print out string and insert end of line symbol. If dml = True string is printed with dml highlighting ( only for windbg )" ) ); -// boost::python::def( "loadDump", &dbgLoadDump, -// "Load crash dump (only for console)"); -// boost::python::def( "startProcess", &startProcess, -// "Start process for debugging (only for console)"); -// boost::python::def( "attachProcess", &attachProcess, -// "Attach debugger to a exsisting process" ); -// boost::python::def( "attachKernel", &attachKernel, -// "Attach debugger to a kernel target" ); -// boost::python::def( "dbgCommand", &dbgCommand, -// "Execute debugger command. For example: dbgCommand( \"lmvm nt\" )" ); -// boost::python::def( "isValid", &isOffsetValid, -// "Check if virtual address is valid" ); -// boost::python::def( "is64bitSystem", &is64bitSystem, -// "Check if target system has 64 address space" ); -// boost::python::def( "isKernelDebugging", &isKernelDebugging, -// "Check if kernel dubugging is running" ); -// boost::python::def( "isDumpAnalyzing", &isDumpAnalyzing, -// "Check if it is a dump analyzing ( not living debuggee )" ); -// boost::python::def( "ptrSize", ptrSize, -// "Return pointer size ( in bytes )" ); -// boost::python::def( "reg", &loadRegister, -// "Return CPU's register value" ); -// boost::python::def( "rdmsr", &loadMSR, -// "Return MSR value" ); -// boost::python::def( "wrmsr", &setMSR, -// "Set MSR value" ); -// boost::python::def( "typedVarList", &loadTypedVarList, -// "Return list of typedVarClass instances. Each item represents one item of the linked list in the target memory" ); -// boost::python::def( "typedVarArray", &loadTypedVarArray, -// "Return list of typedVarClass instances. Each item represents one item of the counted array the target memory" ); -// boost::python::def( "containingRecord", &containingRecord, -// "Return instance of the typedVarClass. It's value are loaded from the target memory." -// "The start address is calculated by the same method as standard macro CONTAINING_RECORD" ); -// boost::python::def( "sizeof", &sizeofType, -// "Return size of type" ); -// boost::python::def( "loadModule", &loadModule, -// "Return instance of the dbgModuleClass" ); -// boost::python::def( "findSymbol", &findSymbolForAddress, -// "Return symbol for specified target address if it exists" ); -// boost::python::def( "getOffset", &findAddressForSymbol, -// "Return target address for specified symbol" ); -// boost::python::def( "findModule", &findModule, -// "Return instance of the dbgModuleClass which posseses specified address" ); -// boost::python::def( "addr64", &addr64, -// "Extend address to 64 bits formats ( for x86 )" ); -// boost::python::def( "loadChars", loadChars, loadCharsOv( boost::python::args( "address", "number", "phyAddr" ), -// "Load string from the target buffer" ) ); -// boost::python::def( "loadWChars", loadWChars, loadWCharsOv( boost::python::args( "address", "number", "phyAddr" ), -// "Load unicode string from the target buffer" ) ); -// boost::python::def( "loadBytes", &loadArray, loadBytes( boost::python::args( "address", "number", "phyAddr" ), -// "Return list of unsigned bytes" ) ); -// boost::python::def( "loadWords", &loadArray, loadWords( boost::python::args( "address", "number", "phyAddr" ), -// "Return list of unsigned words (2-bytes )" ) ); -// boost::python::def( "loadDWords", &loadArray, loadDWords( boost::python::args( "address", "number", "phyAddr" ), -// "Return list of unsigned dwords (4-bytes)" ) ); -// boost::python::def( "loadQWords", &loadArray, loadQWords( boost::python::args( "address", "number", "phyAddr" ), -// "Return list of unsigned qwords (8-butes)" ) ); -// boost::python::def( "loadSignBytes", &loadArray, loadSignBytes( boost::python::args( "address", "number", "phyAddr" ), -// "Return list of signed bytes" ) ); -// boost::python::def( "loadSignWords", &loadArray, loadSignWords( boost::python::args( "address", "number", "phyAddr" ), -// "Return list of signed words (2-bytes)" ) ); -// boost::python::def( "loadSignDWords", &loadArray, loadSignDWords( boost::python::args( "address", "number", "phyAddr" ), -// "Return list of signed dwords (4-bytes)" ) ); -// boost::python::def( "loadSignQWords", &loadArray<__int64>, loadSignQWords( boost::python::args( "address", "number", "phyAddr" ), -// "Return list of signed qwords (8-bytes)" ) ); -// boost::python::def( "loadPtrs", &loadPtrArray, -// "Return list of pointers" ); -// boost::python::def( "loadUnicodeString", &loadUnicodeStr, -// "Return string represention of windows UNICODE_STRING type" ); -// boost::python::def( "loadAnsiString", &loadAnsiStr, -// "Return string represention of windows ANSU_STRING type" ); -// boost::python::def( "loadCStr", &loadCStr, -// "Load string from the target buffer containing 0-terminated ansi-string" ); -// boost::python::def( "loadWStr", &loadWStr, -// "Load string from the target buffer containing 0-terminated unicode-string" ); -// boost::python::def( "loadLinkedList", &loadLinkedList, -// "Return list of instances of the typedVarClass loaded from linked list in the target memory" ); -// boost::python::def( "ptrByte", &loadByPtr, -// "Return 1-byte unsigned value loaded by pointer" ); -// boost::python::def( "ptrSignByte", &loadByPtr, -// "Return 1-byte signed value loaded by pointer" ); -// boost::python::def( "ptrWord", &loadByPtr, -// "Return 2-byte unsigned value loaded by pointer" ); -// boost::python::def( "ptrSignWord", &loadByPtr, -// "Return 2-byte signed value loaded by pointer" ); -// boost::python::def( "ptrDWord", &loadByPtr, -// "Return 4-byte unsigned value loaded by pointer" ); -// boost::python::def( "ptrSignDWord", &loadByPtr, -// "Return 4-byte signed value loaded by pointer" ); -// boost::python::def( "ptrQWord", &loadByPtr, -// "Return 8-byte unsigned value loaded by pointer" ); -// boost::python::def( "ptrSignQWord", &loadByPtr<__int64>, -// "Return 8-byte signed value loaded by pointer" ); -// boost::python::def( "ptrPtr", &loadPtrByPtr, -// "Return pointer value loaded by pointer" ); -// boost::python::def( "ptrMWord", &loadMWord, -// "Return unsigned machine word ( 4-bytes for x86 and 8-bytes for x64 ) loaded by pointer" ); -// boost::python::def( "ptrSignMWord", &loadSignMWord, -// "Return signed machine word ( 4-bytes for x86 and 8-bytes for x64 ) loaded by pointer" ); -// boost::python::def( "compareMemory", &compareMemory, compareMemoryOver( boost::python::args( "addr1", "addr2", "length", "phyAddr" ), -// "Compare two memory buffers by virtual or physical addresses" ) ); -// boost::python::def( "getCurrentStack", &getCurrentStack, -// "Return list of dbgStackFrameClass for current stack" ); -// boost::python::def( "locals", &getLocals, -// "Return dict of locals variables (each item is typedVarClass)" ); -// boost::python::def( "reloadModule", &reloadModule, -// "Reload symbols by module name" ); -// boost::python::def( "getPdbFile", &getPdbFile, -// "Return full path to PDB (Program DataBase, debug information) file" ); -// boost::python::def( "getImplicitThread", &getImplicitThread, -// "Return implicit thread for current process" ); -// boost::python::def( "setImplicitThread", &setImplicitThread, -// "Set implicit thread for current process" ); -// boost::python::def( "getThreadList", &getThreadList, -// "Return list of threads (each item is numeric address of thread)" ); -// boost::python::def( "getCurrentProcess", &getCurrentProcess, -// "Return current process (numeric address)" ); -// boost::python::def( "setCurrentProcess", &setCurrentProcess, -// "Set current process by address" ); -// boost::python::def( "getProcessorMode", &getProcessorMode, -// "Return current processor mode as string: X86, ARM, IA64 or X64" ); -// boost::python::def( "setProcessorMode", &setProcessorMode, -// "Set current processor mode by string (X86, ARM, IA64 or X64)" ); -// boost::python::def( "addSynSymbol", &addSyntheticSymbol, -// "Add new synthetic symbol for virtual address" ); -// boost::python::def( "delAllSynSymbols", &delAllSyntheticSymbols, -// "Delete all synthetic symbol for all modules"); -// boost::python::def( "delSynSymbol", &delSyntheticSymbol, -// "Delete synthetic symbols by virtual address" ); -// boost::python::def( "delSynSymbolsMask", &delSyntheticSymbolsMask, -// "Delete synthetic symbols by mask of module and symbol name"); -// -// -// boost::python::class_( "typeInfo", -// "Class representing non-primitive type info: structure, union, etc. attributes is a fields of non-primitive type" ) -// .def(boost::python::init( boost::python::args("module", "type"), "constructor" ) ) -// .def(boost::python::init( boost::python::args("typeName"), "constructor" ) ) -// .def(boost::python::init( boost::python::args("typeName", "align"), "constructor" ) ) -// .def("size", &TypeInfo::size, -// "Return full size of non-primitive type" ) -// .def("name", &TypeInfo::name, -// "Return type's name" ) -// .def("__str__", &TypeInfo::print, -// "Return a nice string represention: print names and offsets of fields" ) -// .def("__getattr__", &TypeInfo::getField ) -// .def("__len__", &TypeInfo::getFieldCount ) -// .def("__getitem__", &TypeInfo::getFieldByIndex ) -// .def("append", &TypeInfo::appendField, appendOver( boost::python::args("type", "fieldName", "count"), -// "add new field for typeInfo" ) ) -// .def("offset", &TypeInfo::getFieldOffset, -// "Return offset while type is part of the more complex type" ) -// .def("setAlignReq", &TypeInfo::setAlignReq, -// "Set alignment requirement" ) -// .def("load", &TypeInfo::loadVar, loadOver( boost::python::args( "offset", "count"), -// "Create instance of the typedVar class with this typeInfo" ) ); -// -// DEF_PY_GLOBAL( "char_t", TypeInfo("", "char") ); -// DEF_PY_GLOBAL( "uchar_t", TypeInfo("", "unsigned char") ); -// DEF_PY_GLOBAL( "short_t", TypeInfo("", "short") ); -// DEF_PY_GLOBAL( "ushort_t", TypeInfo("", "unsigned short") ); -// DEF_PY_GLOBAL( "long_t", TypeInfo("", "long") ); -// DEF_PY_GLOBAL( "ulong_t", TypeInfo("", "unsigned long") ); -// DEF_PY_GLOBAL( "int_t", TypeInfo("", "int") ); -// DEF_PY_GLOBAL( "uint_t", TypeInfo("", "unsigned int") ); -// DEF_PY_GLOBAL( "ptr_t", TypeInfo("", "void*") ); -// DEF_PY_GLOBAL( "double_t", TypeInfo("", "double") ); -// DEF_PY_GLOBAL( "longlong_t", TypeInfo("", "int64") ); -// DEF_PY_GLOBAL( "ulonglong_t", TypeInfo("", "unsigned int64") ); -// -// boost::python::class_( "typedVar", -// "Class of non-primitive type object, child class of typeClass. Data from target is copied into object instance" ) -// .def(boost::python::init(boost::python::args("typeInfo", "address"), -// "constructor" ) ) -// .def(boost::python::init(boost::python::args("moduleName", "typeName", "address"), -// "constructor" ) ) -// .def(boost::python::init(boost::python::args("address"), -// "constructor" ) ) -// .def(boost::python::init(boost::python::args("symbolName"), -// "constructor" ) ) -// .def("getAddress", &TypedVar::getAddress, -// "Return virtual address" ) -// .def("sizeof", &TypedVar::getSize, -// "Return size of a variable in the target memory" ) -// .def("data", &TypedVar::data, -// "Return raw string object with data stream" ) -// .def("__getattr__", &TypedVar::getFieldWrap, -// "Return field of structure as an object attribute" ) -// .def("__str__", &TypedVar::print, -// "Return a nice string represention: print names and offsets of fields" ); -// -// boost::python::class_( "dbgModuleClass", -// "Class representing module in the target memory" ) -// .def("begin", &dbgModuleClass::getBegin, -// "Return start address of the module" ) -// .def("end", &dbgModuleClass::getEnd, -// "Return end address of the module" ) -// .def("size", &dbgModuleClass::getSize, -// "Return size of the module" ) -// .def("name", &dbgModuleClass::getName, -// "Return name of the module" ) -// .def("contain", &dbgModuleClass::contain, -// "Check if the address belongs to the module") -// .def("image", &dbgModuleClass::getImageSymbolName, -// "Return the full path to the module's image file" ) -// .def("pdb", &dbgModuleClass::getPdbName, -// "Return the full path to the module's pdb file ( symbol information )" ) -// .def("checksum", &dbgModuleClass::getCheckSum, -// "Return checksum of the module ( from PE header )" ) -// .def("timestamp", &dbgModuleClass::getTimeStamp, -// "Return timestamp of the module ( from PE header )" ) -// .def("addSynSymbol", &dbgModuleClass::addSyntheticSymbol, -// "Add synthetic symbol for the module" ) -// .def("delAllSynSymbols", &dbgModuleClass::delAllSyntheticSymbols, -// "Remove all synthetic symbols for the module" ) -// .def("delSynSymbol", &dbgModuleClass::delSyntheticSymbol, -// "Remove specified synthetic symbol for the module" ) -// .def("delSynSymbolsMask", &dbgModuleClass::delSyntheticSymbolsMask ) -// .def("__getattr__", &dbgModuleClass::getOffset, -// "Return address of the symbol" ) -// .def("__str__", &dbgModuleClass::print, -// "Return a nice string represention of the dbgModuleClass" ); -// -// boost::python::class_( -// "ext", -// "windbg extension wrapper", -// boost::python::init( boost::python::args("path"), "__init__ dbgExtensionClass" ) ) -// .def("call", &dbgExtensionClass::call, -// "Call extension command" ) -// .def("__str__", &dbgExtensionClass::print, -// "Return a nice string represention of the dbgExtensionClass" ); -// -// boost::python::class_( "dbgStackFrameClass", -// "Class representing a frame of the call satck" ) -// .def_readonly( "instructionOffset", &dbgStackFrameClass::InstructionOffset, -// "Return a frame's instruction offset" ) -// .def_readonly( "returnOffset", &dbgStackFrameClass::ReturnOffset, -// "Return a frame's return offset" ) -// .def_readonly( "frameOffset", &dbgStackFrameClass::FrameOffset, -// "Return a frame's offset" ) -// .def_readonly( "stackOffset", &dbgStackFrameClass::StackOffset, -// "Return a frame's stack offset" ) -// .def_readonly( "frameNumber", &dbgStackFrameClass::FrameNumber, -// "Return a frame's number" ) -// .def( "__str__", &dbgStackFrameClass::print, -// "Return a nice string represention of the dbgStackFrameClass" ); -// -// boost::python::class_( "windbgOut", "windbgOut" ) -// .def( "write", &dbgOut::write ); -// -// boost::python::class_( "windbgIn", "windbgIn" ) -// .def( "readline", &dbgIn::readline ); -// -// boost::python::class_( "bp", -// "Class representing breakpoint", -// boost::python::init( boost::python::args("offset", "callback"), -// "Break point: user callback" ) ) -// .def( boost::python::init< ULONG64 >( boost::python::args("offset"), -// "Break point constructor: always break" ) ) -// .def( "set", &dbgBreakpointClass::set, -// "Set a breakpoint at the specified address" ) -// .def( "remove", &dbgBreakpointClass::remove, -// "Remove a breakpoint set before" ) -// .def( "__str__", &dbgBreakpointClass::print, -// "Return a nice string represention of the breakpoint class" ); -// -// boost::python::class_( "debugEvent", -// "Base class for debug events handlers" ) -// .def( "onBreakpoint", &debugEventWrap::onBreakpoint, -// "Triggered breakpoint event. Parameter is dict:\n" -// "{\"Id\":int, \"BreakType\":int, \"ProcType\":int, \"Flags\":int, \"Offset\":int," -// " \"Size\":int, \"AccessType\":int, \"PassCount\":int, \"CurrentPassCount\":int," -// " \"MatchThreadId\":int, \"Command\":str, \"OffsetExpression\":str}\n" -// "Detailed information: http://msdn.microsoft.com/en-us/library/ff539284(VS.85).aspx \n" -// "For ignore event method must return DEBUG_STATUS_NO_CHANGE value" ) -// .def( "onException", &debugEventWrap::onException, -// "Exception event. Parameter is dict:\n" -// "{\"Code\":int, \"Flags\":int, \"Record\":int, \"Address\":int," -// " \"Parameters\":[int], \"FirstChance\":bool}\n" -// "Detailed information: http://msdn.microsoft.com/en-us/library/aa363082(VS.85).aspx \n" -// "For ignore event method must return DEBUG_STATUS_NO_CHANGE value" ) -// .def( "onLoadModule", &debugEventWrap::onLoadModule, -// "Load module event. Parameter is instance of dbgModuleClass.\n" -// "For ignore event method must return DEBUG_STATUS_NO_CHANGE value" ) -// .def( "onUnloadModule", &debugEventWrap::onUnloadModule, -// "Unload module event. Parameter is instance of dbgModuleClass.\n" -// "For ignore event method must return DEBUG_STATUS_NO_CHANGE value" ); -// -// boost::python::class_("disasm", "Class disassemble a processor instructions", boost::python::no_init ) -// .def( boost::python::init<>( "constructor" ) ) -// .def( boost::python::init( boost::python::args("offset"), "constructor" ) ) -// .def( "next", &disasm::next, "Disassemble next instruction" ) -// .def( "begin", &disasm::begin, "Return begin offset" ) -// .def( "current", &disasm::current, "Return current offset" ) -// .def( "length", &disasm::length, "Return current instruction length" ) -// .def( "instruction", &disasm::instruction, "Returm current disassembled instruction" ) -// .def( "ea", &disasm::ea, "Return effective address for last disassembled instruction or 0" ); -// -// -// // исключения -// -// boost::python::class_ > waitExceptionClass( "WaitEventException", -// "Type exception class", -// boost::python::no_init ); -// -// boost::python::class_ > typeExceptionClass( "TypeException", -// "Type exception class", -// boost::python::no_init ); -// -// boost::python::class_ > memoryExceptionClass( "MemoryException", -// "Memory exception class", -// boost::python::no_init ); -// -// memoryExceptionClass -// .def( boost::python::init( boost::python::args("targetAddress"), "constructor" ) ) -// .def( "getAddress", &MemoryException::getAddress, -// "Return target address" ); -// -// eventExceptionType = waitExceptionClass.ptr(); -// typeExceptionType = typeExceptionClass.ptr(); -// memoryExceptionType = memoryExceptionClass.ptr(); -// -// boost::python::register_exception_translator( &DbgException::exceptionTranslate ); -// boost::python::register_exception_translator( &WaitEventException::exceptionTranslate ); -// boost::python::register_exception_translator( &TypeException::exceptionTranslate ); -// boost::python::register_exception_translator( &IndexException::translate); -// boost::python::register_exception_translator( &MemoryException::translate ); -// -// boost::python::class_( -// "intBase", -// "intBase") -// .def( boost::python::init<>() ) -// .def( boost::python::init( boost::python::args("value"), "constructor" ) ) -// -// .def( "value", &intBase::value ) -// .def( int_( boost::python::self ) ) -// //.def( boost::python::self = long() ) -// -// .def( boost::python::self + long() ) -// .def( long() + boost::python::self ) -// .def( boost::python::self += long() ) -// .def( boost::python::self + boost::python::self ) -// .def( boost::python::self += boost::python::self ) -// -// .def( boost::python::self - long() ) -// .def( long() - boost::python::self ) -// .def( boost::python::self -= long() ) -// .def( boost::python::self - boost::python::self ) -// .def( boost::python::self -= boost::python::self ) -// -// .def( boost::python::self * long() ) -// .def( long() * boost::python::self ) -// .def( boost::python::self *= long() ) -// .def( boost::python::self * boost::python::self ) -// .def( boost::python::self *= boost::python::self ) -// -// .def( boost::python::self / long() ) -// .def( long() / boost::python::self ) -// .def( boost::python::self /= long() ) -// .def( boost::python::self / boost::python::self ) -// .def( boost::python::self /= boost::python::self ) -// -// .def( boost::python::self % long() ) -// .def( long() % boost::python::self ) -// .def( boost::python::self %= long() ) -// .def( boost::python::self % boost::python::self ) -// .def( boost::python::self %= boost::python::self ) -// -// .def( boost::python::self & long() ) -// .def( long() & boost::python::self ) -// .def( boost::python::self &= long() ) -// .def( boost::python::self & boost::python::self ) -// .def( boost::python::self &= boost::python::self ) -// -// .def( boost::python::self | long() ) -// .def( long() | boost::python::self ) -// .def( boost::python::self |= long() ) -// .def( boost::python::self | boost::python::self ) -// .def( boost::python::self |= boost::python::self ) -// -// .def( boost::python::self ^ long() ) -// .def( long() ^ boost::python::self ) -// .def( boost::python::self ^= long() ) -// .def( boost::python::self ^ boost::python::self ) -// .def( boost::python::self ^= boost::python::self ) -// -// .def( boost::python::self << long() ) -// .def( boost::python::self <<= long() ) -// -// .def( boost::python::self >> long() ) -// .def( boost::python::self >>= long() ) -// -// .def( boost::python::self < long() ) -// .def( boost::python::self < boost::python::self ) -// -// .def( boost::python::self <= long() ) -// .def( boost::python::self <= boost::python::self ) -// -// .def( boost::python::self == long() ) -// .def( boost::python::self == boost::python::self ) -// -// .def( boost::python::self >= long() ) -// .def( boost::python::self >= boost::python::self ) -// -// .def( boost::python::self > long() ) -// .def( boost::python::self > boost::python::self ) -// -// .def( boost::python::self != long() ) -// .def( boost::python::self != boost::python::self ) -// -// .def( ~boost::python::self ) -// .def( !boost::python::self ) -// -// .def( "__str__", &intBase::str ) -// .def( "__hex__", &intBase::hex ); -// -// boost::python::class_ >( -// "cpuReg", -// "CPU regsiter class", -// boost::python::no_init ) -// .def( boost::python::init(boost::python::args("name"), "constructor" ) ) -// .def( boost::python::init(boost::python::args("index"), "constructor" ) ) -// .def( "name", &cpuReg::name, "The name of the regsiter" ) -// .def( "index", &cpuReg::index, "The index of thr register" ) -// .def( "beLive", &cpuReg::beLive, "Turn the object to live: its value will be following the target register value" ); -// -// -// // debug status -// DEF_PY_CONST(DEBUG_STATUS_NO_CHANGE); -// DEF_PY_CONST(DEBUG_STATUS_GO); -// DEF_PY_CONST(DEBUG_STATUS_GO_HANDLED); -// DEF_PY_CONST(DEBUG_STATUS_GO_NOT_HANDLED); -// DEF_PY_CONST(DEBUG_STATUS_STEP_OVER); -// DEF_PY_CONST(DEBUG_STATUS_STEP_INTO); -// DEF_PY_CONST(DEBUG_STATUS_BREAK); -// DEF_PY_CONST(DEBUG_STATUS_NO_DEBUGGEE); -// DEF_PY_CONST(DEBUG_STATUS_STEP_BRANCH); -// DEF_PY_CONST(DEBUG_STATUS_IGNORE_EVENT); -// DEF_PY_CONST(DEBUG_STATUS_RESTART_REQUESTED); -// DEF_PY_CONST(DEBUG_STATUS_REVERSE_GO); -// DEF_PY_CONST(DEBUG_STATUS_REVERSE_STEP_BRANCH); -// DEF_PY_CONST(DEBUG_STATUS_REVERSE_STEP_OVER); -// DEF_PY_CONST(DEBUG_STATUS_REVERSE_STEP_INTO); -// -// // debug status additional mask -// DEF_PY_CONST(DEBUG_STATUS_INSIDE_WAIT); -// DEF_PY_CONST(DEBUG_STATUS_WAIT_TIMEOUT); -// -// // break point type -// DEF_PY_CONST(DEBUG_BREAKPOINT_CODE); -// DEF_PY_CONST(DEBUG_BREAKPOINT_DATA); -// DEF_PY_CONST(DEBUG_BREAKPOINT_TIME); -// -// // break point flag -// DEF_PY_CONST(DEBUG_BREAKPOINT_GO_ONLY); -// DEF_PY_CONST(DEBUG_BREAKPOINT_DEFERRED); -// DEF_PY_CONST(DEBUG_BREAKPOINT_ENABLED); -// DEF_PY_CONST(DEBUG_BREAKPOINT_ADDER_ONLY); -// DEF_PY_CONST(DEBUG_BREAKPOINT_ONE_SHOT); -// -// // break point access type -// DEF_PY_CONST(DEBUG_BREAK_READ); -// DEF_PY_CONST(DEBUG_BREAK_WRITE); -// DEF_PY_CONST(DEBUG_BREAK_EXECUTE); -// DEF_PY_CONST(DEBUG_BREAK_IO); -// -// // exception flags -// DEF_PY_CONST(EXCEPTION_NONCONTINUABLE); -// -// // debug events -// DEF_PY_CONST(DEBUG_EVENT_BREAKPOINT); -// DEF_PY_CONST(DEBUG_EVENT_EXCEPTION); -// DEF_PY_CONST(DEBUG_EVENT_CREATE_THREAD); -// DEF_PY_CONST(DEBUG_EVENT_EXIT_THREAD); -// DEF_PY_CONST(DEBUG_EVENT_CREATE_PROCESS); -// DEF_PY_CONST(DEBUG_EVENT_EXIT_PROCESS); -// DEF_PY_CONST(DEBUG_EVENT_LOAD_MODULE); -// DEF_PY_CONST(DEBUG_EVENT_UNLOAD_MODULE); -// DEF_PY_CONST(DEBUG_EVENT_SYSTEM_ERROR); -// DEF_PY_CONST(DEBUG_EVENT_SESSION_STATUS); -// DEF_PY_CONST(DEBUG_EVENT_CHANGE_DEBUGGEE_STATE); -// DEF_PY_CONST(DEBUG_EVENT_CHANGE_ENGINE_STATE); -// DEF_PY_CONST(DEBUG_EVENT_CHANGE_SYMBOL_STATE); -// -// // debugger type -// //_DEF_PY_CONST(DEBUG_CLASS_UNINITIALIZED); -// //_DEF_PY_CONST(DEBUG_CLASS_KERNEL); -// //_DEF_PY_CONST(DEBUG_CLASS_USER_WINDOWS); -// //_DEF_PY_CONST(DEBUG_CLASS_IMAGE_FILE); -// // -// //_DEF_PY_CONST(DEBUG_KERNEL_CONNECTION); -// //_DEF_PY_CONST(DEBUG_KERNEL_LOCAL); -// //_DEF_PY_CONST(DEBUG_KERNEL_EXDI_DRIVER); -// //_DEF_PY_CONST(DEBUG_KERNEL_IDNA); -// //_DEF_PY_CONST(DEBUG_KERNEL_SMALL_DUMP); -// //_DEF_PY_CONST(DEBUG_KERNEL_DUMP); -// //_DEF_PY_CONST(DEBUG_KERNEL_FULL_DUMP); -// -// //_DEF_PY_CONST(DEBUG_USER_WINDOWS_PROCESS); -// //_DEF_PY_CONST(DEBUG_USER_WINDOWS_PROCESS_SERVER); -// //_DEF_PY_CONST(DEBUG_USER_WINDOWS_IDNA); -// //_DEF_PY_CONST(DEBUG_USER_WINDOWS_SMALL_DUMP); -// //_DEF_PY_CONST(DEBUG_USER_WINDOWS_SMALL_DUMP); -// //_DEF_PY_CONST(DEBUG_USER_WINDOWS_DUMP); -// //_DEF_PY_CONST(DEBUG_USER_WINDOWS_DUMP_WINDOWS_CE); -//} -// -//#undef _DEF_PY_CONST -// -/////////////////////////////////////////////////////////////////////////////////// -// -//class WindbgGlobalSession -//{ -//public: -// -// static -// boost::python::object -// global() { -// return windbgGlobalSession->main.attr("__dict__"); -// } -// -// static -// VOID -// StartWindbgSession() { -// if ( 1 == InterlockedIncrement( &sessionCount ) ) -// { -// windbgGlobalSession = new WindbgGlobalSession(); -// } -// } -// -// static -// VOID -// StopWindbgSession() { -// if ( 0 == InterlockedDecrement( &sessionCount ) ) -// { -// delete windbgGlobalSession; -// windbgGlobalSession = NULL; -// } -// } -// -// static -// bool isInit() { -// return windbgGlobalSession != NULL; -// } -// -// -//private: -// -// WindbgGlobalSession() { -// -// PyImport_AppendInittab("pykd", initpykd ); -// -// Py_Initialize(); -// -// main = boost::python::import("__main__"); -// -// boost::python::object main_namespace = main.attr("__dict__"); -// -// -// // делаем аналог from pykd import * -// boost::python::object pykd = boost::python::import( "pykd" ); -// -// boost::python::dict pykd_namespace( pykd.attr("__dict__") ); -// -// boost::python::list iterkeys( pykd_namespace.iterkeys() ); -// -// for (int i = 0; i < boost::python::len(iterkeys); i++) -// { -// std::string key = boost::python::extract(iterkeys[i]); -// -// main_namespace[ key ] = pykd_namespace[ key ]; -// } -// -// //// перенаправление стандартных потоков ВВ -// //boost::python::object sys = boost::python::import( "sys"); -// // -// //dbgOut dout; -// //sys.attr("stdout") = boost::python::object( dout ); -// -// //dbgIn din; -// //sys.attr("stdin") = boost::python::object( din ); -// // -// g_dbgClient.startEventsMgr(); -// } -// -// ~WindbgGlobalSession() { -// Py_Finalize(); -// g_dbgClient.removeEventsMgr(); -// } -// -// boost::python::object main; -// -// static volatile LONG sessionCount; -// -// static WindbgGlobalSession *windbgGlobalSession; -//}; -// -//volatile LONG WindbgGlobalSession::sessionCount = 0; -// -//WindbgGlobalSession *WindbgGlobalSession::windbgGlobalSession = NULL; -// -//bool isWindbgExt() { -// return WindbgGlobalSession::isInit(); -//} -// -/////////////////////////////////////////////////////////////////////////////////// -// -//HRESULT -//CALLBACK -//DebugExtensionInitialize( -// OUT PULONG Version, -// OUT PULONG Flags ) -//{ -// *Version = DEBUG_EXTENSION_VERSION( 1, 0 ); -// *Flags = 0; -// -// WindbgGlobalSession::StartWindbgSession(); -// -// return S_OK; -//} -// -// -//VOID -//CALLBACK -//DebugExtensionUninitialize() -//{ -// WindbgGlobalSession::StopWindbgSession(); -//} -// -//DbgExt::DbgExt( IDebugClient4 *masterClient ) -//{ -// client = NULL; -// masterClient->QueryInterface( __uuidof(IDebugClient), (void **)&client ); -// -// client4 = NULL; -// masterClient->QueryInterface( __uuidof(IDebugClient4), (void **)&client4 ); -// -// client5 = NULL; -// masterClient->QueryInterface( __uuidof(IDebugClient5), (void **)&client5 ); -// -// control = NULL; -// masterClient->QueryInterface( __uuidof(IDebugControl), (void **)&control ); -// -// control4 = NULL; -// masterClient->QueryInterface( __uuidof(IDebugControl4), (void **)&control4 ); -// -// registers = NULL; -// masterClient->QueryInterface( __uuidof(IDebugRegisters), (void **)®isters ); -// -// symbols = NULL; -// masterClient->QueryInterface( __uuidof(IDebugSymbols), (void ** )&symbols ); -// -// symbols2 = NULL; -// masterClient->QueryInterface( __uuidof(IDebugSymbols2), (void ** )&symbols2 ); -// -// symbols3 = NULL; -// masterClient->QueryInterface( __uuidof(IDebugSymbols3), (void ** )&symbols3 ); -// -// dataSpaces = NULL; -// masterClient->QueryInterface( __uuidof(IDebugDataSpaces), (void **)&dataSpaces ); -// -// dataSpaces4 = NULL; -// masterClient->QueryInterface( __uuidof(IDebugDataSpaces4), (void **)&dataSpaces4 ); -// -// advanced2 = NULL; -// masterClient->QueryInterface( __uuidof(IDebugAdvanced2), (void **)&advanced2 ); -// -// system = NULL; -// masterClient->QueryInterface( __uuidof(IDebugSystemObjects), (void**)&system ); -// -// system2 = NULL; -// masterClient->QueryInterface( __uuidof(IDebugSystemObjects2), (void**)&system2 ); -// -// m_previosExt = dbgExt; -// dbgExt = this; -//} -// -//DbgExt::~DbgExt() -//{ -// BOOST_ASSERT(dbgExt == this); -// dbgExt = m_previosExt; -// -// if ( client ) -// client->Release(); -// -// if ( client4 ) -// client4->Release(); -// -// if ( client5 ) -// client5->Release(); -// -// if ( control ) -// control->Release(); -// -// if ( control4 ) -// control4->Release(); -// -// if ( registers ) -// registers->Release(); -// -// if ( symbols ) -// symbols->Release(); -// -// if ( symbols2 ) -// symbols2->Release(); -// -// if ( symbols3 ) -// symbols3->Release(); -// -// if ( dataSpaces ) -// dataSpaces->Release(); -// -// if ( dataSpaces4 ) -// dataSpaces4->Release(); -// -// if ( advanced2 ) -// advanced2->Release(); -// -// if ( system ) -// system->Release(); -// -// if ( system2 ) -// system2->Release(); -//} -// -/////////////////////////////////////////////////////////////////////////////////// -// -//HRESULT -//CALLBACK -//py( PDEBUG_CLIENT4 client, PCSTR args) -//{ -// DbgExt ext( client ); -// -// PyThreadState *globalInterpreter = PyThreadState_Swap( NULL ); -// PyThreadState *localInterpreter = Py_NewInterpreter(); -// -// try { -// -// boost::python::import( "pykd" ); -// -// boost::python::object main = boost::python::import("__main__"); -// -// boost::python::object global(main.attr("__dict__")); -// -// // перенаправление стандартных потоков ВВ -// boost::python::object sys = boost::python::import("sys"); -// -// boost::python::object tracebackModule = boost::python::import("traceback"); -// -// dbgOut dout; -// sys.attr("stdout") = boost::python::object( dout ); -// -// dbgIn din; -// sys.attr("stdin") = boost::python::object( din ); -// -// // разбор параметров -// typedef boost::escaped_list_separator char_separator_t; -// typedef boost::tokenizer< char_separator_t > char_tokenizer_t; -// -// std::string argsStr( args ); -// -// char_tokenizer_t token( argsStr , char_separator_t( "", " \t", "\"" ) ); -// std::vector argsList; -// -// for ( char_tokenizer_t::iterator it = token.begin(); it != token.end(); ++it ) -// { -// if ( *it != "" ) -// argsList.push_back( *it ); -// } -// -// if ( argsList.size() == 0 ) -// return S_OK; -// -// char **pythonArgs = new char* [ argsList.size() ]; -// -// for ( size_t i = 0; i < argsList.size(); ++i ) -// pythonArgs[i] = const_cast( argsList[i].c_str() ); -// -// PySys_SetArgv( (int)argsList.size(), pythonArgs ); -// -// delete[] pythonArgs; -// -// -// // найти путь к файлу -// std::string fullFileName; -// std::string filePath; -// DbgPythonPath dbgPythonPath; -// -// -// if ( dbgPythonPath.findPath( argsList[0], fullFileName, filePath ) ) -// { -// try { -// -// boost::python::object result; -// -// result = boost::python::exec_file( fullFileName.c_str(), global, global ); -// } -// catch( boost::python::error_already_set const & ) -// { -// // ошибка в скрипте -// PyObject *errtype = NULL, *errvalue = NULL, *traceback = NULL; -// -// PyErr_Fetch( &errtype, &errvalue, &traceback ); -// -// if(errvalue != NULL) -// { -// PyObject *errvalueStr= PyObject_Str(errvalue); -// -// dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "%s\n", PyString_AS_STRING( errvalueStr ) ); -// -// if ( traceback ) -// { -// boost::python::object traceObj( boost::python::handle<>( boost::python::borrowed( traceback ) ) ); -// -// dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "\nTraceback:\n" ); -// -// boost::python::object pFunc( tracebackModule.attr("format_tb") ); -// boost::python::list traceList( pFunc( traceObj ) ); -// -// for ( long i = 0; i < boost::python::len(traceList); ++i ) -// { -// std::string traceLine = boost::python::extract(traceList[i]); -// dbgExt->control->Output( DEBUG_OUTPUT_ERROR, traceLine.c_str() ); -// } -// } -// -// Py_DECREF(errvalueStr); -// } -// -// Py_XDECREF(errvalue); -// Py_XDECREF(errtype); -// Py_XDECREF(traceback); -// } -// } -// else -// { -// dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "script file not found\n" ); -// } -// } -// -// catch(...) -// { -// dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "unexpected error" ); -// } -// -// Py_EndInterpreter( localInterpreter ); -// PyThreadState_Swap( globalInterpreter ); -// -// return S_OK; -//} -// -/////////////////////////////////////////////////////////////////////////////////// -// -//HRESULT -//CALLBACK -//pycmd( PDEBUG_CLIENT4 client, PCSTR args ) -//{ -// DbgExt ext( client ); -// -// try { -// -// // перенаправление стандартных потоков ВВ -// boost::python::object sys = boost::python::import("sys"); -// -// dbgOut dout; -// sys.attr("stdout") = boost::python::object( dout ); -// -// dbgIn din; -// sys.attr("stdin") = boost::python::object( din ); -// -// boost::python::object syntaxError = boost::python::import("exceptions").attr("SyntaxError"); -// -// boost::python::object tracebackModule = boost::python::import("traceback"); -// -// std::string commandBuffer; -// -// bool commandCompleted = true; -// -// do { -// -// if ( commandCompleted ) -// { -// dbgExt->control->Output( DEBUG_OUTPUT_NORMAL, ">>>" ); -// } -// else -// { -// dbgExt->control->Output( DEBUG_OUTPUT_NORMAL, "..." ); -// } -// -// { -// char str[100]; -// ULONG inputSize; -// -// OutputReader outputReader( (IDebugClient*)client ); -// HRESULT hres = dbgExt->control->Input( str, sizeof(str), &inputSize ); -// -// if ( FAILED( hres ) ) -// throw; -// -// if ( commandCompleted ) -// { -// if ( std::string( str ) == "" ) -// break; -// -// commandBuffer = str; -// } -// else -// { -// if ( std::string( str ) == "" ) -// commandCompleted = true; -// else -// { -// commandBuffer.append("\n"); -// commandBuffer.append( str ); -// } -// } -// } -// -// if ( commandCompleted ) -// { -// try { -// -// boost::python::exec( commandBuffer.c_str(), WindbgGlobalSession::global(), WindbgGlobalSession::global() ); -// -// commandBuffer.clear(); -// -// } -// catch( boost::python::error_already_set const & ) -// { -// PyObject *errtype = NULL, *errvalue = NULL, *traceback = NULL, *errvalueStr = NULL; -// -// PyErr_Fetch( &errtype, &errvalue, &traceback ); -// -// if ( errtype && errvalue ) -// { -// errvalueStr = PyObject_Str(errvalue); -// -// do { -// -// if ( PyErr_GivenExceptionMatches( syntaxError.ptr(), errtype ) ) -// { -// boost::python::tuple errValueObj( boost::python::handle<>( boost::python::borrowed(errvalue) ) ); -// -// if ( errValueObj[0] == "unexpected EOF while parsing" ) -// { -// commandCompleted = false; -// break; -// } -// } -// -// dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "%s\n", PyString_AS_STRING(errvalueStr) ); -// -// if ( traceback ) -// { -// boost::python::object traceObj( boost::python::handle<>( boost::python::borrowed( traceback ) ) ); -// -// dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "\nTraceback:\n" ); -// -// boost::python::object pFunc( tracebackModule.attr("format_tb") ); -// boost::python::list traceList( pFunc( traceObj ) ); -// -// for ( long i = 0; i < boost::python::len(traceList); ++i ) -// { -// std::string traceLine = boost::python::extract(traceList[i]); -// dbgExt->control->Output( DEBUG_OUTPUT_ERROR, traceLine.c_str() ); -// } -// } -// -// } while( FALSE ); -// -// Py_XDECREF(errvalueStr); -// Py_XDECREF(errvalue); -// Py_XDECREF(errtype); -// Py_XDECREF(traceback); -// } -// else -// { -// Py_XDECREF(errvalue); -// Py_XDECREF(errtype); -// Py_XDECREF(traceback); -// -// throw; -// } -// } -// } -// -// } while( true ); -// } -// catch(...) -// { -// dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "unexpected error" ); -// } -// -// return S_OK; -//} -// -/////////////////////////////////////////////////////////////////////////////////// -// -//HRESULT -//CALLBACK -//pythonpath( PDEBUG_CLIENT4 client, PCSTR args ) -//{ -// //DbgExt ext; -// -// //SetupDebugEngine( client, &ext ); -// //dbgExt = &ext; -// -// ////DbgPrint::dprintln( dbgPythonPath.getStr() ); -// -// return S_OK; -//} -// -/////////////////////////////////////////////////////////////////////////////////// -// diff --git a/pykd/module.cpp b/pykd/module.cpp index 5f48876..ff30cbf 100644 --- a/pykd/module.cpp +++ b/pykd/module.cpp @@ -152,6 +152,16 @@ Module::reloadSymbols() /////////////////////////////////////////////////////////////////////////////////// +TypeInfo +Module::getTypeByName( const std::string typeName ) +{ + pyDia::SymbolPtr typeSym = m_dia->getChildByName( typeName ); + + return TypeInfo( typeSym ); +} + +/////////////////////////////////////////////////////////////////////////////////// + }; // end of namespace pykd diff --git a/pykd/module.h b/pykd/module.h index 0e5c3a0..770c958 100644 --- a/pykd/module.h +++ b/pykd/module.h @@ -4,6 +4,7 @@ #include "dbgobj.h" #include "diawrapper.h" +#include "typeinfo.h" namespace pykd { @@ -65,6 +66,7 @@ public: return sym->getRva(); } + TypeInfo getTypeByName( const std::string typeName ); private: diff --git a/pykd/pykd_2008.vcproj b/pykd/pykd_2008.vcproj index 7435307..7bbbe8a 100644 --- a/pykd/pykd_2008.vcproj +++ b/pykd/pykd_2008.vcproj @@ -467,6 +467,10 @@ RelativePath=".\stdafx.h" > + + diff --git a/test/scripts/pykdtest.py b/test/scripts/pykdtest.py index a33e17b..4ad88cd 100644 --- a/test/scripts/pykdtest.py +++ b/test/scripts/pykdtest.py @@ -23,7 +23,7 @@ def getTestSuite( singleName = "" ): [ unittest.TestLoader().loadTestsFromTestCase( basetest.BaseTest ), unittest.TestLoader().loadTestsFromTestCase( moduletest.ModuleTest ), unittest.TestLoader().loadTestsFromTestCase( diatest.DiaTest ), -# unittest.TestLoader().loadTestsFromTestCase( typeinfo.TypeInfoTest ), + unittest.TestLoader().loadTestsFromTestCase( typeinfo.TypeInfoTest ), # unittest.TestLoader().loadTestsFromTestCase( regtest.CpuRegTest ) ] ) else: diff --git a/test/scripts/typeinfo.py b/test/scripts/typeinfo.py index 6a23d19..a9d0ef5 100644 --- a/test/scripts/typeinfo.py +++ b/test/scripts/typeinfo.py @@ -2,78 +2,19 @@ # # -#import unittest -#import pykd -#import target +import unittest +import target +import pykd +class TypeInfoTest( unittest.TestCase ): -#class TypeInfoTest( unittest.TestCase ): + def testCtor( self ): + """ typeInfo class can not be created direct """ + try: pykd.typeInfo() + except RuntimeError: pass + + def testCreateByName( self ): + """ creating typeInfo by the type name """ + ti1 = target.module.type( "structTest" ) + ti2 = target.module.type( "classChild" ) -# def testBasicTypes(self): -# self.assertEqual( pykd.char_t.name(), "char" ) -# self.assertEqual( pykd.char_t.size(), 1 ) -# self.assertEqual( pykd.uchar_t.name(), "unsigned char" ) -# self.assertEqual( pykd.uchar_t.size(), 1 ) - -# def testSimpleStruct(self): -# ti = pykd.typeInfo( target.moduleName, "Type1" ) -# self.assertTrue( hasattr( ti, "field1" ) ) -# self.assertTrue( hasattr( ti, "field2" ) ) -# self.assertTrue( hasattr( ti, "field3" ) ) - -# tv = pykd.typedVar( ti, target.module.var1 ) -# self.assertEqual( tv.field1, -121 ) -# self.assertEqual( tv.field2, 220 ) -# self.assertLess( tv.field3 - 1.0095, 0.0001 ) - -# def testEnumField(self): -# ti = pykd.typeInfo( target.moduleName, "Type2" ) -# self.assertEqual( hasattr( ti, "field1" ), True ) - -# tv = pykd.typedVar( ti, target.module.var2 ) -# self.assertEqual( tv.field1, 100 ) - -# def testNamespace(self): -# ti1 = pykd.typeInfo( target.moduleName, "Namespace1::Class1" ) -# ti2 = pykd.typeInfo( target.moduleName, "Namespace1::Namespace2::Class2" ) -# var3 = pykd.typedVar( ti1, pykd.getOffset( target.moduleName, "Namespace1::var3" ) ) -# var4 = pykd.typedVar( ti1, pykd.getOffset( target.moduleName, "Namespace1::Namespace2::var4" ) ) -# self.assertEqual( var3.m_field1, 50 ) - -# def testTemplates(self): -# ti3 = pykd.typeInfo( target.moduleName, "Namespace3::Class3" ) -# var5 = pykd.typedVar( ti3, pykd.getOffset( target.moduleName, "Namespace3::var5" ) ) -# self.assertEqual( var5.m_field1, 5 ) - -# def testNestedStruct(self): -# ti4 = pykd.typeInfo( target.moduleName, "Type4" ) -# self.assertTrue( hasattr( ti4, "field1" ) ) -# self.assertTrue( hasattr( ti4, "field2" ) ) -# self.assertTrue( hasattr( ti4, "field3" ) ) -# self.assertTrue( hasattr( ti4, "field4" ) ) -# self.assertTrue( hasattr( ti4, "field4" ) ) -# self.assertTrue( hasattr( ti4.field4, "field41" ) ) - -# def testPtrField(self): -# v6 = pykd.typedVar( target.moduleName, "Type6", pykd.getOffset( target.moduleName, "var6" ) ) -# self.assertEqual( v6.field1, 10 ) -# self.assertEqual( v6.field2.field1, 10 ) -# self.assertEqual( v6.field2.field2, 20 ) -# self.assertNotEqual( v6.field2, 0 ) -# self.assertEqual( v6.field3[0].field1, 10 ) -# self.assertEqual( v6.field3[1].field2, 20 ) - -# def testArrayField(self): -# v7 = pykd.typedVar( target.moduleName, "Type7", pykd.getOffset( target.moduleName, "var7" ) ) -# self.assertEqual( v7.field1[1].field1, 10 ) -# self.assertEqual( v7.field1[5].field2, 20 ) -# self.assertEqual( v7.field2[1][0].field1, 10 ) -# self.assertEqual( v7.field2[0][1].field2, 20 ) - -# def testTypedVarByAddress(self): -# var5 = pykd.typedVar( pykd.getOffset( target.moduleName, "Namespace3::var5" ) ) -# self.assertEqual( var5.m_field1, 5 ) - -# def testTypedVarBySymbolName(self): -# var5 = pykd.typedVar( "Namespace3::var5" ) -# self.assertEqual( var5.m_field1, 5 )