OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2010 Apple Inc. All rights reserved. | 2 * Copyright (C) 2010 Apple Inc. All rights reserved. |
3 * Copyright (C) 2013 Google Inc. All rights reserved. | 3 * Copyright (C) 2013 Google Inc. All rights reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
7 * are met: | 7 * are met: |
8 * | 8 * |
9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 29 matching lines...) Expand all Loading... |
40 #include "core/fetch/Resource.h" | 40 #include "core/fetch/Resource.h" |
41 #include "core/inspector/ContentSearchUtils.h" | 41 #include "core/inspector/ContentSearchUtils.h" |
42 #include "core/inspector/InjectedScriptManager.h" | 42 #include "core/inspector/InjectedScriptManager.h" |
43 #include "core/inspector/InspectorPageAgent.h" | 43 #include "core/inspector/InspectorPageAgent.h" |
44 #include "core/inspector/InspectorState.h" | 44 #include "core/inspector/InspectorState.h" |
45 #include "core/inspector/InstrumentingAgents.h" | 45 #include "core/inspector/InstrumentingAgents.h" |
46 #include "core/inspector/ScriptArguments.h" | 46 #include "core/inspector/ScriptArguments.h" |
47 #include "core/inspector/ScriptCallFrame.h" | 47 #include "core/inspector/ScriptCallFrame.h" |
48 #include "core/inspector/ScriptCallStack.h" | 48 #include "core/inspector/ScriptCallStack.h" |
49 #include "platform/JSONValues.h" | 49 #include "platform/JSONValues.h" |
| 50 #include "wtf/Vector.h" |
50 #include "wtf/text/WTFString.h" | 51 #include "wtf/text/WTFString.h" |
51 | 52 |
52 using WebCore::TypeBuilder::Array; | 53 using WebCore::TypeBuilder::Array; |
53 using WebCore::TypeBuilder::Debugger::BreakpointId; | 54 using WebCore::TypeBuilder::Debugger::BreakpointId; |
54 using WebCore::TypeBuilder::Debugger::CallFrame; | 55 using WebCore::TypeBuilder::Debugger::CallFrame; |
55 using WebCore::TypeBuilder::Debugger::ExceptionDetails; | 56 using WebCore::TypeBuilder::Debugger::ExceptionDetails; |
56 using WebCore::TypeBuilder::Debugger::FunctionDetails; | 57 using WebCore::TypeBuilder::Debugger::FunctionDetails; |
57 using WebCore::TypeBuilder::Debugger::ScriptId; | 58 using WebCore::TypeBuilder::Debugger::ScriptId; |
58 using WebCore::TypeBuilder::Debugger::StackTrace; | 59 using WebCore::TypeBuilder::Debugger::StackTrace; |
59 using WebCore::TypeBuilder::Runtime::RemoteObject; | 60 using WebCore::TypeBuilder::Runtime::RemoteObject; |
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
446 if (!isPaused() || m_currentCallStack.isNull()) { | 447 if (!isPaused() || m_currentCallStack.isNull()) { |
447 *errorString = "Attempt to access callframe when debugger is not on paus
e"; | 448 *errorString = "Attempt to access callframe when debugger is not on paus
e"; |
448 return; | 449 return; |
449 } | 450 } |
450 InjectedScript& injectedScript = m_injectedScriptManager->injectedScriptForO
bjectId(callFrameId); | 451 InjectedScript& injectedScript = m_injectedScriptManager->injectedScriptForO
bjectId(callFrameId); |
451 if (injectedScript.isEmpty()) { | 452 if (injectedScript.isEmpty()) { |
452 *errorString = "Inspected frame has gone"; | 453 *errorString = "Inspected frame has gone"; |
453 return; | 454 return; |
454 } | 455 } |
455 | 456 |
456 injectedScript.getStepInPositions(errorString, m_currentCallStack, callFrame
Id, positions); | 457 injectedScript.getStepInPositions(errorString, m_currentCallStack.lookup(inj
ectedScript.scriptState()), callFrameId, positions); |
457 } | 458 } |
458 | 459 |
459 void InspectorDebuggerAgent::getBacktrace(ErrorString* errorString, RefPtr<Array
<CallFrame> >& callFrames, WTF::RefPtr<WebCore::TypeBuilder::Debugger::StackTrac
e>& asyncStackTrace) | 460 void InspectorDebuggerAgent::getBacktrace(ErrorString* errorString, RefPtr<Array
<CallFrame> >& callFrames, WTF::RefPtr<WebCore::TypeBuilder::Debugger::StackTrac
e>& asyncStackTrace) |
460 { | 461 { |
461 if (!assertPaused(errorString)) | 462 if (!assertPaused(errorString)) |
462 return; | 463 return; |
463 m_currentCallStack = scriptDebugServer().currentCallFrames(); | 464 m_currentCallStack = scriptDebugServer().currentCallFrames(); |
464 callFrames = currentCallFrames(); | 465 callFrames = currentCallFrames(); |
465 asyncStackTrace = currentAsyncStackTrace(); | 466 asyncStackTrace = currentAsyncStackTrace(); |
466 } | 467 } |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
604 if (!isPaused() || m_currentCallStack.isNull()) { | 605 if (!isPaused() || m_currentCallStack.isNull()) { |
605 *errorString = "Attempt to access callframe when debugger is not on paus
e"; | 606 *errorString = "Attempt to access callframe when debugger is not on paus
e"; |
606 return; | 607 return; |
607 } | 608 } |
608 InjectedScript& injectedScript = m_injectedScriptManager->injectedScriptForO
bjectId(callFrameId); | 609 InjectedScript& injectedScript = m_injectedScriptManager->injectedScriptForO
bjectId(callFrameId); |
609 if (injectedScript.isEmpty()) { | 610 if (injectedScript.isEmpty()) { |
610 *errorString = "Inspected frame has gone"; | 611 *errorString = "Inspected frame has gone"; |
611 return; | 612 return; |
612 } | 613 } |
613 | 614 |
614 injectedScript.restartFrame(errorString, m_currentCallStack, callFrameId, &r
esult); | 615 injectedScript.restartFrame(errorString, m_currentCallStack.lookup(injectedS
cript.scriptState()), callFrameId, &result); |
615 m_currentCallStack = scriptDebugServer().currentCallFrames(); | 616 m_currentCallStack = scriptDebugServer().currentCallFrames(); |
616 newCallFrames = currentCallFrames(); | 617 newCallFrames = currentCallFrames(); |
617 asyncStackTrace = currentAsyncStackTrace(); | 618 asyncStackTrace = currentAsyncStackTrace(); |
618 } | 619 } |
619 | 620 |
620 void InspectorDebuggerAgent::getScriptSource(ErrorString* error, const String& s
criptId, String* scriptSource) | 621 void InspectorDebuggerAgent::getScriptSource(ErrorString* error, const String& s
criptId, String* scriptSource) |
621 { | 622 { |
622 ScriptsMap::iterator it = m_scripts.find(scriptId); | 623 ScriptsMap::iterator it = m_scripts.find(scriptId); |
623 if (it != m_scripts.end()) | 624 if (it != m_scripts.end()) |
624 *scriptSource = it->value.source; | 625 *scriptSource = it->value.source; |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
826 | 827 |
827 void InspectorDebuggerAgent::setPauseOnExceptionsImpl(ErrorString* errorString,
int pauseState) | 828 void InspectorDebuggerAgent::setPauseOnExceptionsImpl(ErrorString* errorString,
int pauseState) |
828 { | 829 { |
829 scriptDebugServer().setPauseOnExceptionsState(static_cast<ScriptDebugServer:
:PauseOnExceptionsState>(pauseState)); | 830 scriptDebugServer().setPauseOnExceptionsState(static_cast<ScriptDebugServer:
:PauseOnExceptionsState>(pauseState)); |
830 if (scriptDebugServer().pauseOnExceptionsState() != pauseState) | 831 if (scriptDebugServer().pauseOnExceptionsState() != pauseState) |
831 *errorString = "Internal error. Could not change pause on exceptions sta
te"; | 832 *errorString = "Internal error. Could not change pause on exceptions sta
te"; |
832 else | 833 else |
833 m_state->setLong(DebuggerAgentState::pauseOnExceptionsState, pauseState)
; | 834 m_state->setLong(DebuggerAgentState::pauseOnExceptionsState, pauseState)
; |
834 } | 835 } |
835 | 836 |
836 void InspectorDebuggerAgent::collectAsyncCallStacks(Vector<StackTrace>& asyncCal
lStacks) | 837 void InspectorDebuggerAgent::collectAsyncCallStacks(Vector<StackTrace>& asyncCal
lStacks, ScriptState* scriptState) |
837 { | 838 { |
838 const AsyncCallStackTracker::AsyncCallChain* asyncChain = m_asyncCallStackTr
acker.isEnabled() ? m_asyncCallStackTracker.currentAsyncCallChain() : 0; | 839 const AsyncCallStackTracker::AsyncCallChain* asyncChain = m_asyncCallStackTr
acker.isEnabled() ? m_asyncCallStackTracker.currentAsyncCallChain() : 0; |
839 if (asyncChain) { | 840 if (asyncChain) { |
840 const AsyncCallStackTracker::AsyncCallStackVector& callStacks = asyncCha
in->callStacks(); | 841 const AsyncCallStackTracker::AsyncCallStackVector& callStacks = asyncCha
in->callStacks(); |
841 asyncCallStacks.resize(callStacks.size()); | 842 asyncCallStacks.resize(callStacks.size()); |
842 AsyncCallStackTracker::AsyncCallStackVector::const_iterator it = callSta
cks.begin(); | 843 AsyncCallStackTracker::AsyncCallStackVector::const_iterator it = callSta
cks.begin(); |
843 for (size_t i = 0; it != callStacks.end(); ++it, ++i) | 844 for (size_t i = 0; it != callStacks.end(); ++it, ++i) |
844 asyncCallStacks[i] = (*it)->callFrames(); | 845 asyncCallStacks[i] = (*it)->callFrames().lookup(scriptState); |
845 } | 846 } |
846 } | 847 } |
847 | 848 |
848 void InspectorDebuggerAgent::evaluateOnCallFrame(ErrorString* errorString, const
String& callFrameId, const String& expression, const String* const objectGroup,
const bool* const includeCommandLineAPI, const bool* const doNotPauseOnExceptio
nsAndMuteConsole, const bool* const returnByValue, const bool* generatePreview,
RefPtr<RemoteObject>& result, TypeBuilder::OptOutput<bool>* wasThrown) | 849 void InspectorDebuggerAgent::evaluateOnCallFrame(ErrorString* errorString, const
String& callFrameId, const String& expression, const String* const objectGroup,
const bool* const includeCommandLineAPI, const bool* const doNotPauseOnExceptio
nsAndMuteConsole, const bool* const returnByValue, const bool* generatePreview,
RefPtr<RemoteObject>& result, TypeBuilder::OptOutput<bool>* wasThrown) |
849 { | 850 { |
850 if (!isPaused() || m_currentCallStack.isNull()) { | 851 if (!isPaused() || m_currentCallStack.isNull()) { |
851 *errorString = "Attempt to access callframe when debugger is not on paus
e"; | 852 *errorString = "Attempt to access callframe when debugger is not on paus
e"; |
852 return; | 853 return; |
853 } | 854 } |
854 InjectedScript& injectedScript = m_injectedScriptManager->injectedScriptForO
bjectId(callFrameId); | 855 InjectedScript& injectedScript = m_injectedScriptManager->injectedScriptForO
bjectId(callFrameId); |
855 if (injectedScript.isEmpty()) { | 856 if (injectedScript.isEmpty()) { |
856 *errorString = "Inspected frame has gone"; | 857 *errorString = "Inspected frame has gone"; |
857 return; | 858 return; |
858 } | 859 } |
859 | 860 |
860 ScriptDebugServer::PauseOnExceptionsState previousPauseOnExceptionsState = s
criptDebugServer().pauseOnExceptionsState(); | 861 ScriptDebugServer::PauseOnExceptionsState previousPauseOnExceptionsState = s
criptDebugServer().pauseOnExceptionsState(); |
861 if (doNotPauseOnExceptionsAndMuteConsole ? *doNotPauseOnExceptionsAndMuteCon
sole : false) { | 862 if (doNotPauseOnExceptionsAndMuteConsole ? *doNotPauseOnExceptionsAndMuteCon
sole : false) { |
862 if (previousPauseOnExceptionsState != ScriptDebugServer::DontPauseOnExce
ptions) | 863 if (previousPauseOnExceptionsState != ScriptDebugServer::DontPauseOnExce
ptions) |
863 scriptDebugServer().setPauseOnExceptionsState(ScriptDebugServer::Don
tPauseOnExceptions); | 864 scriptDebugServer().setPauseOnExceptionsState(ScriptDebugServer::Don
tPauseOnExceptions); |
864 muteConsole(); | 865 muteConsole(); |
865 } | 866 } |
866 | 867 |
867 Vector<StackTrace> asyncCallStacks; | 868 Vector<StackTrace> asyncCallStacks; |
868 collectAsyncCallStacks(asyncCallStacks); | 869 collectAsyncCallStacks(asyncCallStacks, injectedScript.scriptState()); |
869 injectedScript.evaluateOnCallFrame(errorString, m_currentCallStack, asyncCal
lStacks, callFrameId, expression, objectGroup ? *objectGroup : "", includeComman
dLineAPI ? *includeCommandLineAPI : false, returnByValue ? *returnByValue : fals
e, generatePreview ? *generatePreview : false, &result, wasThrown); | 870 injectedScript.evaluateOnCallFrame(errorString, m_currentCallStack.lookup(in
jectedScript.scriptState()), asyncCallStacks, callFrameId, expression, objectGro
up ? *objectGroup : "", includeCommandLineAPI ? *includeCommandLineAPI : false,
returnByValue ? *returnByValue : false, generatePreview ? *generatePreview : fal
se, &result, wasThrown); |
870 | 871 |
871 if (doNotPauseOnExceptionsAndMuteConsole ? *doNotPauseOnExceptionsAndMuteCon
sole : false) { | 872 if (doNotPauseOnExceptionsAndMuteConsole ? *doNotPauseOnExceptionsAndMuteCon
sole : false) { |
872 unmuteConsole(); | 873 unmuteConsole(); |
873 if (scriptDebugServer().pauseOnExceptionsState() != previousPauseOnExcep
tionsState) | 874 if (scriptDebugServer().pauseOnExceptionsState() != previousPauseOnExcep
tionsState) |
874 scriptDebugServer().setPauseOnExceptionsState(previousPauseOnExcepti
onsState); | 875 scriptDebugServer().setPauseOnExceptionsState(previousPauseOnExcepti
onsState); |
875 } | 876 } |
876 } | 877 } |
877 | 878 |
878 void InspectorDebuggerAgent::getCompletionsOnCallFrame(ErrorString* errorString,
const String& callFrameId, const String& expression, RefPtr<TypeBuilder::Array<
String> >& result) | 879 void InspectorDebuggerAgent::getCompletionsOnCallFrame(ErrorString* errorString,
const String& callFrameId, const String& expression, RefPtr<TypeBuilder::Array<
String> >& result) |
879 { | 880 { |
880 if (!isPaused() || m_currentCallStack.isNull()) { | 881 if (!isPaused() || m_currentCallStack.isNull()) { |
881 *errorString = "Attempt to access callframe when debugger is not on paus
e"; | 882 *errorString = "Attempt to access callframe when debugger is not on paus
e"; |
882 return; | 883 return; |
883 } | 884 } |
884 InjectedScript& injectedScript = m_injectedScriptManager->injectedScriptForO
bjectId(callFrameId); | 885 InjectedScript& injectedScript = m_injectedScriptManager->injectedScriptForO
bjectId(callFrameId); |
885 if (injectedScript.isEmpty()) { | 886 if (injectedScript.isEmpty()) { |
886 *errorString = "Inspected frame has gone"; | 887 *errorString = "Inspected frame has gone"; |
887 return; | 888 return; |
888 } | 889 } |
889 | 890 |
890 ScriptDebugServer::PauseOnExceptionsState previousPauseOnExceptionsState = s
criptDebugServer().pauseOnExceptionsState(); | 891 ScriptDebugServer::PauseOnExceptionsState previousPauseOnExceptionsState = s
criptDebugServer().pauseOnExceptionsState(); |
891 if (previousPauseOnExceptionsState != ScriptDebugServer::DontPauseOnExceptio
ns) | 892 if (previousPauseOnExceptionsState != ScriptDebugServer::DontPauseOnExceptio
ns) |
892 scriptDebugServer().setPauseOnExceptionsState(ScriptDebugServer::DontPau
seOnExceptions); | 893 scriptDebugServer().setPauseOnExceptionsState(ScriptDebugServer::DontPau
seOnExceptions); |
893 muteConsole(); | 894 muteConsole(); |
894 | 895 |
895 Vector<StackTrace> asyncCallStacks; | 896 Vector<StackTrace> asyncCallStacks; |
896 collectAsyncCallStacks(asyncCallStacks); | 897 collectAsyncCallStacks(asyncCallStacks, injectedScript.scriptState()); |
897 injectedScript.getCompletionsOnCallFrame(errorString, m_currentCallStack, as
yncCallStacks, callFrameId, expression, &result); | 898 injectedScript.getCompletionsOnCallFrame(errorString, m_currentCallStack.loo
kup(injectedScript.scriptState()), asyncCallStacks, callFrameId, expression, &re
sult); |
898 | 899 |
899 unmuteConsole(); | 900 unmuteConsole(); |
900 if (scriptDebugServer().pauseOnExceptionsState() != previousPauseOnException
sState) | 901 if (scriptDebugServer().pauseOnExceptionsState() != previousPauseOnException
sState) |
901 scriptDebugServer().setPauseOnExceptionsState(previousPauseOnExceptionsS
tate); | 902 scriptDebugServer().setPauseOnExceptionsState(previousPauseOnExceptionsS
tate); |
902 } | 903 } |
903 | 904 |
904 void InspectorDebuggerAgent::compileScript(ErrorString* errorString, const Strin
g& expression, const String& sourceURL, const int* executionContextId, TypeBuild
er::OptOutput<ScriptId>* scriptId, RefPtr<ExceptionDetails>& exceptionDetails) | 905 void InspectorDebuggerAgent::compileScript(ErrorString* errorString, const Strin
g& expression, const String& sourceURL, const int* executionContextId, TypeBuild
er::OptOutput<ScriptId>* scriptId, RefPtr<ExceptionDetails>& exceptionDetails) |
905 { | 906 { |
906 InjectedScript& injectedScript = injectedScriptForEval(errorString, executio
nContextId); | 907 InjectedScript& injectedScript = injectedScriptForEval(errorString, executio
nContextId); |
907 if (injectedScript.isEmpty()) { | 908 if (injectedScript.isEmpty()) { |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
994 if (injectedScript->isEmpty()) { | 995 if (injectedScript->isEmpty()) { |
995 *errorString = "Function object id cannot be resolved"; | 996 *errorString = "Function object id cannot be resolved"; |
996 return; | 997 return; |
997 } | 998 } |
998 } else { | 999 } else { |
999 *errorString = "Either call frame or function object must be specified"; | 1000 *errorString = "Either call frame or function object must be specified"; |
1000 return; | 1001 return; |
1001 } | 1002 } |
1002 String newValueString = newValue->toJSONString(); | 1003 String newValueString = newValue->toJSONString(); |
1003 ASSERT(injectedScript); | 1004 ASSERT(injectedScript); |
1004 injectedScript->setVariableValue(errorString, m_currentCallStack, callFrameI
d, functionObjectId, scopeNumber, variableName, newValueString); | 1005 injectedScript->setVariableValue(errorString, m_currentCallStack.lookup(inje
ctedScript->scriptState()), callFrameId, functionObjectId, scopeNumber, variable
Name, newValueString); |
1005 } | 1006 } |
1006 | 1007 |
1007 void InspectorDebuggerAgent::skipStackFrames(ErrorString* errorString, const Str
ing* pattern) | 1008 void InspectorDebuggerAgent::skipStackFrames(ErrorString* errorString, const Str
ing* pattern) |
1008 { | 1009 { |
1009 OwnPtr<ScriptRegexp> compiled; | 1010 OwnPtr<ScriptRegexp> compiled; |
1010 String patternValue = pattern ? *pattern : ""; | 1011 String patternValue = pattern ? *pattern : ""; |
1011 if (!patternValue.isEmpty()) { | 1012 if (!patternValue.isEmpty()) { |
1012 compiled = compileSkipCallFramePattern(patternValue); | 1013 compiled = compileSkipCallFramePattern(patternValue); |
1013 if (!compiled) { | 1014 if (!compiled) { |
1014 *errorString = "Invalid regular expression"; | 1015 *errorString = "Invalid regular expression"; |
(...skipping 12 matching lines...) Expand all Loading... |
1027 | 1028 |
1028 void InspectorDebuggerAgent::scriptExecutionBlockedByCSP(const String& directive
Text) | 1029 void InspectorDebuggerAgent::scriptExecutionBlockedByCSP(const String& directive
Text) |
1029 { | 1030 { |
1030 if (scriptDebugServer().pauseOnExceptionsState() != ScriptDebugServer::DontP
auseOnExceptions) { | 1031 if (scriptDebugServer().pauseOnExceptionsState() != ScriptDebugServer::DontP
auseOnExceptions) { |
1031 RefPtr<JSONObject> directive = JSONObject::create(); | 1032 RefPtr<JSONObject> directive = JSONObject::create(); |
1032 directive->setString("directiveText", directiveText); | 1033 directive->setString("directiveText", directiveText); |
1033 breakProgram(InspectorFrontend::Debugger::Reason::CSPViolation, directiv
e.release()); | 1034 breakProgram(InspectorFrontend::Debugger::Reason::CSPViolation, directiv
e.release()); |
1034 } | 1035 } |
1035 } | 1036 } |
1036 | 1037 |
| 1038 uint32_t lookupFramePointerHigh(PassRefPtr<CallFrame> frame) |
| 1039 { |
| 1040 double framePointerHigh = 0; |
| 1041 bool ALLOW_UNUSED hasFramePointerHigh = frame->asObject()->getNumber("frameP
ointerHigh", &framePointerHigh); |
| 1042 ASSERT(hasFramePointerHigh); |
| 1043 return static_cast<uint32_t>(framePointerHigh); |
| 1044 } |
| 1045 |
| 1046 uint32_t lookupFramePointerLow(PassRefPtr<CallFrame> frame) |
| 1047 { |
| 1048 double framePointerLow = 0; |
| 1049 bool ALLOW_UNUSED hasFramePointerLow = frame->asObject()->getNumber("framePo
interLow", &framePointerLow); |
| 1050 ASSERT(hasFramePointerLow); |
| 1051 return static_cast<uint32_t>(framePointerLow); |
| 1052 } |
| 1053 |
| 1054 static inline bool compareCallFramePointers(RefPtr<CallFrame> frame1, RefPtr<Cal
lFrame> frame2) |
| 1055 { |
| 1056 uint32_t highFrame1 = lookupFramePointerHigh(frame1); |
| 1057 uint32_t highFrame2 = lookupFramePointerHigh(frame2); |
| 1058 if (highFrame1 != highFrame2) |
| 1059 return highFrame1 < highFrame2; |
| 1060 |
| 1061 return lookupFramePointerLow(frame1) < lookupFramePointerLow(frame2); |
| 1062 } |
| 1063 |
| 1064 void addFramesToVector(PassRefPtr<Array<CallFrame> > trace, Vector<RefPtr<CallFr
ame> > & v) |
| 1065 { |
| 1066 RefPtr<JSONArray> traceArray = trace->asArray(); |
| 1067 for (JSONArray::iterator it = traceArray->begin(); it != traceArray->end();
++it) { |
| 1068 v.append(CallFrame::runtimeCast(*it)); |
| 1069 } |
| 1070 } |
| 1071 |
1037 PassRefPtr<Array<CallFrame> > InspectorDebuggerAgent::currentCallFrames() | 1072 PassRefPtr<Array<CallFrame> > InspectorDebuggerAgent::currentCallFrames() |
1038 { | 1073 { |
| 1074 return callFrames(m_currentCallStack, 0); |
| 1075 } |
| 1076 |
| 1077 PassRefPtr<Array<CallFrame> > InspectorDebuggerAgent::callFrames(StackTraces sta
ckTraces, int asyncOrdinal) |
| 1078 { |
1039 if (!m_pausedScriptState || m_currentCallStack.isNull()) | 1079 if (!m_pausedScriptState || m_currentCallStack.isNull()) |
1040 return Array<TypeBuilder::Debugger::CallFrame>::create(); | 1080 return Array<TypeBuilder::Debugger::CallFrame>::create(); |
1041 InjectedScript& injectedScript = m_injectedScriptManager->injectedScriptFor(
m_pausedScriptState.get()); | 1081 |
1042 if (injectedScript.isEmpty()) { | 1082 Vector<RefPtr<CallFrame> > mergedFrames; |
1043 ASSERT_NOT_REACHED(); | 1083 for (StackTraces::iterator it = m_currentCallStack.begin(); it != m_currentC
allStack.end(); ++it) { |
1044 return Array<CallFrame>::create(); | 1084 ScriptState* scriptState = it->key; |
| 1085 StackTrace& stackTrace = it->value; |
| 1086 // FIXMEDART: passing in -1 as hack to force AsyncStack mode |
| 1087 // evaluation as V8 cannot handle regular evaluation of a call |
| 1088 // frame if not stopped at a v8 breakpoint due to an assert |
| 1089 // in the V8 code base that should probably be removed. |
| 1090 // Async call frame evaluation works almost as well as regular |
| 1091 // call frame evaluation with the only difference being that |
| 1092 // local variable modifications have no impact. |
| 1093 if (asyncOrdinal == 0 && m_pausedScriptState != scriptState) { |
| 1094 asyncOrdinal = -1; |
| 1095 } |
| 1096 addFramesToVector(m_injectedScriptManager->injectedScriptFor(scriptState
).wrapCallFrames(stackTrace, asyncOrdinal), mergedFrames); |
1045 } | 1097 } |
1046 return injectedScript.wrapCallFrames(m_currentCallStack, 0); | 1098 std::stable_sort(mergedFrames.begin(), mergedFrames.end(), compareCallFrameP
ointers); |
| 1099 |
| 1100 RefPtr<Array<CallFrame> > ret = Array<CallFrame>::create(); |
| 1101 for (size_t i = 0; i < mergedFrames.size(); ++i) |
| 1102 ret->addItem(mergedFrames[i]); |
| 1103 return ret; |
1047 } | 1104 } |
1048 | 1105 |
1049 PassRefPtr<WebCore::TypeBuilder::Debugger::StackTrace> InspectorDebuggerAgent::c
urrentAsyncStackTrace() | 1106 PassRefPtr<WebCore::TypeBuilder::Debugger::StackTrace> InspectorDebuggerAgent::c
urrentAsyncStackTrace() |
1050 { | 1107 { |
1051 if (!m_pausedScriptState || !m_asyncCallStackTracker.isEnabled()) | 1108 if (!m_pausedScriptState || !m_asyncCallStackTracker.isEnabled()) |
1052 return nullptr; | 1109 return nullptr; |
1053 InjectedScript& injectedScript = m_injectedScriptManager->injectedScriptFor(
m_pausedScriptState.get()); | 1110 InjectedScript& injectedScript = m_injectedScriptManager->injectedScriptFor(
m_pausedScriptState.get()); |
1054 if (injectedScript.isEmpty()) { | 1111 if (injectedScript.isEmpty()) { |
1055 ASSERT_NOT_REACHED(); | 1112 ASSERT_NOT_REACHED(); |
1056 return nullptr; | 1113 return nullptr; |
1057 } | 1114 } |
1058 const AsyncCallStackTracker::AsyncCallChain* chain = m_asyncCallStackTracker
.currentAsyncCallChain(); | 1115 const AsyncCallStackTracker::AsyncCallChain* chain = m_asyncCallStackTracker
.currentAsyncCallChain(); |
1059 if (!chain) | 1116 if (!chain) |
1060 return nullptr; | 1117 return nullptr; |
1061 const AsyncCallStackTracker::AsyncCallStackVector& callStacks = chain->callS
tacks(); | 1118 const AsyncCallStackTracker::AsyncCallStackVector& callStacks = chain->callS
tacks(); |
1062 if (callStacks.isEmpty()) | 1119 if (callStacks.isEmpty()) |
1063 return nullptr; | 1120 return nullptr; |
1064 RefPtr<WebCore::TypeBuilder::Debugger::StackTrace> result; | 1121 RefPtr<WebCore::TypeBuilder::Debugger::StackTrace> result; |
1065 int asyncOrdinal = callStacks.size(); | 1122 int asyncOrdinal = callStacks.size(); |
1066 for (AsyncCallStackTracker::AsyncCallStackVector::const_reverse_iterator it
= callStacks.rbegin(); it != callStacks.rend(); ++it) { | 1123 for (AsyncCallStackTracker::AsyncCallStackVector::const_reverse_iterator it
= callStacks.rbegin(); it != callStacks.rend(); ++it) { |
1067 RefPtr<WebCore::TypeBuilder::Debugger::StackTrace> next = WebCore::TypeB
uilder::Debugger::StackTrace::create() | 1124 RefPtr<WebCore::TypeBuilder::Debugger::StackTrace> next = WebCore::TypeB
uilder::Debugger::StackTrace::create() |
1068 .setCallFrames(injectedScript.wrapCallFrames((*it)->callFrames(), as
yncOrdinal--)) | 1125 .setCallFrames(callFrames((*it)->callFrames(), asyncOrdinal--)) |
1069 .release(); | 1126 .release(); |
1070 next->setDescription((*it)->description()); | 1127 next->setDescription((*it)->description()); |
1071 if (result) | 1128 if (result) |
1072 next->setAsyncStackTrace(result.release()); | 1129 next->setAsyncStackTrace(result.release()); |
1073 result.swap(next); | 1130 result.swap(next); |
1074 } | 1131 } |
1075 return result.release(); | 1132 return result.release(); |
1076 } | 1133 } |
1077 | 1134 |
1078 String InspectorDebuggerAgent::sourceMapURLForScript(const Script& script) | 1135 String InspectorDebuggerAgent::sourceMapURLForScript(const Script& script) |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1140 if (location) | 1197 if (location) |
1141 m_frontend->breakpointResolved(it->key, location); | 1198 m_frontend->breakpointResolved(it->key, location); |
1142 } | 1199 } |
1143 } | 1200 } |
1144 | 1201 |
1145 void InspectorDebuggerAgent::failedToParseSource(const String& url, const String
& data, int firstLine, int errorLine, const String& errorMessage) | 1202 void InspectorDebuggerAgent::failedToParseSource(const String& url, const String
& data, int firstLine, int errorLine, const String& errorMessage) |
1146 { | 1203 { |
1147 m_frontend->scriptFailedToParse(url, data, firstLine, errorLine, errorMessag
e); | 1204 m_frontend->scriptFailedToParse(url, data, firstLine, errorLine, errorMessag
e); |
1148 } | 1205 } |
1149 | 1206 |
1150 ScriptDebugListener::SkipPauseRequest InspectorDebuggerAgent::didPause(ScriptSta
te* scriptState, const StackTrace& callFrames, const ScriptValue& exception, con
st Vector<String>& hitBreakpoints) | 1207 ScriptDebugListener::SkipPauseRequest InspectorDebuggerAgent::didPause(ScriptSta
te* scriptState, const ScriptValue& exception, const Vector<String>& hitBreakpoi
nts) |
1151 { | 1208 { |
| 1209 const StackTraces& callFrames = scriptDebugServer().currentCallFrames(); |
1152 ScriptDebugListener::SkipPauseRequest result; | 1210 ScriptDebugListener::SkipPauseRequest result; |
1153 if (m_javaScriptPauseScheduled) | 1211 if (m_javaScriptPauseScheduled) |
1154 result = ScriptDebugListener::NoSkip; // Don't skip explicit pause reque
sts from front-end. | 1212 result = ScriptDebugListener::NoSkip; // Don't skip explicit pause reque
sts from front-end. |
1155 else if (m_skipAllPauses) | 1213 else if (m_skipAllPauses) |
1156 result = ScriptDebugListener::Continue; | 1214 result = ScriptDebugListener::Continue; |
1157 else if (!hitBreakpoints.isEmpty()) | 1215 else if (!hitBreakpoints.isEmpty()) |
1158 result = ScriptDebugListener::NoSkip; // Don't skip explicit breakpoints
even if set in frameworks. | 1216 result = ScriptDebugListener::NoSkip; // Don't skip explicit breakpoints
even if set in frameworks. |
1159 else if (!exception.isEmpty()) | 1217 else if (!exception.isEmpty()) |
1160 result = shouldSkipExceptionPause(); | 1218 result = shouldSkipExceptionPause(); |
1161 else if (m_debuggerStepScheduled || m_pausingOnNativeEvent) | 1219 else if (m_debuggerStepScheduled || m_pausingOnNativeEvent) |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1204 m_continueToLocationBreakpointId = ""; | 1262 m_continueToLocationBreakpointId = ""; |
1205 } | 1263 } |
1206 if (m_listener) | 1264 if (m_listener) |
1207 m_listener->didPause(); | 1265 m_listener->didPause(); |
1208 return result; | 1266 return result; |
1209 } | 1267 } |
1210 | 1268 |
1211 void InspectorDebuggerAgent::didContinue() | 1269 void InspectorDebuggerAgent::didContinue() |
1212 { | 1270 { |
1213 m_pausedScriptState = nullptr; | 1271 m_pausedScriptState = nullptr; |
1214 m_currentCallStack = StackTrace(); | 1272 m_currentCallStack = StackTraces(); |
1215 clearBreakDetails(); | 1273 clearBreakDetails(); |
1216 m_frontend->resumed(); | 1274 m_frontend->resumed(); |
1217 } | 1275 } |
1218 | 1276 |
1219 bool InspectorDebuggerAgent::canBreakProgram() | 1277 bool InspectorDebuggerAgent::canBreakProgram() |
1220 { | 1278 { |
1221 return scriptDebugServer().canBreakProgram(); | 1279 return scriptDebugServer().canBreakProgram(); |
1222 } | 1280 } |
1223 | 1281 |
1224 void InspectorDebuggerAgent::breakProgram(InspectorFrontend::Debugger::Reason::E
num breakReason, PassRefPtr<JSONObject> data) | 1282 void InspectorDebuggerAgent::breakProgram(InspectorFrontend::Debugger::Reason::E
num breakReason, PassRefPtr<JSONObject> data) |
1225 { | 1283 { |
1226 if (m_skipAllPauses) | 1284 if (m_skipAllPauses) |
1227 return; | 1285 return; |
1228 m_breakReason = breakReason; | 1286 m_breakReason = breakReason; |
1229 m_breakAuxData = data; | 1287 m_breakAuxData = data; |
1230 m_debuggerStepScheduled = false; | 1288 m_debuggerStepScheduled = false; |
1231 m_pausingOnNativeEvent = false; | 1289 m_pausingOnNativeEvent = false; |
1232 scriptDebugServer().breakProgram(); | 1290 scriptDebugServer().breakProgram(); |
1233 } | 1291 } |
1234 | 1292 |
1235 void InspectorDebuggerAgent::clear() | 1293 void InspectorDebuggerAgent::clear() |
1236 { | 1294 { |
1237 m_pausedScriptState = nullptr; | 1295 m_pausedScriptState = nullptr; |
1238 m_currentCallStack = StackTrace(); | 1296 m_currentCallStack = StackTraces(); |
1239 m_scripts.clear(); | 1297 m_scripts.clear(); |
1240 m_breakpointIdToDebugServerBreakpointIds.clear(); | 1298 m_breakpointIdToDebugServerBreakpointIds.clear(); |
1241 m_asyncCallStackTracker.clear(); | 1299 m_asyncCallStackTracker.clear(); |
1242 m_continueToLocationBreakpointId = String(); | 1300 m_continueToLocationBreakpointId = String(); |
1243 clearBreakDetails(); | 1301 clearBreakDetails(); |
1244 m_javaScriptPauseScheduled = false; | 1302 m_javaScriptPauseScheduled = false; |
1245 m_debuggerStepScheduled = false; | 1303 m_debuggerStepScheduled = false; |
1246 m_pausingOnNativeEvent = false; | 1304 m_pausingOnNativeEvent = false; |
1247 ErrorString error; | 1305 ErrorString error; |
1248 setOverlayMessage(&error, 0); | 1306 setOverlayMessage(&error, 0); |
(...skipping 30 matching lines...) Expand all Loading... |
1279 { | 1337 { |
1280 m_scripts.clear(); | 1338 m_scripts.clear(); |
1281 m_breakpointIdToDebugServerBreakpointIds.clear(); | 1339 m_breakpointIdToDebugServerBreakpointIds.clear(); |
1282 m_asyncCallStackTracker.clear(); | 1340 m_asyncCallStackTracker.clear(); |
1283 if (m_frontend) | 1341 if (m_frontend) |
1284 m_frontend->globalObjectCleared(); | 1342 m_frontend->globalObjectCleared(); |
1285 } | 1343 } |
1286 | 1344 |
1287 } // namespace WebCore | 1345 } // namespace WebCore |
1288 | 1346 |
OLD | NEW |