コード例 #1
0
ファイル: DebugFuncEval.cs プロジェクト: kevingosse/corert
        private unsafe static void ReturnToDebuggerWithReturn(FuncEvalResult funcEvalResult)
        {
            uint   returnHandleIdentifier   = funcEvalResult.ReturnHandleIdentifier;
            IntPtr returnValueHandlePointer = funcEvalResult.ReturnValueHandlePointer;
            bool   isException = funcEvalResult.IsException;

            // Signal to the debugger the func eval completes

            DebuggerFuncEvalCompleteWithReturnResponse *debuggerFuncEvalCompleteWithReturnResponse = stackalloc DebuggerFuncEvalCompleteWithReturnResponse[1];

            debuggerFuncEvalCompleteWithReturnResponse->kind = isException ? DebuggerResponseKind.FuncEvalCompleteWithException : DebuggerResponseKind.FuncEvalCompleteWithReturn;
            debuggerFuncEvalCompleteWithReturnResponse->returnHandleIdentifier = returnHandleIdentifier;
            debuggerFuncEvalCompleteWithReturnResponse->returnAddress          = (long)returnValueHandlePointer;
            IntPtr debuggerFuncEvalCompleteWithReturnResponsePointer = new IntPtr(debuggerFuncEvalCompleteWithReturnResponse);

            RuntimeAugments.RhpSendCustomEventToDebugger(debuggerFuncEvalCompleteWithReturnResponsePointer, Unsafe.SizeOf <DebuggerFuncEvalCompleteWithReturnResponse>());

            // debugger magic will make sure this function never returns, instead control will be transferred back to the point where the FuncEval begins
        }
コード例 #2
0
ファイル: DebugFuncEval.cs プロジェクト: kevingosse/corert
        private unsafe static void HighLevelDebugFuncEvalHelper()
        {
            long           lastFuncEvalId = s_funcEvalId;
            long           myFuncEvalId   = 0;
            FuncEvalResult funcEvalResult = new FuncEvalResult();

            s_funcEvalThread = RuntimeAugments.RhpGetCurrentThread();
            Exception ex = null;

            try
            {
                uint parameterBufferSize = RuntimeAugments.RhpGetFuncEvalParameterBufferSize();

                IntPtr debuggerFuncEvalParameterBufferReadyResponsePointer;
                IntPtr parameterBufferPointer;

                byte *parameterBuffer = stackalloc byte[(int)parameterBufferSize];
                parameterBufferPointer = new IntPtr(parameterBuffer);

                DebuggerFuncEvalParameterBufferReadyResponse *debuggerFuncEvalParameterBufferReadyResponse = stackalloc DebuggerFuncEvalParameterBufferReadyResponse[1];
                debuggerFuncEvalParameterBufferReadyResponse->kind          = DebuggerResponseKind.FuncEvalParameterBufferReady;
                debuggerFuncEvalParameterBufferReadyResponse->bufferAddress = parameterBufferPointer.ToInt64();

                debuggerFuncEvalParameterBufferReadyResponsePointer = new IntPtr(debuggerFuncEvalParameterBufferReadyResponse);

                RuntimeAugments.RhpSendCustomEventToDebugger(debuggerFuncEvalParameterBufferReadyResponsePointer, Unsafe.SizeOf <DebuggerFuncEvalParameterBufferReadyResponse>());

                // .. debugger magic ... the parameterBuffer will be filled with parameter data

                FuncEvalMode mode = (FuncEvalMode)RuntimeAugments.RhpGetFuncEvalMode();

                switch (mode)
                {
                case FuncEvalMode.CallParameterizedFunction:
                    funcEvalResult = CallParameterizedFunction(ref myFuncEvalId, parameterBuffer, parameterBufferSize);
                    break;

                case FuncEvalMode.NewStringWithLength:
                    funcEvalResult = NewStringWithLength(ref myFuncEvalId, parameterBuffer, parameterBufferSize);
                    break;

                case FuncEvalMode.NewParameterizedArray:
                    funcEvalResult = NewParameterizedArray(ref myFuncEvalId, parameterBuffer, parameterBufferSize);
                    break;

                case FuncEvalMode.NewParameterizedObjectNoConstructor:
                    funcEvalResult = NewParameterizedObjectNoConstructor(ref myFuncEvalId, parameterBuffer, parameterBufferSize);
                    break;

                case FuncEvalMode.NewParameterizedObject:
                    funcEvalResult = NewParameterizedObject(ref myFuncEvalId, parameterBuffer, parameterBufferSize);
                    break;

                default:
                    Debug.Assert(false, "Debugger provided an unexpected func eval mode.");
                    break;
                }

                if (Interlocked.CompareExchange(ref s_funcEvalId, lastFuncEvalId, myFuncEvalId) == myFuncEvalId)
                {
                    ReturnToDebuggerWithReturn(funcEvalResult);
                    // ... debugger magic ... the process will go back to wherever it was before the func eval
                }
                else
                {
                    // Wait for the abort to complete
                    while (true)
                    {
                        RuntimeAugments.RhYield();
                    }
                }
            }
            catch (Exception e)
            {
                RuntimeAugments.RhpCancelThreadAbort(s_funcEvalThread);
                ex = e;

                // It is important that we let the try block complete to clean up runtime data structures,
                // therefore, while the result is already available, we still need to let the runtime exit the catch block
                // cleanly before we return to the debugger.
            }

            s_funcEvalId = lastFuncEvalId;
            ReturnToDebuggerWithReturn(new FuncEvalResult(ex, true));

            // ... debugger magic ... the process will go back to wherever it was before the func eval
        }