mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-21 04:13:22 +08:00
Merge branch '0.3.2' into '0.3.2'
Enumerate and read secondary callback (Issue #14) See merge request pykd/pykd!1
This commit is contained in:
commit
3018bcdc3d
2
kdlibcpp
2
kdlibcpp
@ -1 +1 @@
|
||||
Subproject commit 3bb3cbf8e4a206d7bcf08f0d8303e3c59dd4e2b4
|
||||
Subproject commit 9bfa80d7f415e8697f7c84696d67afda07dbc559
|
@ -590,6 +590,7 @@
|
||||
<ClInclude Include="pymodule.h" />
|
||||
<ClInclude Include="pyprocess.h" />
|
||||
<ClInclude Include="pysymengine.h" />
|
||||
<ClInclude Include="pytagged.h" />
|
||||
<ClInclude Include="pythreadstate.h" />
|
||||
<ClInclude Include="pytypedvar.h" />
|
||||
<ClInclude Include="pytypeinfo.h" />
|
||||
@ -623,6 +624,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="pymodule.cpp" />
|
||||
<ClCompile Include="pyprocess.cpp" />
|
||||
<ClCompile Include="pytagged.cpp" />
|
||||
<ClCompile Include="pytypedvar.cpp" />
|
||||
<ClCompile Include="pytypeinfo.cpp" />
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
|
@ -81,6 +81,9 @@
|
||||
<ClInclude Include="pydataaccess.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="pytagged.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
@ -248,6 +251,9 @@
|
||||
<ClCompile Include="pyprocess.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="pytagged.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="pykd.def">
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "pytypeinfo.h"
|
||||
#include "pycpucontext.h"
|
||||
#include "pyprocess.h"
|
||||
#include "pytagged.h"
|
||||
|
||||
using namespace pykd;
|
||||
|
||||
@ -597,6 +598,12 @@ BOOST_PYTHON_MODULE( pykd )
|
||||
python::def( "removeSyntheticSymbol", pykd::removeSyntheticSymbol,
|
||||
"The removeSyntheticSymbol function removes a synthetic symbol from a module in the current proces" );
|
||||
|
||||
// secondary callback data
|
||||
python::def("enumTagged", pykd::enumTagged,
|
||||
"Return the list of secondary callback data IDs (as a strings)" );
|
||||
python::def("loadTaggedBuffer", pykd::loadTaggedBuffer,
|
||||
"Read the buffer of secondary callback data by ID" );
|
||||
|
||||
python::class_<kdlib::NumBehavior, boost::noncopyable>( "numVariant", "numVariant", python::no_init )
|
||||
.def("__init__", python::make_constructor(&NumVariantAdaptor::getVariant) )
|
||||
.def( "__eq__", &NumVariantAdaptor::eq )
|
||||
|
76
pykd/pytagged.cpp
Normal file
76
pykd/pytagged.cpp
Normal file
@ -0,0 +1,76 @@
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "pytagged.h"
|
||||
#include "kdlib\tagged.h"
|
||||
#include "kdlib\exceptions.h"
|
||||
|
||||
#include "pythreadstate.h"
|
||||
#include "stladaptor.h"
|
||||
|
||||
#include <rpc.h>
|
||||
#pragma comment(lib, "Rpcrt4.lib")
|
||||
|
||||
|
||||
namespace pykd {
|
||||
|
||||
|
||||
void __declspec(noreturn) throwRpcStatus( const std::string &functionName, RPC_STATUS status )
|
||||
{
|
||||
std::stringstream sstr;
|
||||
sstr << "Call " << functionName << " failed\n";
|
||||
sstr << "RPC_STATUS 0x" << std::hex << status;
|
||||
throw kdlib::DbgException( sstr.str() );
|
||||
}
|
||||
|
||||
python::list enumTagged()
|
||||
{
|
||||
std::list<kdlib::TaggedId> ids;
|
||||
{
|
||||
AutoRestorePyState pystate;
|
||||
ids = std::move( kdlib::enumTagged() );
|
||||
}
|
||||
|
||||
python::list result;
|
||||
|
||||
for (const auto &id : ids)
|
||||
{
|
||||
RPC_WSTR id_str = nullptr;
|
||||
auto status = ::UuidToString(&id, &id_str);
|
||||
if (RPC_S_OK != status)
|
||||
throwRpcStatus("UuidToString", status);
|
||||
|
||||
const auto stringFree =
|
||||
[](RPC_WSTR *str)
|
||||
{
|
||||
auto status = ::RpcStringFree(str);
|
||||
if (RPC_S_OK != status)
|
||||
throwRpcStatus("RpcStringFree", status);
|
||||
};
|
||||
std::unique_ptr<RPC_WSTR, decltype(stringFree)> freeGuard{&id_str, stringFree};
|
||||
|
||||
result.append( std::wstring(reinterpret_cast<wchar_t *>(id_str)) );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
python::list loadTaggedBuffer(const std::wstring &id_str)
|
||||
{
|
||||
const auto rcp_str =
|
||||
reinterpret_cast<RPC_WSTR>( const_cast<wchar_t *>(id_str.c_str()) );
|
||||
kdlib::TaggedId id;
|
||||
auto status = ::UuidFromString(rcp_str, &id);
|
||||
if (RPC_S_OK != status)
|
||||
throwRpcStatus("UuidFromString", status);
|
||||
|
||||
|
||||
kdlib::TaggedBuffer buff;
|
||||
{
|
||||
AutoRestorePyState pystate;
|
||||
buff = std::move( kdlib::loadTaggedBuffer(id) );
|
||||
}
|
||||
|
||||
return vectorToList(buff);
|
||||
}
|
||||
|
||||
} // namespace pykd
|
12
pykd/pytagged.h
Normal file
12
pykd/pytagged.h
Normal file
@ -0,0 +1,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace python = boost::python;
|
||||
|
||||
namespace pykd {
|
||||
|
||||
python::list enumTagged();
|
||||
|
||||
python::list loadTaggedBuffer(const std::wstring &id_str);
|
||||
|
||||
} // namespace pykd
|
@ -27,6 +27,7 @@ import excepttest
|
||||
import targetprocess
|
||||
import ehloadtest
|
||||
import synsymtest
|
||||
import taggedtest
|
||||
|
||||
pykd.initialize()
|
||||
|
||||
@ -65,6 +66,7 @@ def getTestSuite( singleName = "" ):
|
||||
unittest.TestLoader().loadTestsFromTestCase( mspdbtest.MsPdbTest ),
|
||||
unittest.TestLoader().loadTestsFromTestCase( targetprocess.ProcessTest ),
|
||||
unittest.TestLoader().loadTestsFromTestCase( ehloadtest.EhLoadTest ),
|
||||
unittest.TestLoader().loadTestsFromTestCase( taggedtest.TaggedTest ),
|
||||
|
||||
#unittest.TestLoader().loadTestsFromTestCase( excepttest.ExceptionTest ),
|
||||
] )
|
||||
|
@ -50,6 +50,7 @@
|
||||
<Compile Include="regtest.py" />
|
||||
<Compile Include="stacktest.py" />
|
||||
<Compile Include="synsymtest.py" />
|
||||
<Compile Include="taggedtest.py" />
|
||||
<Compile Include="target.py" />
|
||||
<Compile Include="targetprocess.py" />
|
||||
<Compile Include="testutils.py" />
|
||||
|
31
test/scripts/taggedtest.py
Normal file
31
test/scripts/taggedtest.py
Normal file
@ -0,0 +1,31 @@
|
||||
import unittest
|
||||
import pykd
|
||||
import sys
|
||||
import os
|
||||
|
||||
class TaggedTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
dump_file = os.path.join( os.path.dirname(sys.argv[0]),
|
||||
r"..\..\kdlibcpp\kdlib\tests\dumps\win8_x64_mem.cab" )
|
||||
self.dump_id = pykd.loadDump( dump_file )
|
||||
|
||||
self._existing_id = "D03DC06F-D88E-44C5-BA2A-FAE035172D19"
|
||||
self._non_existing_id = "88597A32-1493-41CA-BF87-2A950DF4CEE0"
|
||||
|
||||
def tearDown(self):
|
||||
pykd.closeDump( self.dump_id )
|
||||
|
||||
def testEnum(self):
|
||||
ids = pykd.enumTagged()
|
||||
|
||||
self.assertTrue( self._existing_id.lower() in [i.lower() for i in ids] )
|
||||
|
||||
self.assertFalse( self._non_existing_id.lower() in [i.lower() for i in ids] )
|
||||
|
||||
|
||||
def testLoadBuffer(self):
|
||||
buff = pykd.loadTaggedBuffer( self._existing_id )
|
||||
self.assertEqual( len(buff), 0x410 )
|
||||
|
||||
self.assertRaises( pykd.DbgException, pykd.loadTaggedBuffer, self._non_existing_id )
|
||||
|
Loading…
Reference in New Issue
Block a user