Commit 04cfb35a authored by SND\ussrhero_cp's avatar SND\ussrhero_cp Committed by Mikhail I. Izmestev

getting string value

git-svn-id: https://kdlibcpp.svn.codeplex.com/svn@91255 9b283d60-5439-405e-af05-b73fd8c4d996
parent 2b4fa087
......@@ -114,6 +114,9 @@ public:
virtual TypeInfoPtr getType() const = 0;
virtual NumVariant getValue() const = 0;
virtual void setValue(const NumVariant& value) = 0;
virtual std::wstring getStrValue() const = 0;
virtual void setStrValue(const std::wstring& value) = 0;
virtual std::wstring printValue() const = 0;
virtual TypedVarPtr deref() = 0;
virtual TypedVarPtr castTo(const std::wstring& typeName) const = 0;
virtual TypedVarPtr castTo(const TypeInfoPtr &typeInfo) const = 0;
......
......@@ -213,6 +213,8 @@ std::wstring MetaDataProvider::getTypeNameByToken(mdTypeDef typeDef)
DWORD typeDefFlags;
mdToken baseType;
BOOL validToken = m_metaDataImport->IsValidToken (typeDef);
HRESULT hres = m_metaDataImport->GetTypeDefProps(
typeDef,
&typeNameBuf.front(),
......@@ -298,9 +300,6 @@ void MetaDataProvider::getFields(mdTypeDef typeDef, NetFieldList& fields)
ULONG fetched;
HRESULT hres = m_metaDataImport->EnumFields(&enumFieldDefs, typeDef, &fieldDef, 1, &fetched);
if ( FAILED(hres) )
throw DbgException("Failed IMetaDataImport::EnumTypeDefs");
if ( hres != S_OK )
break;
......
......@@ -47,8 +47,6 @@ public:
void getFields(mdTypeDef typeDef, NetFieldList& fields);
private:
MetaDataProvider(ICorDebugModule* module);
......
This diff is collapsed.
......@@ -2,10 +2,12 @@
#include "kdlib/heap.h"
#include <map>
#include <atlbase.h>
#include "net.h"
#include "net/metadata.h"
#include "kdlib/typedvar.h"
#include "kdlib/exceptions.h"
......@@ -129,6 +131,18 @@ protected:
throw TypeException(L"Not applicable for managed objects");
}
virtual std::wstring getStrValue() const {
throw TypeException(L"Not applicable for managed objects");
}
virtual void setStrValue(const std::wstring& value) {
throw TypeException(L"Not applicable for managed objects");
}
virtual std::wstring printValue() const {
throw TypeException(L"Not applicable for managed objects");
}
virtual TypedVarPtr deref() {
throw TypeException(L"Not applicable for managed objects");
}
......@@ -161,55 +175,130 @@ protected:
///////////////////////////////////////////////////////////////////////////////
struct FieldDesc
{
std::wstring name;
mdFieldDef token;
CComPtr<ICorDebugClass> debugClass;
};
typedef std::vector< FieldDesc > FieldsList;
class NetObjectClass : public NetObject
{
public:
NetObjectClass( const TypeInfoPtr& typeInfo, const DataAccessorPtr &dataSource ) :
m_typeInfo(typeInfo),
m_dataAccessor(dataSource)
{}
NetObjectClass(ICorDebugObjectValue* objectValue);
public:
virtual TypedVarPtr getElement( const std::wstring& fieldName );
virtual MEMOFFSET_64 getAddress() const {
return m_address;
}
virtual std::wstring printValue() const {
return L"Class";
}
virtual std::wstring str();
private:
TypeInfoPtr m_typeInfo;
CComPtr<ICorDebugObjectValue> m_objectValue;
CComPtr<ICorDebugType> m_objectType;
std::map<std::wstring, FieldDesc> m_fieldCache;
FieldsList m_fields;
MetaDataProviderPtr m_metaDataProvder;
MEMOFFSET_64 m_address;
FieldsList getFieldsByType(ICorDebugType* corType);
};
///////////////////////////////////////////////////////////////////////////////
class NetObjectString : public NetObject
{
public:
NetObjectString(ICorDebugStringValue* strValue) :
m_strValue(strValue)
{}
virtual std::wstring getStrValue() const;
virtual MEMOFFSET_64 getAddress() const;
virtual std::wstring printValue() const;
DataAccessorPtr m_dataAccessor;
private:
CComPtr<ICorDebugStringValue> m_strValue;
};
///////////////////////////////////////////////////////////////////////////////
class NetObjectArray : public NetObject
{
public:
NetObjectArray(const TypeInfoPtr& typeInfo, MEMOFFSET_64 addr, const COR_ARRAY_LAYOUT& arrayLayout, std::vector<size_t> indices ={});
NetObjectArray(ICorDebugArrayValue* arrayValue, std::vector<ULONG32> indices ={} );
private:
virtual TypedVarPtr getElement( size_t index );
virtual size_t getElementCount();
virtual MEMOFFSET_64 getAddress() const;
virtual std::wstring printValue() const {
return L"Array";
}
private:
TypeInfoPtr m_typeInfo;
CComPtr<ICorDebugArrayValue> m_arrayValue;
MEMOFFSET_64 m_arrayObjAddr;
std::vector<ULONG32> m_indices;
DataAccessorPtr m_dataAccessor;
std::vector<ULONG32> m_dimensions;
COR_ARRAY_LAYOUT m_arrayLayout;
ULONG32 m_elementCount;
};
///////////////////////////////////////////////////////////////////////////////
class NetObjectEnum : public NetObject
{
public:
NetObjectEnum(ICorDebugObjectValue* value) :
m_enumValue(value)
{}
private:
virtual NumVariant getValue() const;
size_t m_elementCount;
virtual MEMOFFSET_64 getAddress() const;
size_t m_elementSize;
virtual std::wstring printValue() const {
return L"Enum";
}
private:
std::vector<size_t> m_ranks;
CComPtr<ICorDebugObjectValue> m_enumValue;
std::vector<size_t> m_indices;
};
///////////////////////////////////////////////////////////////////////////////
......
......@@ -139,13 +139,6 @@ size_t NetTypeClass::getSize()
///////////////////////////////////////////////////////////////////////////////
TypedVarPtr NetTypeClass::getVar(const DataAccessorPtr &dataSource)
{
return TypedVarPtr( new NetObjectClass(shared_from_this(), dataSource) );
}
///////////////////////////////////////////////////////////////////////////////
void NetTypeClass::getFields()
{
COR_TYPE_LAYOUT typeLayout;
......@@ -284,13 +277,4 @@ TypeInfoPtr NetTypeArray::getElementType()
///////////////////////////////////////////////////////////////////////////////
TypedVarPtr NetTypeArray::getVar(const DataAccessorPtr &dataSource)
{
MEMOFFSET_64 addr = ptrSize() == 4 ? dataSource->readDWord() : dataSource->readQWord();
return TypedVarPtr( new NetObjectArray(shared_from_this(), addr, m_arrayLayout) );
}
///////////////////////////////////////////////////////////////////////////////
}
......@@ -12,6 +12,7 @@
namespace kdlib {
///////////////////////////////////////////////////////////////////////////////
TypeInfoPtr getNetTypeById(COR_TYPEID typeId);
......@@ -298,36 +299,6 @@ private:
///////////////////////////////////////////////////////////////////////////////
//class NetTypeFieldRef : public NetTypeInfoBase
//{
//public:
//
// NetTypeFieldRef(const TypeInfoPtr& derefType) :
// m_derefType(derefType)
// {}
//
// virtual size_t getSize() {
// return ptrSize();
// }
//
// virtual std::wstring getName() {
// return m_derefType->getName();
// }
//
// virtual TypedVarPtr getVar(const DataAccessorPtr &dataSource)
// {
// MEMOFFSET_64 addr = ptrSize() == 4 ? dataSource->readDWord() : dataSource->readQWord();
// size_t size = m_derefType->getSize();
//
// }
//
//private:
//
// TypeInfoPtr m_derefType;
//};
///////////////////////////////////////////////////////////////////////////////
class NetTypeClass : public TypeInfoFields
{
public:
......@@ -344,8 +315,6 @@ public:
virtual size_t getSize();
virtual TypedVarPtr getVar(const DataAccessorPtr &dataSource);
private:
NetTypeClass(COR_TYPEID& typeId, MetaDataProviderPtr& metaProvider, const std::wstring& name, mdTypeDef token) :
......@@ -366,34 +335,6 @@ private:
///////////////////////////////////////////////////////////////////////////////
//class NetTypeBase : public NetTypeInfoBase
//{
//public:
//
// NetTypeBase(CorElementType baseType) :
// m_baseType(baseType)
// {}
//
//private:
//
// bool isBase() {
// return true;
// }
//
// std::wstring getName();
//
// virtual TypedVarPtr getVar(const DataAccessorPtr &dataSource)
// {
// NOT_IMPLEMENTED();
// }
//
//private:
//
// CorElementType m_baseType;
//};
///////////////////////////////////////////////////////////////////////////////
class NetTypeArray : public NetTypeInfoBase
{
......@@ -418,7 +359,6 @@ public:
return ptrSize();
}
virtual TypedVarPtr getVar(const DataAccessorPtr &dataSource);
private:
......@@ -426,32 +366,6 @@ private:
TypeInfoPtr getElementType();
//public:
//
// NetTypeArray(const TypeInfoPtr& derefType) :
// m_derefType(derefType)
// {}
//
//public:
//
// virtual std::wstring getName() {
// return m_derefType->getName() + L"[]";
// }
//
// virtual bool isArray()
// {
// return true;
// }
//
// virtual TypedVarPtr getVar(const DataAccessorPtr &dataSource)
// {
// NOT_IMPLEMENTED();
// }
//
//
//private:
//
// TypeInfoPtr m_derefType;
};
///////////////////////////////////////////////////////////////////////////////
......
......@@ -19,6 +19,7 @@ protected:
NOT_IMPLEMENTED();
}
virtual NumVariant getValue() const
{
NOT_IMPLEMENTED();
......@@ -29,6 +30,21 @@ protected:
throw TypeException( m_typeInfo->getName(), L" failed to set value");
}
virtual std::wstring getStrValue() const
{
NOT_IMPLEMENTED();
}
virtual void setStrValue(const std::wstring& value)
{
NOT_IMPLEMENTED();
}
virtual std::wstring printValue() const
{
NOT_IMPLEMENTED();
}
virtual VarStorage getStorage() const
{
return m_varData->getStorageType();
......@@ -210,6 +226,7 @@ protected:
virtual void setValue(const NumVariant& value);
virtual std::wstring str();
};
......@@ -486,6 +503,21 @@ public:
throw TypeException(L"Not applicable for Void");
}
virtual std::wstring getStrValue() const
{
throw TypeException(L"Not applicable for Void");
}
virtual void setStrValue(const std::wstring& value)
{
throw TypeException(L"Not applicable for Void");
}
virtual std::wstring printValue() const
{
throw TypeException(L"Not applicable for Void");
}
virtual VarStorage getStorage() const
{
throw TypeException(L"Not applicable for Void");
......
......@@ -191,11 +191,19 @@ public:
m_systemId = getCurrentSystemId();
}
TargetProcessImpl(PROCESS_DEBUG_ID processId)
TargetProcessImpl(PROCESS_DEBUG_ID processId)
{
kdlib::checkProcessById(processId);
m_processId = processId;
m_systemId = getCurrentSystemId();
if ( processId == -1 )
{
m_processId = getCurrentProcessId();
m_systemId = getCurrentSystemId();
}
else
{
kdlib::checkProcessById(processId);
m_processId = processId;
m_systemId = getCurrentSystemId();
}
}
virtual ~TargetProcessImpl()
......@@ -499,13 +507,23 @@ public:
TargetThreadImpl(THREAD_DEBUG_ID id)
{
kdlib::checkThreadById(id);
m_threadId = id;
m_processId = getCurrentProcessId();
m_systemId = getCurrentSystemId();
if ( id == -1 )
{
m_threadId = getCurrentThreadId();
m_processId = getCurrentProcessId();
m_systemId = getCurrentSystemId();
}
else
{
kdlib::checkThreadById(id);
m_threadId = id;
m_processId = getCurrentProcessId();
m_systemId = getCurrentSystemId();
}
}
TargetThreadImpl() {
TargetThreadImpl()
{
m_threadId = getCurrentThreadId();
m_processId = getCurrentProcessId();
m_systemId = getCurrentSystemId();
......
......@@ -5,10 +5,10 @@
<ClCompile Include="kdlibtest.cpp" />
<ClCompile Include="stdafx.cpp" />
<ClCompile Include="..\comdate\testvars.cpp">
<Filter>testcases\testdata</Filter>
<Filter>testdata</Filter>
</ClCompile>
<ClCompile Include="..\comdate\testfunc.cpp">
<Filter>testcases\testdata</Filter>
<Filter>testdata</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
......@@ -30,7 +30,7 @@
<Filter>testcases</Filter>
</ClInclude>
<ClInclude Include="..\..\include\test\testvars.h">
<Filter>testcases\testdata</Filter>
<Filter>testdata</Filter>
</ClInclude>
<ClInclude Include="processtest.h">
<Filter>testcases</Filter>
......@@ -92,7 +92,7 @@
<Filter Include="testfixtures">
<UniqueIdentifier>{f2d12c59-7d69-4aa8-baa8-dc68e1e3b881}</UniqueIdentifier>
</Filter>
<Filter Include="testcases\testdata">
<Filter Include="testdata">
<UniqueIdentifier>{617ec5ef-8b76-49d2-b598-1ffc78b37637}</UniqueIdentifier>
</Filter>
</ItemGroup>
......
#pragma once
#include "procfixture.h"
#include "kdlib/heap.h"
class NetTest : public NetProcessFixture
{
};
TEST_F(NetTest, ProcessIsManaged)
{
EXPECT_TRUE(TargetProcess::getCurrent()->isManaged());
}
TEST_F(NetTest, NetModuleIsManaged)
{
EXPECT_TRUE(m_targetModule->isManaged());
EXPECT_FALSE( loadModule(L"ntdll")->isManaged());
}
TEST_F(NetTest, NetHeap)
{
kdlib::TargetHeapPtr targetHeap;
ASSERT_NO_THROW(targetHeap = TargetProcess::getCurrent()->getManagedHeap());
EXPECT_LT(0, targetHeap->getCount() );
EXPECT_LT(0, targetHeap->getCount(L"managedapp*") );
kdlib::TargetHeapEnumPtr heapEnum;
ASSERT_NO_THROW(heapEnum = targetHeap->getEnum(L"managedapp*"));
std::wstring typeName;
size_t size;
MEMOFFSET_64 address;
EXPECT_TRUE( heapEnum->Next(address, typeName, size) );
}
//TEST_F(NetTest, NetModuleEnumTypes)
//{
// EXPECT_EQ(
// TypeNameList( { L"managedapp.Class1",
// L"managedapp.Class1.Nested",
// L"managedapp.Program" } ),
// m_targetModule->enumTypes() );
//
// EXPECT_EQ(
// TypeNameList( { L"managedapp.Class1",
// L"managedapp.Class1.Nested" } ),
// m_targetModule->enumTypes(L"*Class1*") );
//
//}
//
//TEST_F(NetTest, ClassField)
//{
// TypeInfoPtr classBase;
//
// ASSERT_NO_THROW( classBase = m_targetModule->getTypeByName(L"managedapp.TestClass") );
//
// std::wstring desc;
// EXPECT_NO_THROW( desc = classBase->str() );
//}
template <typename T>
class NetTestObj : public T
{
protected:
virtual void SetUp()
{
T::SetUp();
kdlib::TargetHeapPtr targetHeap;
ASSERT_NO_THROW(targetHeap = TargetProcess::getCurrent()->getManagedHeap());
kdlib::TargetHeapEnumPtr heapEnum;
ASSERT_NO_THROW(heapEnum = targetHeap->getEnum(L"managedapp.TestClass"));
std::wstring typeName;
size_t size;
MEMOFFSET_64 address;
ASSERT_TRUE( heapEnum->Next(address, typeName, size) );
ASSERT_NO_THROW( m_testClassVar = TargetProcess::getCurrent()->getManagedVar(address) );
}
virtual void TearDown()
{
T::TearDown();
}
kdlib::TypedVarPtr m_testClassVar;
};
typedef ::testing::Types<NetProcessFixture, NetDumpFixture> NetTargetTypes;
TYPED_TEST_CASE(NetTestObj, NetTargetTypes);
TYPED_TEST(NetTestObj, BaseField)
{
EXPECT_EQ( 'a', *m_testClassVar->getElement(L"charField") );
EXPECT_EQ( 3456, *m_testClassVar->getElement(L"shortField") );
}
TYPED_TEST(NetTestObj, HeapVarArray)
{
EXPECT_EQ( 4, m_testClassVar->getElement(L"intArray")->getElementCount() );
EXPECT_EQ (8888, *m_testClassVar->getElement(L"intArray")->getElement(3) );
}
TYPED_TEST(NetTestObj, HeapVarMultiSizeArray)
{
EXPECT_EQ( 2, m_testClassVar->getElement(L"floatArray")->getElementCount() );
EXPECT_FLOAT_EQ(0.3f, *m_testClassVar->getElement(L"floatArray")->getElement(0)->getElement(1)->getElement(0) );
}
TYPED_TEST(NetTestObj, HeapVarString)
{
EXPECT_EQ(L"Hello", m_testClassVar->getElement(L"strField")->getStrValue());
}
TYPED_TEST(NetTestObj, HeapVarClass)
{
EXPECT_EQ(-555, *m_testClassVar->getElement(L"class1Field")->getElement(L"Field1"));
}
TYPED_TEST(NetTestObj, HeapFieldEnum)
{
EXPECT_EQ(4, *m_testClassVar->getElement(L"daysField"));
}
TYPED_TEST(NetTestObj, Str)
{
std::wstring str;
EXPECT_NO_THROW(str = m_testClassVar->str() );
}
TYPED_TEST(NetTestObj, InheritedField)
{
EXPECT_EQ( 0xAABBCCDD, *m_testClassVar->getElement(L"longField") );
}
......@@ -82,6 +82,35 @@ protected:
std::wstring m_cmdLine;
};
class NetDumpFixture : public ::testing::Test
{
protected:
virtual void SetUp()
{
ASSERT_NO_THROW( kdlib::startProcess(L"managedapp.exe"));
ASSERT_NO_THROW( kdlib::targetGo(); ); // go to work break point
ASSERT_NO_THROW( kdlib::writeDump(L"managedapp.dmp", false) );
ASSERT_NO_THROW( kdlib::terminateProcess() );
ASSERT_NO_THROW( kdlib::loadDump(L"managedapp.dmp") );
ASSERT_NO_THROW( m_targetModule = kdlib::loadModule( L"managedapp" ) );
}
virtual void TearDown()
{
ASSERT_NO_THROW( kdlib::closeDump() );
}
kdlib::PROCESS_DEBUG_ID m_processId;
kdlib::ModulePtr m_targetModule;
};
#ifndef FIELD_OFFSET
#define FIELD_OFFSET(type, field) ((long)&(((type *)0)->field))
#endif
......
......@@ -8,10 +8,17 @@ using System.Diagnostics;
namespace managedapp
{
enum Days { Sat, Sun, Mon, Tue, Wed, Thu, Fri };
class Class1
{
private int Field1;
public Class1()
{
Field1 = -555;
}
public class Nested
{
public Nested()
......@@ -22,12 +29,26 @@ namespace managedapp
}
}
class TestClass
class TestClassBase
{
public long longField;
public int intField;
public TestClassBase()
{
longField = 0xAABBCCDD;
}
}
class TestClass : TestClassBase
{
private char charField;
private short shortField;
private int[] intArray;
private float[, ,] floatArray;
private string strField;
private Days daysField;
public Class1 class1Field;
......@@ -37,6 +58,9 @@ namespace managedapp
shortField = 3456;
intArray = new int[4] { 1, 128, -555, 8888 };
floatArray = new float[2, 2, 2] { { { 0.1f, 0.2f }, {