Debugger.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Copyright (c) 2021 ChakraCore Project Contributors. All rights reserved.
  4. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  5. //-------------------------------------------------------------------------------------------------------
  6. #include "stdafx.h"
  7. #include "Helpers.h"
  8. #include "PlatformAgnostic/ChakraICU.h"
  9. #define MAX_BASELINE_SIZE (1024*1024*200)
  10. void CHAKRA_CALLBACK Debugger::DebugEventHandler(_In_ JsDiagDebugEvent debugEvent, _In_ JsValueRef eventData, _In_opt_ void* callbackState)
  11. {
  12. Debugger* debugger = (Debugger*)callbackState;
  13. debugger->HandleDebugEvent(debugEvent, eventData);
  14. }
  15. JsValueRef Debugger::GetSource(JsValueRef callee, bool isConstructCall, JsValueRef * arguments, unsigned short argumentCount, void * callbackState)
  16. {
  17. int scriptId;
  18. JsValueRef source = JS_INVALID_REFERENCE;
  19. if (argumentCount > 1)
  20. {
  21. IfJsErrorFailLogAndRet(ChakraRTInterface::JsNumberToInt(arguments[1], &scriptId));
  22. IfJsErrorFailLogAndRet(ChakraRTInterface::JsDiagGetSource(scriptId, &source));
  23. }
  24. return source;
  25. }
  26. JsValueRef Debugger::SetBreakpoint(JsValueRef callee, bool isConstructCall, JsValueRef * arguments, unsigned short argumentCount, void * callbackState)
  27. {
  28. int scriptId;
  29. int line;
  30. int column;
  31. JsValueRef bpObject = JS_INVALID_REFERENCE;
  32. if (argumentCount > 3)
  33. {
  34. IfJsErrorFailLogAndRet(ChakraRTInterface::JsNumberToInt(arguments[1], &scriptId));
  35. IfJsErrorFailLogAndRet(ChakraRTInterface::JsNumberToInt(arguments[2], &line));
  36. IfJsErrorFailLogAndRet(ChakraRTInterface::JsNumberToInt(arguments[3], &column));
  37. IfJsErrorFailLogAndRet(ChakraRTInterface::JsDiagSetBreakpoint(scriptId, line, column, &bpObject));
  38. }
  39. return bpObject;
  40. }
  41. JsValueRef Debugger::GetStackTrace(JsValueRef callee, bool isConstructCall, JsValueRef * arguments, unsigned short argumentCount, void * callbackState)
  42. {
  43. JsValueRef stackInfo = JS_INVALID_REFERENCE;
  44. IfJsErrorFailLogAndRet(ChakraRTInterface::JsDiagGetStackTrace(&stackInfo));
  45. return stackInfo;
  46. }
  47. JsValueRef Debugger::GetBreakpoints(JsValueRef callee, bool isConstructCall, JsValueRef *arguments, unsigned short argumentCount, void *callbackState)
  48. {
  49. JsValueRef breakpoints = JS_INVALID_REFERENCE;
  50. IfJsErrorFailLogAndRet(ChakraRTInterface::JsDiagGetBreakpoints(&breakpoints));
  51. return breakpoints;
  52. }
  53. JsValueRef Debugger::RemoveBreakpoint(JsValueRef callee, bool isConstructCall, JsValueRef *arguments, unsigned short argumentCount, void *callbackState)
  54. {
  55. int bpId;
  56. if (argumentCount > 1)
  57. {
  58. JsValueRef numberValue;
  59. IfJsErrorFailLogAndRet(ChakraRTInterface::JsConvertValueToNumber(arguments[1], &numberValue));
  60. IfJsErrorFailLogAndRet(ChakraRTInterface::JsNumberToInt(numberValue, &bpId));
  61. IfJsErrorFailLogAndRet(ChakraRTInterface::JsDiagRemoveBreakpoint(bpId));
  62. }
  63. return JS_INVALID_REFERENCE;
  64. }
  65. JsValueRef Debugger::SetBreakOnException(JsValueRef callee, bool isConstructCall, JsValueRef *arguments, unsigned short argumentCount, void *callbackState)
  66. {
  67. int exceptionAttributes;
  68. if (argumentCount > 1)
  69. {
  70. JsValueRef breakOnException;
  71. IfJsErrorFailLogAndRet(ChakraRTInterface::JsConvertValueToNumber(arguments[1], &breakOnException));
  72. IfJsErrorFailLogAndRet(ChakraRTInterface::JsNumberToInt(breakOnException, &exceptionAttributes));
  73. IfJsErrorFailLogAndRet(ChakraRTInterface::JsDiagSetBreakOnException(Debugger::GetRuntime(), (JsDiagBreakOnExceptionAttributes)exceptionAttributes));
  74. }
  75. return JS_INVALID_REFERENCE;
  76. }
  77. JsValueRef Debugger::GetBreakOnException(JsValueRef callee, bool isConstructCall, JsValueRef *arguments, unsigned short argumentCount, void *callbackState)
  78. {
  79. JsDiagBreakOnExceptionAttributes exceptionAttributes;
  80. IfJsErrorFailLogAndRet(ChakraRTInterface::JsDiagGetBreakOnException(Debugger::GetRuntime(), &exceptionAttributes));
  81. JsValueRef exceptionAttributesRef;
  82. IfJsErrorFailLogAndRet(ChakraRTInterface::JsDoubleToNumber((double)exceptionAttributes, &exceptionAttributesRef));
  83. return exceptionAttributesRef;
  84. }
  85. JsValueRef Debugger::SetStepType(JsValueRef callee, bool isConstructCall, JsValueRef *arguments, unsigned short argumentCount, void *callbackState)
  86. {
  87. int stepType;
  88. if (argumentCount > 1)
  89. {
  90. IfJsErrorFailLogAndRet(ChakraRTInterface::JsNumberToInt(arguments[1], &stepType));
  91. IfJsErrorFailLogAndRet(ChakraRTInterface::JsDiagSetStepType((JsDiagStepType)stepType));
  92. }
  93. return JS_INVALID_REFERENCE;
  94. }
  95. JsValueRef Debugger::GetScripts(JsValueRef callee, bool isConstructCall, JsValueRef *arguments, unsigned short argumentCount, void *callbackState)
  96. {
  97. JsValueRef sourcesList = JS_INVALID_REFERENCE;
  98. IfJsErrorFailLogAndRet(ChakraRTInterface::JsDiagGetScripts(&sourcesList));
  99. return sourcesList;
  100. }
  101. JsValueRef Debugger::GetStackProperties(JsValueRef callee, bool isConstructCall, JsValueRef *arguments, unsigned short argumentCount, void *callbackState)
  102. {
  103. JsValueRef properties = JS_INVALID_REFERENCE;
  104. int stackFrameIndex;
  105. if (argumentCount > 1)
  106. {
  107. IfJsErrorFailLogAndRet(ChakraRTInterface::JsNumberToInt(arguments[1], &stackFrameIndex));
  108. IfJsErrorFailLogAndRet(ChakraRTInterface::JsDiagGetStackProperties(stackFrameIndex, &properties));
  109. }
  110. return properties;
  111. }
  112. JsValueRef Debugger::GetProperties(JsValueRef callee, bool isConstructCall, JsValueRef *arguments, unsigned short argumentCount, void *callbackState)
  113. {
  114. JsValueRef properties = JS_INVALID_REFERENCE;
  115. int objectHandle;
  116. int fromCount;
  117. int totalCount;
  118. if (argumentCount > 3)
  119. {
  120. IfJsErrorFailLogAndRet(ChakraRTInterface::JsNumberToInt(arguments[1], &objectHandle));
  121. IfJsErrorFailLogAndRet(ChakraRTInterface::JsNumberToInt(arguments[2], &fromCount));
  122. IfJsErrorFailLogAndRet(ChakraRTInterface::JsNumberToInt(arguments[3], &totalCount));
  123. IfJsErrorFailLogAndRet(ChakraRTInterface::JsDiagGetProperties(objectHandle, fromCount, totalCount, &properties));
  124. }
  125. return properties;
  126. }
  127. JsValueRef Debugger::GetObjectFromHandle(JsValueRef callee, bool isConstructCall, JsValueRef *arguments, unsigned short argumentCount, void *callbackState)
  128. {
  129. JsValueRef properties = JS_INVALID_REFERENCE;
  130. int objectHandle;
  131. if (argumentCount > 1)
  132. {
  133. IfJsErrorFailLogAndRet(ChakraRTInterface::JsNumberToInt(arguments[1], &objectHandle));
  134. IfJsErrorFailLogAndRet(ChakraRTInterface::JsDiagGetObjectFromHandle(objectHandle, &properties));
  135. }
  136. return properties;
  137. }
  138. JsValueRef Debugger::Evaluate(JsValueRef callee, bool isConstructCall, JsValueRef *arguments, unsigned short argumentCount, void *callbackState)
  139. {
  140. int stackFrameIndex;
  141. JsValueRef result = JS_INVALID_REFERENCE;
  142. if (argumentCount > 2)
  143. {
  144. IfJsErrorFailLogAndRet(ChakraRTInterface::JsNumberToInt(arguments[1], &stackFrameIndex));
  145. ChakraRTInterface::JsDiagEvaluate(arguments[2], stackFrameIndex, JsParseScriptAttributeNone, /* forceSetValueProp */ false, &result);
  146. }
  147. return result;
  148. }
  149. Debugger::Debugger(JsRuntimeHandle runtime)
  150. {
  151. this->m_runtime = runtime;
  152. this->m_context = JS_INVALID_REFERENCE;
  153. this->m_isDetached = true;
  154. }
  155. Debugger::~Debugger()
  156. {
  157. if (this->m_context != JS_INVALID_REFERENCE)
  158. {
  159. ChakraRTInterface::JsRelease(this->m_context, nullptr);
  160. this->m_context = JS_INVALID_REFERENCE;
  161. }
  162. this->m_runtime = JS_INVALID_RUNTIME_HANDLE;
  163. }
  164. Debugger * Debugger::GetDebugger(JsRuntimeHandle runtime)
  165. {
  166. if (Debugger::debugger == nullptr)
  167. {
  168. Debugger::debugger = new Debugger(runtime);
  169. Debugger::debugger->Initialize();
  170. }
  171. return Debugger::debugger;
  172. }
  173. void Debugger::CloseDebugger()
  174. {
  175. if (Debugger::debugger != nullptr)
  176. {
  177. delete Debugger::debugger;
  178. Debugger::debugger = nullptr;
  179. }
  180. }
  181. JsRuntimeHandle Debugger::GetRuntime()
  182. {
  183. return Debugger::debugger != nullptr ? Debugger::debugger->m_runtime : JS_INVALID_RUNTIME_HANDLE;
  184. }
  185. bool Debugger::Initialize()
  186. {
  187. // Create a new context and run dbgcontroller.js in that context
  188. // setup dbgcontroller.js callbacks
  189. Assert(this->m_context == JS_INVALID_REFERENCE);
  190. IfJsrtErrorFailLogAndRetFalse(ChakraRTInterface::JsCreateContext(this->m_runtime, &this->m_context));
  191. IfJsrtErrorFailLogAndRetFalse(ChakraRTInterface::JsAddRef(this->m_context, nullptr)); // Pin context
  192. AutoRestoreContext autoRestoreContext(this->m_context);
  193. JsValueRef globalFunc = JS_INVALID_REFERENCE;
  194. JsValueRef scriptSource;
  195. IfJsrtErrorFailLogAndRetFalse(ChakraRTInterface::JsCreateExternalArrayBuffer(
  196. (void*)controllerScript, (unsigned int)strlen(controllerScript),
  197. nullptr, nullptr, &scriptSource));
  198. JsValueRef fname;
  199. ChakraRTInterface::JsCreateString(
  200. "DbgController.js", strlen("DbgController.js"), &fname);
  201. IfJsrtErrorFailLogAndRetFalse(ChakraRTInterface::JsParse(scriptSource,
  202. JS_SOURCE_CONTEXT_NONE, fname, JsParseScriptAttributeLibraryCode,
  203. &globalFunc));
  204. JsValueRef undefinedValue;
  205. IfJsrtErrorFailLogAndRetFalse(ChakraRTInterface::JsGetUndefinedValue(&undefinedValue));
  206. JsValueRef args[] = { undefinedValue };
  207. JsValueRef result = JS_INVALID_REFERENCE;
  208. IfJsrtErrorFailLogAndRetFalse(ChakraRTInterface::JsCallFunction(globalFunc, args, _countof(args), &result));
  209. JsValueRef globalObj = JS_INVALID_REFERENCE;
  210. IfJsrtErrorFailLogAndRetFalse(ChakraRTInterface::JsGetGlobalObject(&globalObj));
  211. JsPropertyIdRef hostDebugObjectPropId;
  212. IfJsrtErrorFailLogAndRetFalse(CreatePropertyIdFromString("hostDebugObject", &hostDebugObjectPropId));
  213. JsPropertyIdRef hostDebugObject;
  214. IfJsrtErrorFailLogAndRetFalse(ChakraRTInterface::JsGetProperty(globalObj, hostDebugObjectPropId, &hostDebugObject));
  215. this->InstallDebugCallbacks(hostDebugObject);
  216. if (!WScriptJsrt::Initialize())
  217. {
  218. return false;
  219. }
  220. if (HostConfigFlags::flags.dbgbaselineIsEnabled)
  221. {
  222. this->SetBaseline();
  223. }
  224. if (HostConfigFlags::flags.InspectMaxStringLengthIsEnabled)
  225. {
  226. this->SetInspectMaxStringLength();
  227. }
  228. return true;
  229. }
  230. bool Debugger::InstallDebugCallbacks(JsValueRef hostDebugObject)
  231. {
  232. HRESULT hr = S_OK;
  233. IfFalseGo(WScriptJsrt::InstallObjectsOnObject(hostDebugObject, "JsDiagGetSource", Debugger::GetSource));
  234. IfFalseGo(WScriptJsrt::InstallObjectsOnObject(hostDebugObject, "JsDiagSetBreakpoint", Debugger::SetBreakpoint));
  235. IfFalseGo(WScriptJsrt::InstallObjectsOnObject(hostDebugObject, "JsDiagGetStackTrace", Debugger::GetStackTrace));
  236. IfFalseGo(WScriptJsrt::InstallObjectsOnObject(hostDebugObject, "JsDiagGetBreakpoints", Debugger::GetBreakpoints));
  237. IfFalseGo(WScriptJsrt::InstallObjectsOnObject(hostDebugObject, "JsDiagRemoveBreakpoint", Debugger::RemoveBreakpoint));
  238. IfFalseGo(WScriptJsrt::InstallObjectsOnObject(hostDebugObject, "JsDiagSetBreakOnException", Debugger::SetBreakOnException));
  239. IfFalseGo(WScriptJsrt::InstallObjectsOnObject(hostDebugObject, "JsDiagGetBreakOnException", Debugger::GetBreakOnException));
  240. IfFalseGo(WScriptJsrt::InstallObjectsOnObject(hostDebugObject, "JsDiagSetStepType", Debugger::SetStepType));
  241. IfFalseGo(WScriptJsrt::InstallObjectsOnObject(hostDebugObject, "JsDiagGetScripts", Debugger::GetScripts));
  242. IfFalseGo(WScriptJsrt::InstallObjectsOnObject(hostDebugObject, "JsDiagGetStackProperties", Debugger::GetStackProperties));
  243. IfFalseGo(WScriptJsrt::InstallObjectsOnObject(hostDebugObject, "JsDiagGetProperties", Debugger::GetProperties));
  244. IfFalseGo(WScriptJsrt::InstallObjectsOnObject(hostDebugObject, "JsDiagGetObjectFromHandle", Debugger::GetObjectFromHandle));
  245. IfFalseGo(WScriptJsrt::InstallObjectsOnObject(hostDebugObject, "JsDiagEvaluate", Debugger::Evaluate));
  246. Error:
  247. return hr != S_OK;
  248. }
  249. bool Debugger::SetBaseline()
  250. {
  251. const char* script = nullptr;
  252. char* fileName = nullptr;
  253. JsValueRef scriptRef = JS_INVALID_REFERENCE;
  254. HRESULT hr = E_FAIL;
  255. UINT lengthBytes = 0;
  256. if (SUCCEEDED(WideStringToNarrowDynamic(HostConfigFlags::flags.dbgbaseline, &fileName)))
  257. {
  258. Helpers::LoadScriptFromFile(fileName, script, &lengthBytes);
  259. if (script && lengthBytes < MAX_BASELINE_SIZE &&
  260. ChakraRTInterface::JsCreateString(script, strlen(script), &scriptRef) == JsNoError)
  261. {
  262. this->CallFunctionNoResult("SetBaseline", scriptRef);
  263. hr = S_OK;
  264. }
  265. }
  266. if (script)
  267. {
  268. delete[] script;
  269. }
  270. if (hr != S_OK)
  271. {
  272. Helpers::LogError(_u("Failed to load & process debug baseline: %s"), HostConfigFlags::flags.dbgbaseline);
  273. }
  274. return hr == S_OK;
  275. }
  276. bool Debugger::SetInspectMaxStringLength()
  277. {
  278. Assert(HostConfigFlags::flags.InspectMaxStringLength > 0);
  279. JsValueRef maxStringRef;
  280. IfJsrtErrorFailLogAndRetFalse(ChakraRTInterface::JsDoubleToNumber(HostConfigFlags::flags.InspectMaxStringLength, &maxStringRef));
  281. return this->CallFunctionNoResult("SetInspectMaxStringLength", maxStringRef);
  282. }
  283. bool Debugger::CallFunction(char const * functionName, JsValueRef *result, JsValueRef arg1, JsValueRef arg2)
  284. {
  285. AutoRestoreContext autoRestoreContext(this->m_context);
  286. // Get the global object
  287. JsValueRef globalObj = JS_INVALID_REFERENCE;
  288. IfJsrtErrorFailLogAndRetFalse(ChakraRTInterface::JsGetGlobalObject(&globalObj));
  289. // Get a script string for the function name
  290. JsPropertyIdRef targetFuncId = JS_INVALID_REFERENCE;
  291. IfJsrtErrorFailLogAndRetFalse(CreatePropertyIdFromString(functionName, &targetFuncId));
  292. // Get the target function
  293. JsValueRef targetFunc = JS_INVALID_REFERENCE;
  294. IfJsrtErrorFailLogAndRetFalse(ChakraRTInterface::JsGetProperty(globalObj, targetFuncId, &targetFunc));
  295. static const unsigned short MaxArgs = 2;
  296. JsValueRef args[MaxArgs + 1];
  297. // Pass in undefined for 'this'
  298. IfJsrtErrorFailLogAndRetFalse(ChakraRTInterface::JsGetUndefinedValue(&args[0]));
  299. unsigned short argCount = 1;
  300. if (arg1 != JS_INVALID_REFERENCE)
  301. {
  302. args[argCount++] = arg1;
  303. }
  304. Assert(arg2 == JS_INVALID_REFERENCE || argCount != 1);
  305. if (arg2 != JS_INVALID_REFERENCE)
  306. {
  307. args[argCount++] = arg2;
  308. }
  309. // Call the function
  310. IfJsrtErrorFailLogAndRetFalse(ChakraRTInterface::JsCallFunction(targetFunc, args, argCount, result));
  311. return true;
  312. }
  313. bool Debugger::CallFunctionNoResult(char const * functionName, JsValueRef arg1, JsValueRef arg2)
  314. {
  315. JsValueRef result = JS_INVALID_REFERENCE;
  316. return this->CallFunction(functionName, &result, arg1, arg2);
  317. }
  318. bool Debugger::DumpFunctionPosition(JsValueRef functionPosition)
  319. {
  320. return this->CallFunctionNoResult("DumpFunctionPosition", functionPosition);
  321. }
  322. bool Debugger::StartDebugging(JsRuntimeHandle runtime)
  323. {
  324. JsErrorCode errorCode = ChakraRTInterface::JsDiagStartDebugging(runtime, Debugger::DebugEventHandler, this);
  325. if (errorCode == JsErrorCode::JsErrorDiagAlreadyInDebugMode)
  326. {
  327. return false;
  328. }
  329. IfJsrtErrorFailLogAndRetFalse(errorCode);
  330. this->m_isDetached = false;
  331. return true;
  332. }
  333. bool Debugger::StopDebugging(JsRuntimeHandle runtime)
  334. {
  335. void* callbackState = nullptr;
  336. JsErrorCode errorCode = ChakraRTInterface::JsDiagStopDebugging(runtime, &callbackState);
  337. if (errorCode == JsErrorCode::JsErrorDiagNotInDebugMode)
  338. {
  339. return false;
  340. }
  341. IfJsrtErrorFailLogAndRetFalse(errorCode);
  342. Assert(callbackState == this);
  343. this->m_isDetached = true;
  344. return true;
  345. }
  346. bool Debugger::HandleDebugEvent(JsDiagDebugEvent debugEvent, JsValueRef eventData)
  347. {
  348. JsValueRef debugEventRef;
  349. IfJsrtErrorFailLogAndRetFalse(ChakraRTInterface::JsDoubleToNumber(debugEvent, &debugEventRef));
  350. return this->CallFunctionNoResult("HandleDebugEvent", debugEventRef, eventData);
  351. }
  352. bool Debugger::CompareOrWriteBaselineFile(LPCSTR fileName)
  353. {
  354. AutoRestoreContext autoRestoreContext(this->m_context);
  355. // Pass in undefined for 'this'
  356. JsValueRef undefinedRef;
  357. IfJsrtErrorFailLogAndRetFalse(ChakraRTInterface::JsGetUndefinedValue(&undefinedRef));
  358. JsValueRef result = JS_INVALID_REFERENCE;
  359. bool testPassed = false;
  360. if (HostConfigFlags::flags.dbgbaselineIsEnabled)
  361. {
  362. this->CallFunction("Verify", &result);
  363. JsValueRef numberVal;
  364. IfJsrtErrorFailLogAndRetFalse(ChakraRTInterface::JsConvertValueToNumber(result, &numberVal));
  365. int val;
  366. IfJsrtErrorFailLogAndRetFalse(ChakraRTInterface::JsNumberToInt(numberVal, &val));
  367. testPassed = (val == 0);
  368. }
  369. if (!testPassed)
  370. {
  371. this->CallFunction("GetOutputJson", &result);
  372. AutoString baselineData;
  373. IfJsrtErrorFailLogAndRetFalse(baselineData.Initialize(result));
  374. char16 baselineFilename[256];
  375. swprintf_s(baselineFilename, HostConfigFlags::flags.dbgbaselineIsEnabled ? _u("%S.dbg.baseline.rebase") : _u("%S.dbg.baseline"), fileName);
  376. FILE *file = nullptr;
  377. if (_wfopen_s(&file, baselineFilename, _u("wt")) != 0)
  378. {
  379. return false;
  380. }
  381. if (file != nullptr)
  382. {
  383. int countWritten = static_cast<int>(fwrite(baselineData.GetString(), sizeof(char), baselineData.GetLength(), file));
  384. Assert(baselineData.GetLength() <= INT_MAX);
  385. if (countWritten != (int)baselineData.GetLength())
  386. {
  387. Assert(false);
  388. return false;
  389. }
  390. fclose(file);
  391. }
  392. if (!HostConfigFlags::flags.dbgbaselineIsEnabled)
  393. {
  394. wprintf(_u("No baseline file specified, baseline created at '%s'\n"), baselineFilename);
  395. }
  396. else
  397. {
  398. Helpers::LogError(_u("Rebase file created at '%s'\n"), baselineFilename);
  399. }
  400. }
  401. return true;
  402. }
  403. bool Debugger::SourceRunDown()
  404. {
  405. AutoRestoreContext autoRestoreContext(this->m_context);
  406. JsValueRef sourcesList = JS_INVALID_REFERENCE;
  407. IfJsrtErrorFailLogAndRetFalse(ChakraRTInterface::JsDiagGetScripts(&sourcesList));
  408. return this->CallFunctionNoResult("HandleSourceRunDown", sourcesList);
  409. }