From b7737870e56c3e26882ff0373f5bf4fe98039284 Mon Sep 17 00:00:00 2001 From: "SND\\kernelnet_cp" Date: Wed, 26 Oct 2011 06:49:57 +0000 Subject: [PATCH] [0.1.x] added : loadBytes [0.1.x] added : loadWords [0.1.x] added : loadDWords [0.1.x] added : loadQWords git-svn-id: https://pykd.svn.codeplex.com/svn@70757 9b283d60-5439-405e-af05-b73fd8c4d996 --- pykd/dbgclient.h | 16 ++- pykd/dbgevent.cpp | 219 +++++++++++++++++++++++++++++++++-- pykd/dbgevent.h | 57 ++++++--- pykd/dbgext.cpp | 28 ++++- pykd/dbgmem.cpp | 68 +++++++++++ pykd/dbgmem.h | 8 ++ test/scripts/basetest.py | 7 +- test/scripts/memtest.py | 41 +++++++ test/targetapp/targetapp.cpp | 9 ++ 9 files changed, 424 insertions(+), 29 deletions(-) create mode 100644 test/scripts/memtest.py diff --git a/pykd/dbgclient.h b/pykd/dbgclient.h index 3782425..9ec8700 100644 --- a/pykd/dbgclient.h +++ b/pykd/dbgclient.h @@ -86,9 +86,17 @@ public: return DbgExtensionPtr( new DbgExtension( m_client, extPath ) ); } - std::string loadChars( ULONG64 address, ULONG number, bool phyAddr = FALSE ); + python::list loadBytes( ULONG64 offset, ULONG count, bool phyAddr = FALSE ); - std::wstring loadWChars( ULONG64 address, ULONG number, bool phyAddr = FALSE ); + python::list loadWords( ULONG64 offset, ULONG count, bool phyAddr = FALSE ); + + python::list loadDWords( ULONG64 offset, ULONG count, bool phyAddr = FALSE ); + + python::list loadQWords( ULONG64 offset, ULONG count, bool phyAddr = FALSE ); + + std::string loadChars( ULONG64 offset, ULONG count, bool phyAddr = FALSE ); + + std::wstring loadWChars( ULONG64 offset, ULONG count, bool phyAddr = FALSE ); void dprint( const std::wstring &str, bool dml = false ); @@ -131,6 +139,10 @@ public: private: + template + python::list + loadArray( ULONG64 offset, ULONG count, bool phyAddr ); + DebugClient( IDebugClient4 *client ) : DbgObject( client ) {} PyThreadStateSaver m_pyThreadState; diff --git a/pykd/dbgevent.cpp b/pykd/dbgevent.cpp index 3f2d19a..bf26aa4 100644 --- a/pykd/dbgevent.cpp +++ b/pykd/dbgevent.cpp @@ -15,39 +15,239 @@ EventHandler::EventHandler() { HRESULT hres; - hres = g_dbgClient->client()->CreateClient( &m_client ); + hres = g_dbgClient->client()->CreateClient( &m_handlerClient ); if ( FAILED( hres ) ) throw DbgException( "IDebugClient::CreateClient" ); - hres = m_client->SetEventCallbacks(this); + hres = m_handlerClient->SetEventCallbacks(this); if (FAILED(hres)) - throw DbgException( "IDebugClient::SetEventCallbacks" ); + throw DbgException( "IDebugClient::SetEventCallbacks" ); + + m_parentClient = g_dbgClient; } /////////////////////////////////////////////////////////////////////////////////// -EventHandler::EventHandler( DebugClient &client ) +EventHandler::EventHandler( DebugClientPtr &client ) { HRESULT hres; - hres = client.client()->CreateClient( &m_client ); + hres = client->client()->CreateClient( &m_handlerClient ); if ( FAILED( hres ) ) throw DbgException( "IDebugClient::CreateClient" ); - hres = m_client->SetEventCallbacks(this); + hres = m_handlerClient->SetEventCallbacks(this); if (FAILED(hres)) - throw DbgException( "IDebugClient::SetEventCallbacks" ); + throw DbgException( "IDebugClient::SetEventCallbacks" ); + + m_parentClient = client; } /////////////////////////////////////////////////////////////////////////////////// EventHandler::~EventHandler() { - m_client->SetEventCallbacks( NULL ); + m_handlerClient->SetEventCallbacks( NULL ); } /////////////////////////////////////////////////////////////////////////////////// +HRESULT EventHandler::GetInterestMask( + __out PULONG Mask +) +{ + *Mask = 0; + + *Mask |= DEBUG_EVENT_LOAD_MODULE; + *Mask |= DEBUG_EVENT_UNLOAD_MODULE; + *Mask |= DEBUG_EVENT_SESSION_STATUS; + *Mask |= DEBUG_EVENT_EXCEPTION; + *Mask |= DEBUG_EVENT_BREAKPOINT; + + return S_OK; +} + +/////////////////////////////////////////////////////////////////////////////////// + +HRESULT EventHandler::Breakpoint( + __in PDEBUG_BREAKPOINT Bp +) +{ +// boost::python::dict bpParameters; +// +// HRESULT hres; +// ULONG Value = 0; +// ULONG Value2 = 0; +// ULONG64 Value64 = 0; +// std::string str; +// +//#define _ADD_BP_ULONG(x) \ +// hres = Bp->Get##x(&Value); \ +// BOOST_ASSERT( SUCCEEDED( hres ) || hres == E_NOINTERFACE ); \ +// if (SUCCEEDED( hres )) \ +// bpParameters[#x] = Value; +// +//#define _ADD_BP_ULONG2(x, n1, n2) \ +// hres = Bp->Get##x(&Value, &Value2); \ +// BOOST_ASSERT( SUCCEEDED( hres ) || hres == E_NOINTERFACE ); \ +// if (SUCCEEDED( hres )) \ +// { \ +// bpParameters[n1] = Value; bpParameters[n2] = Value2; \ +// } +// +//#define _ADD_BP_ULONG64(x) \ +// hres = Bp->Get##x(&Value64); \ +// BOOST_ASSERT( SUCCEEDED( hres ) || hres == E_NOINTERFACE ); \ +// if (SUCCEEDED( hres )) \ +// bpParameters[#x] = Value64; +// +//#define _ADD_BP_STR(x) \ +// Value = 0; \ +// Bp->Get##x(NULL, 0, &Value); \ +// if (Value) \ +// { \ +// str.resize(Value + 1); \ +// BOOST_VERIFY( SUCCEEDED( \ +// Bp->Get##x(&str[0], (ULONG)str.size(), NULL) \ +// ) ); \ +// if (!str.empty()) bpParameters[#x] = str.c_str(); \ +// } +// +// _ADD_BP_ULONG(Id); +// _ADD_BP_ULONG2(Type, "BreakType", "ProcType"); +// _ADD_BP_ULONG(Flags); +// _ADD_BP_ULONG64(Offset); +// _ADD_BP_ULONG2(DataParameters, "Size", "AccessType"); +// _ADD_BP_ULONG(PassCount); +// _ADD_BP_ULONG(CurrentPassCount); +// _ADD_BP_ULONG(MatchThreadId); +// _ADD_BP_STR(Command); +// _ADD_BP_STR(OffsetExpression); +// +//#undef _ADD_BP_ULONG +//#undef _ADD_BP_ULONG2 +//#undef _ADD_BP_ULONG64 +//#undef _ADD_BP_STR +// + //PyThread_StateSave pyThreadSave; + + boost::python::dict bpParameters; + + return onBreakpoint( bpParameters ); + + //onException(bpParameters); + //return S_OK; +} + +/////////////////////////////////////////////////////////////////////////////////// + +HRESULT EventHandler::Exception( + __in PEXCEPTION_RECORD64 Exception, + __in ULONG FirstChance +) +{ + python::list exceptParams; + python::dict exceptData; + + // build list of parameters + for (ULONG i = 0; i < Exception->NumberParameters; ++i) + exceptParams.append(Exception->ExceptionInformation[i]); + + exceptData["Code"] = Exception->ExceptionCode; + exceptData["Flags"] = Exception->ExceptionFlags; + exceptData["Record"] = Exception->ExceptionRecord; + exceptData["Address"] = Exception->ExceptionAddress; + exceptData["Parameters"] = exceptParams; + exceptData["FirstChance"] = (0 != FirstChance); + + PyThread_StateSave pyThreadSave( m_parentClient->getThreadState() ); + + return onException(exceptData); +} + +/////////////////////////////////////////////////////////////////////////////////// + +HRESULT EventHandler::LoadModule( + __in ULONG64 ImageFileHandle, + __in ULONG64 BaseOffset, + __in ULONG ModuleSize, + __in PCSTR ModuleName, + __in PCSTR ImageName, + __in ULONG CheckSum, + __in ULONG TimeDateStamp +) +{ + //PyThread_StateSave pyThreadSave( m_parentClient->getThreadState() ); + + //return onLoadModule( module ); + + //std::auto_ptr silentMode( new OutputReader(dbgExt->client) ); + + //ULONG64 moduleBase; + //ULONG moduleSize; + //std::string moduleName; + // + //queryModuleParams(BaseOffset, moduleName, moduleBase, moduleSize); + //dbgModuleClass module(moduleName, moduleBase, moduleSize); + //silentMode.reset(); + + //PyThread_StateSave pyThreadSave; + //return onLoadModule( module ); + + return S_OK; + +} + +/////////////////////////////////////////////////////////////////////////////////// + +HRESULT EventHandler::UnloadModule( + __in PCSTR ImageBaseName, + __in ULONG64 BaseOffset +) +{ + //std::auto_ptr silentMode( new OutputReader(dbgExt->client) ); + + //ULONG64 moduleBase; + //ULONG moduleSize; + //std::string moduleName; + // + //queryModuleParams(BaseOffset, moduleName, moduleBase, moduleSize); + //dbgModuleClass module(moduleName, moduleBase, moduleSize); + //silentMode.reset(); + + //PyThread_StateSave pyThreadSave; + //return onUnloadModule( module ); + return S_OK; +} + +/////////////////////////////////////////////////////////////////////////////////// + +HRESULT EventHandler::SessionStatus( + __in ULONG Status +) +{ + //PyThread_StateSave pyThreadSave; + //return onChangeSessionStatus( Status ); + + return S_OK; +} + +/////////////////////////////////////////////////////////////////////////////////// + +HRESULT EventHandler::ChangeDebuggeeState( + __in ULONG Flags, + __in ULONG64 Argument +) +{ + //PyThread_StateSave pyThreadSave; + //return onChangeDebugeeState(); + + return S_OK; +} + +/////////////////////////////////////////////////////////////////////////////////// + + }; // end pykd namespace @@ -56,6 +256,9 @@ EventHandler::~EventHandler() + + + //#include "dbgevent.h" //#include "dbgio.h" //#include "dbgexcept.h" diff --git a/pykd/dbgevent.h b/pykd/dbgevent.h index b06bc85..6a34b60 100644 --- a/pykd/dbgevent.h +++ b/pykd/dbgevent.h @@ -21,7 +21,7 @@ public: EventHandler(); - EventHandler( DebugClient &client ); + EventHandler( DebugClientPtr &client ); virtual ~EventHandler(); @@ -30,18 +30,43 @@ protected: STDMETHOD_(ULONG, AddRef)() { return 1; } STDMETHOD_(ULONG, Release)() { return 1; } - STDMETHOD(GetInterestMask)( - __out PULONG Mask - ) { - *Mask = 0; - *Mask |= DEBUG_EVENT_LOAD_MODULE; - *Mask |= DEBUG_EVENT_UNLOAD_MODULE; - *Mask |= DEBUG_EVENT_SESSION_STATUS; - *Mask |= DEBUG_EVENT_EXCEPTION; - *Mask |= DEBUG_EVENT_BREAKPOINT; - return S_OK; - } - + STDMETHOD( GetInterestMask ) ( + __out PULONG Mask + ); + + STDMETHOD(Breakpoint)( + __in PDEBUG_BREAKPOINT Bp + ); + + STDMETHOD(Exception)( + __in PEXCEPTION_RECORD64 Exception, + __in ULONG FirstChance + ); + + STDMETHOD(LoadModule)( + __in ULONG64 ImageFileHandle, + __in ULONG64 BaseOffset, + __in ULONG ModuleSize, + __in PCSTR ModuleName, + __in PCSTR ImageName, + __in ULONG CheckSum, + __in ULONG TimeDateStamp + ); + + STDMETHOD(UnloadModule)( + __in PCSTR ImageBaseName, + __in ULONG64 BaseOffset + ); + + STDMETHOD(SessionStatus)( + __in ULONG Status + ); + + STDMETHOD(ChangeDebuggeeState)( + __in ULONG Flags, + __in ULONG64 Argument ); + + protected: virtual ULONG onBreakpoint(const python::dict &/*bpParameters*/) = 0; @@ -58,7 +83,9 @@ protected: protected: - CComPtr m_client; + CComPtr m_handlerClient; + + DebugClientPtr m_parentClient; }; ///////////////////////////////////////////////////////////////////////////////// @@ -71,7 +98,7 @@ public: EventHandlerWrap() {} - EventHandlerWrap( DebugClient &client ) : EventHandler( client ) + EventHandlerWrap( DebugClientPtr &client ) : EventHandler( client ) {} ULONG onBreakpoint(const python::dict &bpParameters) { diff --git a/pykd/dbgext.cpp b/pykd/dbgext.cpp index 14d3c1f..6815e79 100644 --- a/pykd/dbgext.cpp +++ b/pykd/dbgext.cpp @@ -57,9 +57,17 @@ BOOST_PYTHON_FUNCTION_OVERLOADS( dprintln_, dprintln, 1, 2 ); BOOST_PYTHON_FUNCTION_OVERLOADS( loadChars_, loadChars, 2, 3 ); BOOST_PYTHON_FUNCTION_OVERLOADS( loadWChars_, loadWChars, 2, 3 ); +BOOST_PYTHON_FUNCTION_OVERLOADS( loadBytes_, loadBytes, 2, 3 ); +BOOST_PYTHON_FUNCTION_OVERLOADS( loadWords_, loadWords, 2, 3 ); +BOOST_PYTHON_FUNCTION_OVERLOADS( loadDWords_, loadDWords, 2, 3 ); +BOOST_PYTHON_FUNCTION_OVERLOADS( loadQWords_, loadQWords, 2, 3 ); BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( DebugClient_loadChars, DebugClient::loadChars, 2, 3 ); BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( DebugClient_loadWChars, DebugClient::loadWChars, 2, 3 ); +BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( DebugClient_loadBytes, DebugClient::loadBytes, 2, 3 ); +BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( DebugClient_loadWords, DebugClient::loadWords, 2, 3 ); +BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( DebugClient_loadDWords, DebugClient::loadDWords, 2, 3 ); +BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( DebugClient_loadQWords, DebugClient::loadQWords, 2, 3 ); #define DEF_PY_CONST_ULONG(x) \ @@ -88,9 +96,17 @@ BOOST_PYTHON_MODULE( pykd ) "Check if it is a dump analyzing ( not living debuggee )" ) .def( "isKernelDebugging", &pykd::DebugClient::isKernelDebugging, "Check if kernel dubugging is running" ) - .def( "loadChars", &pykd::DebugClient::loadChars, DebugClient_loadChars( python::args( "address", "count", "phyAddr" ), + .def( "loadBytes", &pykd::DebugClient::loadBytes, DebugClient_loadBytes( python::args( "offset", "count", "phyAddr" ), + "Read the block of the target's memory and return it as list of unsigned bytes" ) ) + .def( "loadWords", &pykd::DebugClient::loadWords, DebugClient_loadWords( python::args( "offset", "count", "phyAddr" ), + "Read the block of the target's memory and return it as list of unsigned shorts" ) ) + .def( "loadDWords", &pykd::DebugClient::loadDWords, DebugClient_loadDWords( python::args( "offset", "count", "phyAddr" ), + "Read the block of the target's memory and return it as list of unsigned long ( double word )" ) ) + .def( "loadQWords", &pykd::DebugClient::loadQWords, DebugClient_loadQWords( python::args( "offset", "count", "phyAddr" ), + "Read the block of the target's memory and return it as list of unsigned long long ( quad word )" ) ) + .def( "loadChars", &pykd::DebugClient::loadChars, DebugClient_loadChars( python::args( "offset", "count", "phyAddr" ), "Load string from target memory" ) ) - .def( "loadWChars", &pykd::DebugClient::loadWChars, DebugClient_loadWChars( python::args( "address", "count", "phyAddr" ), + .def( "loadWChars", &pykd::DebugClient::loadWChars, DebugClient_loadWChars( python::args( "offset", "count", "phyAddr" ), "Load string from target memory" ) ) .def ( "loadExt", &pykd::DebugClient::loadExtension, "Load a debuger extension" ) @@ -135,6 +151,14 @@ BOOST_PYTHON_MODULE( pykd ) "Check if it is a dump analyzing ( not living debuggee )" ); python::def( "isKernelDebugging", &pykd::isKernelDebugging, "Check if kernel dubugging is running" ); + python::def( "loadBytes", &loadBytes, loadBytes_( python::args( "offset", "count", "phyAddr" ), + "Read the block of the target's memory and return it as liat of unsigned bytes" ) ); + python::def( "loadWords", &loadWords, loadWords_( python::args( "offset", "count", "phyAddr" ), + "Read the block of the target's memory and return it as list of unsigned shorts" ) ); + python::def( "loadDWords", &loadDWords, loadDWords_( python::args( "offset", "count", "phyAddr" ), + "Read the block of the target's memory and return it as list of unsigned long ( double word )" ) ); + python::def( "loadQWords", &loadQWords, loadQWords_( python::args( "offset", "count", "phyAddr" ), + "Read the block of the target's memory and return it as list of unsigned long long ( quad word )" ) ); python::def( "loadChars", &loadChars, loadChars_( python::args( "address", "count", "phyAddr" ), "Load string from target memory" ) ); python::def( "loadWChars", &loadWChars, loadWChars_( python::args( "address", "count", "phyAddr" ), diff --git a/pykd/dbgmem.cpp b/pykd/dbgmem.cpp index ae1c306..fda9699 100644 --- a/pykd/dbgmem.cpp +++ b/pykd/dbgmem.cpp @@ -7,6 +7,25 @@ namespace pykd { ///////////////////////////////////////////////////////////////////////////////////// +template +python::list +DebugClient::loadArray( ULONG64 offset, ULONG count, bool phyAddr ) +{ + std::vector buffer(count); + + if (count) + readMemory( offset, &buffer[0], count*sizeof(T), phyAddr ); + + python::list lst; + + for( ULONG i = 0; i < count; ++i ) + lst.append( buffer[i] ); + + return lst; +} + +///////////////////////////////////////////////////////////////////////////////////// + ULONG64 DebugClient::addr64( ULONG64 addr) { @@ -104,6 +123,55 @@ std::wstring loadWChars( ULONG64 address, ULONG number, bool phyAddr ) ///////////////////////////////////////////////////////////////////////////////////// +python::list DebugClient::loadBytes( ULONG64 offset, ULONG count, bool phyAddr ) +{ + return loadArray( offset, count, phyAddr ); +} + +python::list loadBytes( ULONG64 offset, ULONG count, bool phyAddr ) +{ + return g_dbgClient->loadBytes( offset, count, phyAddr ); +} + +///////////////////////////////////////////////////////////////////////////////////// + +python::list DebugClient::loadWords( ULONG64 offset, ULONG count, bool phyAddr ) +{ + return loadArray( offset, count, phyAddr ); +} + +python::list loadWords( ULONG64 offset, ULONG count, bool phyAddr ) +{ + return g_dbgClient->loadWords( offset, count, phyAddr ); +} + +///////////////////////////////////////////////////////////////////////////////////// + +python::list DebugClient::loadDWords( ULONG64 offset, ULONG count, bool phyAddr ) +{ + return loadArray( offset, count, phyAddr ); +} + +python::list loadDWords( ULONG64 offset, ULONG count, bool phyAddr ) +{ + return g_dbgClient->loadDWords( offset, count, phyAddr ); +} + +///////////////////////////////////////////////////////////////////////////////////// + +python::list DebugClient::loadQWords( ULONG64 offset, ULONG count, bool phyAddr ) +{ + return loadArray( offset, count, phyAddr ); +} + +python::list loadQWords( ULONG64 offset, ULONG count, bool phyAddr ) +{ + return g_dbgClient->loadQWords( offset, count, phyAddr ); +} + +///////////////////////////////////////////////////////////////////////////////////// + + }; // end of pykd diff --git a/pykd/dbgmem.h b/pykd/dbgmem.h index 96d610b..12c18e1 100644 --- a/pykd/dbgmem.h +++ b/pykd/dbgmem.h @@ -21,6 +21,14 @@ std::string loadChars( ULONG64 address, ULONG number, bool phyAddr = FALSE ); std::wstring loadWChars( ULONG64 address, ULONG number, bool phyAddr = FALSE ); +python::list loadBytes( ULONG64 offset, ULONG count, bool phyAddr = FALSE ); + +python::list loadWords( ULONG64 offset, ULONG count, bool phyAddr = FALSE ); + +python::list loadDWords( ULONG64 offset, ULONG count, bool phyAddr = FALSE ); + +python::list loadQWords( ULONG64 offset, ULONG count, bool phyAddr = FALSE ); + /////////////////////////////////////////////////////////////////////////////////// }; diff --git a/test/scripts/basetest.py b/test/scripts/basetest.py index 9e1d1cf..1751815 100644 --- a/test/scripts/basetest.py +++ b/test/scripts/basetest.py @@ -8,8 +8,8 @@ import pykd class BaseTest( unittest.TestCase ): - def testOldSupportedApi( self ): - """ Branch test: API 0.0.x what must be available """ + def testOldSupportedRoutines( self ): + """ Branch test: old API 0.0.x what must be available """ self.assertTrue( hasattr(pykd, 'addSynSymbol') ) self.assertTrue( hasattr(pykd, 'attachKernel') ) @@ -87,6 +87,9 @@ class BaseTest( unittest.TestCase ): self.assertTrue( hasattr(pykd, 'typedVarList') ) self.assertTrue( hasattr(pykd, 'wrmsr') ) + + def testOldSupportedClass( self ): + """ Branch test: old API 0.0.x class must be available """ self.assertTrue( hasattr(pykd, 'BaseException') ) self.assertTrue( hasattr(pykd, 'MemoryException') ) self.assertTrue( hasattr(pykd, 'TypeException') ) diff --git a/test/scripts/memtest.py b/test/scripts/memtest.py new file mode 100644 index 0000000..69d31ac --- /dev/null +++ b/test/scripts/memtest.py @@ -0,0 +1,41 @@ +# +# +# + +import unittest +import target +import pykd + +class MemoryTest( unittest.TestCase ): + + def testLoadChars( self ): + s = pykd.loadChars( target.module.helloStr, 5 ) + self.assertEqual( "Hello", s ) + + def testLoadWChars( self ): + s = pykd.loadWChars( target.module.helloWStr, 5 ) + self.assertEqual( "Hello", s ) + + def testLoadBytes( self ): + ucharArray = pykd.loadBytes( target.module.ucharArray, 5 ) + testArray = [ 0, 10, 0x78, 128, 0xFF ] + self.assertEqual( 5, len(ucharArray) ) + self.assertEqual( 0, len( [ ucharArray[i] for i in xrange(5) if ucharArray[i] != testArray[i] ] ) ) + + def testLoadWords( self ): + loadArray = pykd.loadWords( target.module.ushortArray, 5 ) + testArray = [ 0, 10, 0xFF, 0xFFF, 0xFFFF ] + self.assertEqual( len(testArray), len(loadArray) ) + self.assertEqual( 0, len( [ loadArray[i] for i in xrange(len(testArray)) if loadArray[i] != testArray[i] ] ) ) + + def testLoadDWords( self ): + loadArray = pykd.loadDWords( target.module.ulongArray, 5 ) + testArray = [ 0, 0xFF, 0xFFF, 0xFFFF, 0xFFFFFFFF ] + self.assertEqual( len(testArray), len(loadArray) ) + self.assertEqual( 0, len( [ loadArray[i] for i in xrange(len(testArray)) if loadArray[i] != testArray[i] ] ) ) + + def testLoadQWords( self ): + loadArray = pykd.loadQWords( target.module.ulonglongArray, 5 ) + testArray = [ 0, 0xFF, 0xFFF, 0x8000000000000000, 0xFFFFFFFFFFFFFFFF ] + self.assertEqual( len(testArray), len(loadArray) ) + self.assertEqual( 0, len( [ loadArray[i] for i in xrange(len(testArray)) if loadArray[i] != testArray[i] ] ) ) \ No newline at end of file diff --git a/test/targetapp/targetapp.cpp b/test/targetapp/targetapp.cpp index 8cb9f82..b1b4972 100644 --- a/test/targetapp/targetapp.cpp +++ b/test/targetapp/targetapp.cpp @@ -56,6 +56,11 @@ structTest **g_structTestPtrPtr = &g_structTestPtr; char helloStr[] = "Hello"; wchar_t helloWStr[] = L"Hello"; +unsigned char ucharArray[] = {0, 10, 0x78, 128, 0xFF }; +unsigned short ushortArray[] = {0, 10, 0xFF, 0xFFF, 0xFFFF }; +unsigned long ulongArray[] = {0, 0xFF, 0xFFF, 0xFFFF, 0xFFFFFFFF }; +unsigned __int64 ulonglongArray[] = {0, 0xFF, 0xFFF, 0x8000000000000000, 0xFFFFFFFFFFFFFFFF }; + class classChild : public classBase { public: int m_childField; @@ -93,6 +98,10 @@ void FuncWithName0() std::cout << helloStr; std::wcout << helloWStr; + std::cout << ucharArray[2]; + std::cout << ushortArray[2]; + std::cout << ulongArray[2]; + std::cout << ulonglongArray[2]; } void FuncWithName1(int a)