Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Au <andrewau@microsoft.com>2017-06-15 21:07:48 +0300
committerAndrew Au <andrewau@microsoft.com>2017-06-15 21:07:48 +0300
commit34b00937c6c83185d3f3512df2b71d777263f3b4 (patch)
tree5e4c9b86627266158e0c9bc66afb934f1c3bcd99
parent3805f6558511e79f9367723147f1aeff1be4cc20 (diff)
Debugger Support
[tfs-changeset: 1661846]
-rw-r--r--src/Native/Runtime/Debug.h9
-rw-r--r--src/Native/Runtime/DebuggerHook.cpp64
-rw-r--r--src/Native/Runtime/DebuggerHook.h13
-rw-r--r--src/Native/Runtime/gcrhenv.cpp5
-rw-r--r--src/Native/Runtime/gcrhinterface.h3
-rw-r--r--src/Native/Runtime/gcrhscan.cpp2
6 files changed, 70 insertions, 26 deletions
diff --git a/src/Native/Runtime/Debug.h b/src/Native/Runtime/Debug.h
index 685298504..48156fc19 100644
--- a/src/Native/Runtime/Debug.h
+++ b/src/Native/Runtime/Debug.h
@@ -14,7 +14,8 @@ enum DebuggerGcProtectionRequestKind : uint16_t
{
EnsureConservativeReporting = 1,
RemoveConservativeReporting = 2,
- RemoveHandle = 3
+ EnsureHandle = 3,
+ RemoveHandle = 4
};
struct GcProtectionMessage
@@ -27,7 +28,11 @@ struct GcProtectionMessage
struct GcProtectionRequest
{
DebuggerGcProtectionRequestKind kind;
- uint16_t size;
+ union
+ {
+ uint16_t size;
+ uint16_t type;
+ };
uint32_t identifier;
uint64_t address;
};
diff --git a/src/Native/Runtime/DebuggerHook.cpp b/src/Native/Runtime/DebuggerHook.cpp
index dafa56b4b..5c0708c41 100644
--- a/src/Native/Runtime/DebuggerHook.cpp
+++ b/src/Native/Runtime/DebuggerHook.cpp
@@ -10,14 +10,13 @@
#include "DebuggerHook.h"
#include "DebugEventSource.h"
-
GVAL_IMPL_INIT(UInt32, g_numGcProtectionRequests, 0);
#ifndef DACCESS_COMPILE
-/* static */ DebuggerProtectedBufferList* DebuggerHook::s_debuggerProtectedBuffers = nullptr;
+/* static */ DebuggerProtectedBufferListNode* DebuggerHook::s_debuggerProtectedBuffers = nullptr;
-/* static */ DebuggerOwnedHandleList* DebuggerHook::s_debuggerOwnedHandleList = nullptr;
+/* static */ DebuggerOwnedHandleListNode* DebuggerHook::s_debuggerOwnedHandles = nullptr;
/* static */ UInt32 DebuggerHook::s_debuggeeInitiatedHandleIdentifier = 2;
@@ -67,6 +66,10 @@ GVAL_IMPL_INIT(UInt32, g_numGcProtectionRequests, 0);
{
RemoveConservativeReporting(requests + i);
}
+ else if (requests[i].kind == DebuggerGcProtectionRequestKind::EnsureHandle)
+ {
+ EnsureHandle(requests + i);
+ }
else if (requests[i].kind == DebuggerGcProtectionRequestKind::RemoveHandle)
{
RemoveHandle(requests + i);
@@ -79,7 +82,7 @@ GVAL_IMPL_INIT(UInt32, g_numGcProtectionRequests, 0);
/* static */ UInt32 DebuggerHook::RecordDebuggeeInitiatedHandle(void* objectHandle)
{
- DebuggerOwnedHandleList* head = new (nothrow) DebuggerOwnedHandleList();
+ DebuggerOwnedHandleListNode* head = new (nothrow) DebuggerOwnedHandleListNode();
if (head == nullptr)
{
return 0;
@@ -87,8 +90,8 @@ GVAL_IMPL_INIT(UInt32, g_numGcProtectionRequests, 0);
head->handle = objectHandle;
head->identifier = DebuggerHook::s_debuggeeInitiatedHandleIdentifier;
- head->next = s_debuggerOwnedHandleList;
- s_debuggerOwnedHandleList = head;
+ head->next = s_debuggerOwnedHandles;
+ s_debuggerOwnedHandles = head;
s_debuggeeInitiatedHandleIdentifier += 2;
@@ -97,10 +100,11 @@ GVAL_IMPL_INIT(UInt32, g_numGcProtectionRequests, 0);
/* static */ void DebuggerHook::EnsureConservativeReporting(GcProtectionRequest* request)
{
- DebuggerProtectedBufferList* tail = DebuggerHook::s_debuggerProtectedBuffers;
- s_debuggerProtectedBuffers = new (std::nothrow) DebuggerProtectedBufferList();
+ DebuggerProtectedBufferListNode* tail = DebuggerHook::s_debuggerProtectedBuffers;
+ s_debuggerProtectedBuffers = new (std::nothrow) DebuggerProtectedBufferListNode();
if (s_debuggerProtectedBuffers == nullptr)
{
+ s_debuggerProtectedBuffers = tail;
// TODO, FuncEval, we cannot handle the debugger request to protect a buffer (we have to break our promise)
// TODO, FuncEval, we need to figure out how to communicate this broken promise to the debugger
}
@@ -115,8 +119,8 @@ GVAL_IMPL_INIT(UInt32, g_numGcProtectionRequests, 0);
/* static */ void DebuggerHook::RemoveConservativeReporting(GcProtectionRequest* request)
{
- DebuggerProtectedBufferList* prev = nullptr;
- DebuggerProtectedBufferList* curr = DebuggerHook::s_debuggerProtectedBuffers;
+ DebuggerProtectedBufferListNode* prev = nullptr;
+ DebuggerProtectedBufferListNode* curr = DebuggerHook::s_debuggerProtectedBuffers;
while (true)
{
if (curr == nullptr)
@@ -126,7 +130,7 @@ GVAL_IMPL_INIT(UInt32, g_numGcProtectionRequests, 0);
}
if (curr->identifier == request->identifier)
{
- DebuggerProtectedBufferList* toDelete = curr;
+ DebuggerProtectedBufferListNode* toDelete = curr;
if (prev == nullptr)
{
// We are trying to remove the head of the linked list
@@ -148,10 +152,38 @@ GVAL_IMPL_INIT(UInt32, g_numGcProtectionRequests, 0);
}
}
+/* static */ void DebuggerHook::EnsureHandle(GcProtectionRequest* request)
+{
+ DebuggerOwnedHandleListNode* tail = DebuggerHook::s_debuggerOwnedHandles;
+ s_debuggerOwnedHandles = new (std::nothrow) DebuggerOwnedHandleListNode();
+ if (s_debuggerOwnedHandles == nullptr)
+ {
+ s_debuggerOwnedHandles = tail;
+ // TODO, FuncEval, we cannot handle the debugger request to protect a buffer (we have to break our promise)
+ // TODO, FuncEval, we need to figure out how to communicate this broken promise to the debugger
+ }
+ else
+ {
+ int handleType;
+ switch (request->type)
+ {
+ case 1: handleType = 2 /* == HNDTYPE_STRONG */; break;
+ case 2: handleType = 1 /* == HNDTYPE_WEAK_LONG */; break;
+ default:
+ assert("Debugger is passing in a wrong handle type" && false);
+ handleType = 2 /* == HNDTYPE_STRONG */;
+ }
+ void* handle = RedhawkGCInterface::CreateTypedHandle((void*)request->address, handleType);
+ s_debuggerOwnedHandles->handle = handle;
+ s_debuggerOwnedHandles->identifier = request->identifier;
+ s_debuggerOwnedHandles->next = tail;
+ }
+}
+
/* static */ void DebuggerHook::RemoveHandle(GcProtectionRequest* request)
{
- DebuggerOwnedHandleList* prev = nullptr;
- DebuggerOwnedHandleList* curr = DebuggerHook::s_debuggerOwnedHandleList;
+ DebuggerOwnedHandleListNode* prev = nullptr;
+ DebuggerOwnedHandleListNode* curr = DebuggerHook::s_debuggerOwnedHandles;
while (true)
{
if (curr == nullptr)
@@ -161,13 +193,13 @@ GVAL_IMPL_INIT(UInt32, g_numGcProtectionRequests, 0);
}
if (curr->identifier == request->identifier)
{
- DebuggerOwnedHandleList* toDelete = curr;
+ DebuggerOwnedHandleListNode* toDelete = curr;
RedhawkGCInterface::DestroyTypedHandle(toDelete->handle);
if (prev == nullptr)
{
// We are trying to remove the head of the linked list
- DebuggerHook::s_debuggerOwnedHandleList = curr->next;
+ DebuggerHook::s_debuggerOwnedHandles = curr->next;
}
else
{
@@ -192,7 +224,7 @@ EXTERN_C REDHAWK_API UInt32 __cdecl RhpRecordDebuggeeInitiatedHandle(void* objec
EXTERN_C REDHAWK_API void __cdecl RhpVerifyDebuggerCleanup()
{
- assert(DebuggerHook::s_debuggerOwnedHandleList == nullptr);
+ assert(DebuggerHook::s_debuggerOwnedHandles == nullptr);
assert(DebuggerHook::s_debuggerProtectedBuffers == nullptr);
}
diff --git a/src/Native/Runtime/DebuggerHook.h b/src/Native/Runtime/DebuggerHook.h
index c64ff8b0c..3f050a4d0 100644
--- a/src/Native/Runtime/DebuggerHook.h
+++ b/src/Native/Runtime/DebuggerHook.h
@@ -18,19 +18,19 @@
#ifndef DACCESS_COMPILE
-struct DebuggerProtectedBufferList
+struct DebuggerProtectedBufferListNode
{
UInt64 address;
UInt16 size;
UInt32 identifier;
- struct DebuggerProtectedBufferList* next;
+ struct DebuggerProtectedBufferListNode* next;
};
-struct DebuggerOwnedHandleList
+struct DebuggerOwnedHandleListNode
{
void* handle;
UInt32 identifier;
- struct DebuggerOwnedHandleList* next;
+ struct DebuggerOwnedHandleListNode* next;
};
class DebuggerHook
@@ -38,11 +38,12 @@ class DebuggerHook
public:
static void OnBeforeGcCollection();
static UInt32 RecordDebuggeeInitiatedHandle(void* handle);
- static DebuggerProtectedBufferList* s_debuggerProtectedBuffers;
- static DebuggerOwnedHandleList* s_debuggerOwnedHandleList;
+ static DebuggerProtectedBufferListNode* s_debuggerProtectedBuffers;
+ static DebuggerOwnedHandleListNode* s_debuggerOwnedHandles;
private:
static void EnsureConservativeReporting(GcProtectionRequest* request);
static void RemoveConservativeReporting(GcProtectionRequest* request);
+ static void EnsureHandle(GcProtectionRequest* request);
static void RemoveHandle(GcProtectionRequest* request);
static UInt32 s_debuggeeInitiatedHandleIdentifier;
};
diff --git a/src/Native/Runtime/gcrhenv.cpp b/src/Native/Runtime/gcrhenv.cpp
index 93476f8dc..30ac3210c 100644
--- a/src/Native/Runtime/gcrhenv.cpp
+++ b/src/Native/Runtime/gcrhenv.cpp
@@ -894,6 +894,11 @@ void RedhawkGCInterface::DestroyTypedHandle(void * handle)
::DestroyTypedHandle((OBJECTHANDLE)handle);
}
+void* RedhawkGCInterface::CreateTypedHandle(void* pObject, int type)
+{
+ return (void*)::CreateTypedHandle(g_HandleTableMap.pBuckets[0]->pTable[GetCurrentThreadHomeHeapNumber()], (Object*)pObject, type);
+}
+
void GCToEEInterface::SuspendEE(SUSPEND_REASON reason)
{
#ifdef FEATURE_EVENT_TRACE
diff --git a/src/Native/Runtime/gcrhinterface.h b/src/Native/Runtime/gcrhinterface.h
index dfcd00939..2cea66073 100644
--- a/src/Native/Runtime/gcrhinterface.h
+++ b/src/Native/Runtime/gcrhinterface.h
@@ -158,7 +158,8 @@ public:
static void SetLastAllocEEType(EEType *pEEType);
// Used by debugger hook
- static void DestroyTypedHandle(void * handle);
+ static void* CreateTypedHandle(void* object, int type);
+ static void DestroyTypedHandle(void* handle);
private:
// The EEType for the last allocation. This value is used inside of the GC allocator
diff --git a/src/Native/Runtime/gcrhscan.cpp b/src/Native/Runtime/gcrhscan.cpp
index 31ac4d7a5..e342e2c78 100644
--- a/src/Native/Runtime/gcrhscan.cpp
+++ b/src/Native/Runtime/gcrhscan.cpp
@@ -49,7 +49,7 @@ void EnumAllStaticGCRefs(EnumGcRefCallbackFunc * fn, EnumGcRefScanContext * sc)
void GCToEEInterface::GcScanRoots(EnumGcRefCallbackFunc * fn, int condemned, int max_gen, EnumGcRefScanContext * sc)
{
- DebuggerProtectedBufferList* cursor = DebuggerHook::s_debuggerProtectedBuffers;
+ DebuggerProtectedBufferListNode* cursor = DebuggerHook::s_debuggerProtectedBuffers;
while (cursor != nullptr)
{
GcEnumObjectsConservatively((PTR_PTR_Object)cursor->address, (PTR_PTR_Object)(cursor->address + cursor->size), fn, sc);