Commit 8b153f2c authored by SND\ussrhero_cp's avatar SND\ussrhero_cp Committed by Mikhail I. Izmestev
Browse files

added managed heap support

git-svn-id: https://kdlibcpp.svn.codeplex.com/svn@91251 9b283d60-5439-405e-af05-b73fd8c4d996
parent c786b433
#pragma once
#include <boost/smart_ptr.hpp>
namespace kdlib {
///////////////////////////////////////////////////////////////////////////////
class TargetHeap;
typedef boost::shared_ptr<TargetHeap> TargetHeapPtr;
///////////////////////////////////////////////////////////////////////////////
class TargetHeap
{
public:
virtual size_t getCount(const std::wstring& typeName=L"", size_t minSize = 0, size_t maxSize = -1) const = 0;
};
TargetHeapPtr getManagedHeap();
///////////////////////////////////////////////////////////////////////////////
}
......@@ -7,6 +7,7 @@
#include "kdlib/breakpoint.h"
#include "kdlib/stack.h"
#include "kdlib/variant.h"
#include "kdlib/heap.h"
namespace kdlib {
......@@ -89,6 +90,9 @@ public:
virtual unsigned long getNumberBreakpoints() = 0;
virtual BreakpointPtr getBreakpoint(unsigned long index) = 0;
virtual bool isManaged() = 0;
virtual TargetHeapPtr getManagedHeap() = 0;
};
///////////////////////////////////////////////////////////////////////////////
......
......@@ -46,8 +46,11 @@
<ClCompile Include="disasm.cpp" />
<ClCompile Include="memaccess.cpp" />
<ClCompile Include="module.cpp" />
<ClCompile Include="net\metadata.cpp" />
<ClCompile Include="net\net.cpp" />
<ClCompile Include="net\netheap.cpp" />
<ClCompile Include="net\netmodule.cpp" />
<ClCompile Include="net\nettype.cpp" />
<ClCompile Include="processmon.cpp" />
<ClCompile Include="stack.cpp" />
<ClCompile Include="stdafx.cpp">
......@@ -88,6 +91,7 @@
<ClInclude Include="..\include\kdlib\disasmengine.h" />
<ClInclude Include="..\include\kdlib\eventhandler.h" />
<ClInclude Include="..\include\kdlib\exceptions.h" />
<ClInclude Include="..\include\kdlib\heap.h" />
<ClInclude Include="..\include\kdlib\kdlib.h" />
<ClInclude Include="..\include\kdlib\memaccess.h" />
<ClInclude Include="..\include\kdlib\module.h" />
......@@ -104,9 +108,12 @@
<ClInclude Include="dia\diacallback.h" />
<ClInclude Include="dia\diawrapper.h" />
<ClInclude Include="moduleimp.h" />
<ClInclude Include="net\metadata.h" />
<ClInclude Include="net\net.h" />
<ClInclude Include="net\netheap.h" />
<ClInclude Include="net\netmodule.h" />
<ClInclude Include="net\xclrdata.h" />
<ClInclude Include="net\netobject.h" />
<ClInclude Include="net\nettype.h" />
<ClInclude Include="processmon.h" />
<ClInclude Include="stackimpl.h" />
<ClInclude Include="stdafx.h" />
......
......@@ -124,6 +124,15 @@
<ClCompile Include="net\netmodule.cpp">
<Filter>net</Filter>
</ClCompile>
<ClCompile Include="net\netheap.cpp">
<Filter>net</Filter>
</ClCompile>
<ClCompile Include="net\nettype.cpp">
<Filter>net</Filter>
</ClCompile>
<ClCompile Include="net\metadata.cpp">
<Filter>net</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h" />
......@@ -245,10 +254,22 @@
<ClInclude Include="net\net.h">
<Filter>net</Filter>
</ClInclude>
<ClInclude Include="net\xclrdata.h">
<ClInclude Include="net\netmodule.h">
<Filter>net</Filter>
</ClInclude>
<ClInclude Include="net\netmodule.h">
<ClInclude Include="net\netobject.h">
<Filter>net</Filter>
</ClInclude>
<ClInclude Include="..\include\kdlib\heap.h">
<Filter>kdlib/include</Filter>
</ClInclude>
<ClInclude Include="net\netheap.h">
<Filter>net</Filter>
</ClInclude>
<ClInclude Include="net\nettype.h">
<Filter>net</Filter>
</ClInclude>
<ClInclude Include="net\metadata.h">
<Filter>net</Filter>
</ClInclude>
</ItemGroup>
......
#include "stdafx.h"
#include <boost/make_shared.hpp>
#include <boost/regex.hpp>
#include <metahost.h>
#include "net/metadata.h"
#include "net/nettype.h"
///////////////////////////////////////////////////////////////////////////////
namespace {
///////////////////////////////////////////////////////////////////////////////
const boost::wregex r1(L"\\?");
const boost::wregex r2(L"\\*");
const boost::wregex r3(L"\\.");
bool fnmatch( const std::wstring& pattern, const std::wstring& str)
{
std::wstring mask = pattern;
mask = boost::regex_replace(mask, r1, L".");
mask = boost::regex_replace(mask, r2, L".*");
mask = boost::regex_replace(mask, r3, L"\\.");
boost::wsmatch matchResult;
boost::wregex regEx(mask);
return boost::regex_match(str, matchResult, regEx);
}
///////////////////////////////////////////////////////////////////////////////
}
namespace kdlib {
MetaDataProviderPtr getMetaDataProvider(ICorDebugModule* module)
{
return MetaDataProviderPtr( new MetaDataProvider(module) );
}
MetaDataProvider::MetaDataProvider(ICorDebugModule* module)
{
HRESULT hres = module->GetMetaDataInterface(IID_IMetaDataImport, (IUnknown**)&m_metaDataImport);
if (FAILED(hres))
throw DbgException("Failed ICorDebugModule::GetMetaDataInterface");
}
TypeInfoPtr MetaDataProvider::getTypeByToken(mdTypeDef typeDef)
{
return TypeInfoPtr( new NetTypeClass( shared_from_this(), getTypeNameByToken(typeDef), typeDef ) );
}
std::wstring MetaDataProvider::getTypeNameByToken(mdTypeDef typeDef)
{
std::vector<wchar_t> typeNameBuf(0x100);
ULONG typeNameLength;
DWORD typeDefFlags;
mdToken baseType;
HRESULT hres = m_metaDataImport->GetTypeDefProps(
typeDef,
&typeNameBuf.front(),
typeNameBuf.size(),
&typeNameLength,
&typeDefFlags,
&baseType );
if ( FAILED(hres) )
throw DbgException("Failed IMetaDataImport::GetTypeDefProps");
std::wstring typeName( &typeNameBuf.front());
if ( ( typeDefFlags & tdVisibilityMask ) > tdPublic )
{
// nested class
mdTypeDef encloseClass;
hres = m_metaDataImport->GetNestedClassProps(typeDef, &encloseClass);
if ( FAILED(hres) )
throw DbgException("Failed IMetaDataImport::GetNestedClassProps");
TypeInfoPtr encloseType = getTypeByToken(encloseClass);
typeName = encloseType->getName() + std::wstring(L".") + typeName;
}
return typeName;
}
TypeNameList MetaDataProvider::getTypeNames(const std::wstring& mask)
{
HCORENUM enumTypeDefs = NULL;
TypeNameList typeList;
auto enumCloseFn = [=](HCORENUM*){ if ( enumTypeDefs ) m_metaDataImport->CloseEnum(enumTypeDefs); };
std::unique_ptr<HCORENUM, decltype(enumCloseFn)> enumCloser(&enumTypeDefs, enumCloseFn);
while(true)
{
mdTypeDef typeDef;
ULONG fetched;
HRESULT hres = m_metaDataImport->EnumTypeDefs(&enumTypeDefs, &typeDef, 1, &fetched);
if ( FAILED(hres) )
throw DbgException("Failed IMetaDataImport::EnumTypeDefs");
if ( hres != S_OK )
break;
std::wstring typeName = getTypeNameByToken(typeDef);
if ( mask.empty() || fnmatch(mask, typeName) )
typeList.push_back(typeName);
}
return typeList;
}
}
#pragma once
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include "net/net.h"
#include <cor.h>
#include "kdlib/exceptions.h"
#include "kdlib/typeinfo.h"
#include "kdlib/module.h"
namespace kdlib {
///////////////////////////////////////////////////////////////////////////////
class MetaDataProvider;
typedef boost::shared_ptr<MetaDataProvider> MetaDataProviderPtr;
MetaDataProviderPtr getMetaDataProvider(ICorDebugModule* module);
class MetaDataProvider : public boost::enable_shared_from_this<MetaDataProvider>
{
friend MetaDataProviderPtr getMetaDataProvider(ICorDebugModule* module);
public:
TypeInfoPtr getTypeByToken(mdTypeDef typeDef);
TypeNameList getTypeNames(const std::wstring& mask);
std::wstring getTypeNameByToken(mdTypeDef typeDef);
private:
MetaDataProvider(ICorDebugModule* module);
CComPtr<IMetaDataImport> m_metaDataImport;
};
///////////////////////////////////////////////////////////////////////////////
}
This diff is collapsed.
#pragma once
#include <clrdata.h>
#include <CorHdr.h>
#include <CorDebug.h>
#include <ClrData.h>
#include <MetaHost.h>
#include <atlbase.h>
#include "xclrdata.h"
#include "kdlib/dbgtypedef.h"
//#include "kdlib/dbgtypedef.h"
#include "kdlib/typedvar.h"
namespace kdlib {
class CLRDataTarget : public ICLRDataTarget
class ClrDebugManager
{
public:
CLRDataTarget() : m_xclrDataProcess(0), m_mscordacMod(NULL)
{}
~CLRDataTarget();
IXCLRDataProcess* get();
private:
virtual ICorDebugProcess* targetProcess() = 0;
STDMETHOD_(ULONG, AddRef)() { return 1; }
virtual ~ClrDebugManager()
{}
ICorDebugProcess5* targetProcess5() {
return CComQIPtr<ICorDebugProcess5>( targetProcess() );
}
STDMETHOD_(ULONG, Release)() { return 1; }
static void init();
STDMETHOD(QueryInterface)(
_In_ REFIID InterfaceId,
_Out_ PVOID* Interface
)
{
*Interface = NULL;
static void deinit();
};
if ( IsEqualIID(InterfaceId, IID_IUnknown) || IsEqualIID(InterfaceId, __uuidof(ICLRDataTarget)) )
{
AddRef();
*Interface = this;
return S_OK;
}
*Interface = NULL;
extern ClrDebugManager* g_netMgr;
return E_NOINTERFACE;
}
}
STDMETHOD(GetMachineType)(
/* [out] */ ULONG32 *machineType
);
STDMETHOD (GetPointerSize)(
/* [out] */ ULONG32 *pointerSize
);
STDMETHOD (GetImageBase)(
/* [string][in] */ LPCWSTR imagePath,
/* [out] */ CLRDATA_ADDRESS *baseAddress
);
STDMETHOD (ReadVirtual)(
/* [in] */ CLRDATA_ADDRESS address,
/* [length_is][size_is][out] */ BYTE *buffer,
/* [in] */ ULONG32 bytesRequested,
/* [out] */ ULONG32 *bytesRead
);
STDMETHOD (WriteVirtual)(
/* [in] */ CLRDATA_ADDRESS address,
/* [size_is][in] */ BYTE *buffer,
/* [in] */ ULONG32 bytesRequested,
/* [out] */ ULONG32 *bytesWritten
)
{
return E_NOTIMPL;
}
STDMETHOD (GetTLSValue)(
/* [in] */ ULONG32 threadID,
/* [in] */ ULONG32 index,
/* [out] */ CLRDATA_ADDRESS *value
)
{
return E_NOTIMPL;
}
STDMETHOD (SetTLSValue)(
/* [in] */ ULONG32 threadID,
/* [in] */ ULONG32 index,
/* [in] */ CLRDATA_ADDRESS value
)
{
return E_NOTIMPL;
}
STDMETHOD (GetCurrentThreadID)(
/* [out] */ ULONG32 *threadID
)
{
return E_NOTIMPL;
}
STDMETHOD (GetThreadContext)(
/* [in] */ ULONG32 threadID,
/* [in] */ ULONG32 contextFlags,
/* [in] */ ULONG32 contextSize,
/* [size_is][out] */ BYTE *context
)
{
return E_NOTIMPL;
}
STDMETHOD (SetThreadContext)(
/* [in] */ ULONG32 threadID,
/* [in] */ ULONG32 contextSize,
/* [size_is][in] */ BYTE *context
)
{
return E_NOTIMPL;
}
STDMETHOD (Request)(
/* [in] */ ULONG32 reqCode,
/* [in] */ ULONG32 inBufferSize,
/* [size_is][in] */ BYTE *inBuffer,
/* [in] */ ULONG32 outBufferSize,
/* [size_is][out] */ BYTE *outBuffer
)
{
return E_NOTIMPL;
}
private:
IXCLRDataProcess* m_xclrDataProcess;
HMODULE m_mscordacMod;
};
extern CLRDataTarget g_clrDataTarget;
template<typename T>
HRESULT clrGetName(T* obj, std::wstring& name)
{
name.clear();
ULONG32 bufferLength = 0x100;
std::vector<WCHAR> buf(bufferLength);
ULONG32 nameLen = 0;
HRESULT hres = obj->GetName(0, bufferLength, &bufferLength, &buf.front() );
if ( hres == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) )
{
buf.resize(bufferLength);
hres = obj->GetName(0, bufferLength, &bufferLength, &buf.front() );
}
if (FAILED(hres))
return hres;
name = std::wstring(&buf.front());
return S_OK;
}
///*
//class CLRDataTarget : public ICLRDataTarget
//{
//
//public:
//
// CLRDataTarget() : m_xclrDataProcess(0), m_mscordacMod(NULL)
// {}
//
// ~CLRDataTarget();
//
// IXCLRDataProcess* get();
//
//private:
//
// STDMETHOD_(ULONG, AddRef)() { return 1; }
//
// STDMETHOD_(ULONG, Release)() { return 1; }
//
// STDMETHOD(QueryInterface)(
// _In_ REFIID InterfaceId,
// _Out_ PVOID* Interface
// )
// {
// *Interface = NULL;
//
// if ( IsEqualIID(InterfaceId, IID_IUnknown) || IsEqualIID(InterfaceId, __uuidof(ICLRDataTarget)) )
// {
// AddRef();
// *Interface = this;
// return S_OK;
// }
//
// *Interface = NULL;
//
// return E_NOINTERFACE;
// }
//
// STDMETHOD(GetMachineType)(
// /* [out] */ ULONG32 *machineType
// );
//
// STDMETHOD (GetPointerSize)(
// /* [out] */ ULONG32 *pointerSize
// );
//
// STDMETHOD (GetImageBase)(
// /* [string][in] */ LPCWSTR imagePath,
// /* [out] */ CLRDATA_ADDRESS *baseAddress
// );
//
// STDMETHOD (ReadVirtual)(
// /* [in] */ CLRDATA_ADDRESS address,
// /* [length_is][size_is][out] */ BYTE *buffer,
// /* [in] */ ULONG32 bytesRequested,
// /* [out] */ ULONG32 *bytesRead
// );
//
// STDMETHOD (WriteVirtual)(
// /* [in] */ CLRDATA_ADDRESS address,
// /* [size_is][in] */ BYTE *buffer,
// /* [in] */ ULONG32 bytesRequested,
// /* [out] */ ULONG32 *bytesWritten
// )
// {
// return E_NOTIMPL;
// }
//
// STDMETHOD (GetTLSValue)(
// /* [in] */ ULONG32 threadID,
// /* [in] */ ULONG32 index,
// /* [out] */ CLRDATA_ADDRESS *value
// )
// {
// return E_NOTIMPL;
// }
//
// STDMETHOD (SetTLSValue)(
// /* [in] */ ULONG32 threadID,
// /* [in] */ ULONG32 index,
// /* [in] */ CLRDATA_ADDRESS value
// )
// {
// return E_NOTIMPL;
// }
//
// STDMETHOD (GetCurrentThreadID)(
// /* [out] */ ULONG32 *threadID
// )
// {
// return E_NOTIMPL;
// }
//
// STDMETHOD (GetThreadContext)(
// /* [in] */ ULONG32 threadID,
// /* [in] */ ULONG32 contextFlags,
// /* [in] */ ULONG32 contextSize,
// /* [size_is][out] */ BYTE *context
// )
// {
// return E_NOTIMPL;
// }
//
// STDMETHOD (SetThreadContext)(
// /* [in] */ ULONG32 threadID,
// /* [in] */ ULONG32 contextSize,
// /* [size_is][in] */ BYTE *context
// )
// {
// return E_NOTIMPL;
// }
//
// STDMETHOD (Request)(
// /* [in] */ ULONG32 reqCode,
// /* [in] */ ULONG32 inBufferSize,
// /* [size_is][in] */ BYTE *inBuffer,
// /* [in] */ ULONG32 outBufferSize,
// /* [size_is][out] */ BYTE *outBuffer
// )
// {
// return E_NOTIMPL;
// }
//
//private:
//
// IXCLRDataProcess* m_xclrDataProcess;
//
// HMODULE m_mscordacMod;
//};
//
//extern CLRDataTarget g_clrDataTarget;
//
//
//template <typename T>
//HRESULT clrGetName(
// T* obj,
// HRESULT(STDMETHODCALLTYPE T::*method)( ULONG32, ULONG32, ULONG32*, WCHAR[]),
// std::wstring & name,
// ULONG32 flags = 0
// )
//{
// name.clear();
//
// ULONG32 bufferLength = 0x100;
// std::vector<WCHAR> buf(bufferLength);
// ULONG32 nameLen = 0;