DiagProbe.h 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #pragma once
  6. namespace Js
  7. {
  8. class MutationBreakpoint;
  9. enum StopType
  10. {
  11. STOP_BREAKPOINT,
  12. STOP_INLINEBREAKPOINT,
  13. STOP_STEPCOMPLETE,
  14. STOP_EXCEPTIONTHROW,
  15. STOP_ASYNCBREAK,
  16. STOP_MUTATIONBREAKPOINT
  17. };
  18. struct ReturnedValue
  19. {
  20. ReturnedValue() {}
  21. ReturnedValue(Js::Var _returnedValue, Js::JavascriptFunction * _calledFunction, bool _isValueOfReturnStatement)
  22. : returnedValue(_returnedValue), calledFunction(_calledFunction), isValueOfReturnStatement(_isValueOfReturnStatement)
  23. {
  24. if (isValueOfReturnStatement)
  25. {
  26. Assert(returnedValue == nullptr);
  27. Assert(calledFunction == nullptr);
  28. }
  29. }
  30. Js::Var returnedValue;
  31. Js::JavascriptFunction *calledFunction;
  32. bool isValueOfReturnStatement;
  33. };
  34. typedef JsUtil::List<ReturnedValue*> ReturnedValueList;
  35. class DiagStackFrame;
  36. typedef JsUtil::Stack<DiagStackFrame*> DiagStack;
  37. typedef WeakArenaReference<DiagStack> WeakDiagStack;
  38. struct InterpreterHaltState
  39. {
  40. StopType stopType;
  41. const FunctionBody* executingFunction;
  42. DiagStackFrame* topFrame;
  43. DiagStack* framePointers;
  44. ReferencedArenaAdapter* referencedDiagnosticArena;
  45. JavascriptExceptionObject* exceptionObject;
  46. StringBuilder<ArenaAllocator>* stringBuilder;
  47. MutationBreakpoint* activeMutationBP;
  48. InterpreterHaltState(StopType _stopType, const FunctionBody* _executingFunction, MutationBreakpoint* _activeMutationBP = nullptr);
  49. FunctionBody* GetFunction();
  50. int GetCurrentOffset();
  51. void SetCurrentOffset(int offset);
  52. bool IsValid() const;
  53. };
  54. struct HaltCallback
  55. {
  56. virtual bool CanHalt(InterpreterHaltState* pHaltState) = 0;
  57. virtual void DispatchHalt(InterpreterHaltState* pHaltState) = 0;
  58. virtual void CleanupHalt() = 0;
  59. virtual bool IsInClosedState() { return false; }
  60. // Mentions the policy if the hitting a breakpoint is allowed (based on the fact whether we are at callback from the breakpoint)
  61. virtual bool CanAllowBreakpoints() { return false; }
  62. };
  63. struct Probe : HaltCallback
  64. {
  65. virtual bool Install(Js::ScriptContext* pScriptContext) = 0;
  66. virtual bool Uninstall(Js::ScriptContext* pScriptContext) = 0;
  67. };
  68. enum StepType : BYTE
  69. {
  70. STEP_NONE,
  71. STEP_IN = 0x01,
  72. STEP_OVER = 0x02,
  73. STEP_OUT = 0x04,
  74. STEP_DOCUMENT = 0x08,
  75. // On entry of a jitted function, need to bailout to handle stepping if in STEP_IN mode,
  76. // or STEP_OVER (e.g. STEP_OVER at the end of this function, and it is called again by a
  77. // library caller).
  78. STEP_BAILOUT = STEP_IN | STEP_OVER,
  79. };
  80. struct DebuggerOptionsCallback
  81. {
  82. virtual bool IsFirstChanceExceptionEnabled() { return false; }
  83. virtual bool IsNonUserCodeSupportEnabled() { return false; }
  84. virtual bool IsLibraryStackFrameSupportEnabled() { return false; }
  85. };
  86. class StepController
  87. {
  88. friend class ProbeManager;
  89. friend class ProbeContainer;
  90. StepType stepType;
  91. int byteOffset;
  92. RecyclerRootPtr<FunctionBody> body;
  93. FunctionBody::StatementMap* statementMap;
  94. int frameCountWhenSet;
  95. int returnedValueRecordingDepth;
  96. DWORD_PTR frameAddrWhenSet;
  97. uint scriptIdWhenSet;
  98. bool stepCompleteOnInlineBreakpoint;
  99. ScriptContext *pActivatedContext;
  100. ReturnedValueList *returnedValueList;
  101. public:
  102. StepController();
  103. ~StepController()
  104. {
  105. this->Deactivate();
  106. }
  107. bool IsActive();
  108. void Activate(StepType stepType, InterpreterHaltState* haltState);
  109. void Deactivate(InterpreterHaltState* haltState = nullptr);
  110. bool IsStepComplete_AllowingFalsePositives(InterpreterStackFrame * stackFrame);
  111. bool IsStepComplete(InterpreterHaltState* haltState, HaltCallback *haltCallback, OpCode originalOpcode);
  112. bool ContinueFromInlineBreakpoint();
  113. ScriptContext* GetActivatedContext() const
  114. {
  115. return this->pActivatedContext;
  116. }
  117. const StepType* GetAddressOfStepType() const
  118. {
  119. return &stepType;
  120. }
  121. void* GetAddressOfScriptIdWhenSet() const
  122. {
  123. return (void*)&scriptIdWhenSet;
  124. }
  125. void* GetAddressOfFrameAddress() const
  126. {
  127. return (void*)&frameAddrWhenSet;
  128. }
  129. void SetFrameAddr(DWORD_PTR value)
  130. {
  131. this->frameAddrWhenSet = value;
  132. }
  133. void AddToReturnedValueContainer(Js::Var returnValue, Js::JavascriptFunction * function, bool isValueOfReturnStatement);
  134. void AddReturnToReturnedValueContainer();
  135. void StartRecordingCall();
  136. void EndRecordingCall(Js::Var returnValue, Js::JavascriptFunction * function);
  137. ReturnedValueList* GetReturnedValueList() const { return this->returnedValueList; }
  138. void ResetReturnedValueList();
  139. void HandleResumeAction(Js::InterpreterHaltState* haltState, BREAKRESUMEACTION resumeAction);
  140. private:
  141. uint GetScriptId(_In_ FunctionBody* body);
  142. };
  143. // This is separate from the step controller because it is the only case where activation
  144. // happens while the script is running.
  145. class AsyncBreakController
  146. {
  147. private:
  148. HaltCallback* haltCallback;
  149. public:
  150. AsyncBreakController();
  151. void Activate(HaltCallback* haltCallback);
  152. void Deactivate();
  153. bool IsBreak();
  154. bool IsAtStoppingLocation(InterpreterHaltState* haltState);
  155. void DispatchAndReset(InterpreterHaltState* haltState);
  156. };
  157. typedef JsUtil::List<Probe*, ArenaAllocator> ProbeList;
  158. }