Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(985)

Unified Diff: third_party/WebKit/Source/platform/v8_inspector/V8DebuggerAgentImpl.cpp

Issue 1902993002: [DevTools] Introduce provisional blackboxing (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/platform/v8_inspector/V8DebuggerAgentImpl.cpp
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerAgentImpl.cpp b/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerAgentImpl.cpp
index 5ae6ce42f24f9f034be08295857845781a58c57f..db4a83c3928319ffc4c480136422a19b3d03a701 100644
--- a/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerAgentImpl.cpp
+++ b/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerAgentImpl.cpp
@@ -45,6 +45,11 @@ namespace DebuggerAgentState {
static const char javaScriptBreakpoints[] = "javaScriptBreakopints";
static const char pauseOnExceptionsState[] = "pauseOnExceptionsState";
static const char asyncCallStackDepth[] = "asyncCallStackDepth";
+static const char blackboxPatterns[] = "blackboxPatterns";
+static const char blackboxRangesByURL[] = "blackboxRangesByURL";
+static const char blackboxRangesByHash[] = "blackboxRangesByHash";
+static const char blackboxScriptsByURL[] = "blackboxScriptsByURL";
+static const char blackboxScriptsByHash[] = "blackboxScriptsByHash";
// Breakpoint properties.
static const char url[] = "url";
@@ -236,7 +241,6 @@ void V8DebuggerAgentImpl::disable(ErrorString*)
JavaScriptCallFrames emptyCallFrames;
m_pausedCallFrames.swap(emptyCallFrames);
m_scripts.clear();
- m_blackboxedPositions.clear();
m_breakpointIdToDebuggerBreakpointIds.clear();
internalSetAsyncCallStackDepth(0);
m_continueToLocationBreakpointId = String16();
@@ -250,6 +254,10 @@ void V8DebuggerAgentImpl::disable(ErrorString*)
m_recursionLevelForStepFrame = 0;
m_skipAllPauses = false;
m_enabled = false;
+
+ m_blackboxPattern = nullptr;
+ m_blackboxRangesByHash.clear();
+ m_blackboxRangesByURL.clear();
}
void V8DebuggerAgentImpl::internalSetAsyncCallStackDepth(int depth)
@@ -284,12 +292,63 @@ void V8DebuggerAgentImpl::restore()
int pauseState = V8DebuggerImpl::DontPauseOnExceptions;
m_state->getNumber(DebuggerAgentState::pauseOnExceptionsState, &pauseState);
setPauseOnExceptionsImpl(&error, pauseState);
+ ASSERT(error.isEmpty());
m_skipAllPauses = m_state->booleanProperty(DebuggerAgentState::skipAllPauses, false);
int asyncCallStackDepth = 0;
m_state->getNumber(DebuggerAgentState::asyncCallStackDepth, &asyncCallStackDepth);
internalSetAsyncCallStackDepth(asyncCallStackDepth);
+
+ protocol::ListValue* blackboxPatternsValue = m_state->getArray(DebuggerAgentState::blackboxPatterns);
+ if (blackboxPatternsValue) {
+ protocol::ErrorSupport errors;
+ OwnPtr<protocol::Array<String16>> blackboxPatterns = protocol::Array<String16>::parse(blackboxPatternsValue, &errors);
+ if (blackboxPatterns)
+ setBlackboxPatterns(&error, blackboxPatterns.release());
+ ASSERT(!errors.hasErrors() && error.isEmpty());
+ }
+ restoreBlackboxScripts(DebuggerAgentState::blackboxScriptsByHash, m_blackboxRangesByHash);
dgozman 2016/04/20 02:06:40 Can we use empty ranges as a meaning for "fully bl
+ restoreBlackboxScripts(DebuggerAgentState::blackboxScriptsByURL, m_blackboxRangesByURL);
+ restoreBlackboxRanges(DebuggerAgentState::blackboxRangesByHash, m_blackboxRangesByHash);
+ restoreBlackboxRanges(DebuggerAgentState::blackboxRangesByURL, m_blackboxRangesByURL);
+}
+
+void V8DebuggerAgentImpl::restoreBlackboxScripts(const String16& key, BlackboxRangesByString& map)
+{
+ protocol::ListValue* list = m_state->getArray(key);
+ if (!list)
+ return;
+ Vector<std::pair<int, int>> blackboxedRanges(1);
+ for (size_t i = 0; i < list->size(); ++i) {
+ protocol::Value* val = list->at(i);
+ String16 id;
+ bool success = val->asString(&id);
+ ASSERT_UNUSED(success, success);
+ map.set(id, blackboxedRanges);
+ }
+}
+
+void V8DebuggerAgentImpl::restoreBlackboxRanges(const String16& key, BlackboxRangesByString& map)
+{
+ using protocol::Runtime::SourceRange;
+
+ protocol::DictionaryValue* storedMap = m_state->getObject(key);
+ if (!storedMap)
+ return;
+ protocol::ErrorSupport errorSupport;
+ for (size_t i = 0; i < storedMap->size(); ++i) {
+ auto value = storedMap->at(i);
+ OwnPtr<protocol::Array<SourceRange>> ranges = protocol::Array<SourceRange>::parse(value.second, &errorSupport);
+ ASSERT(!errorSupport.hasErrors());
+ Vector<std::pair<int, int>> blackboxedRanges(ranges->length() * 2);
+ for (size_t i = 0; i < ranges->length(); ++i) {
+ SourceRange* range = ranges->get(i);
+ blackboxedRanges[i * 2] = std::make_pair(range->getStartLine(), range->getStartColumn());
+ blackboxedRanges[i * 2 + 1] = std::make_pair(range->getEndLine(), range->getEndColumn());
+ }
+ map.set(value.first, blackboxedRanges);
+ }
}
void V8DebuggerAgentImpl::setBreakpointsActive(ErrorString* errorString, bool active)
@@ -505,11 +564,23 @@ bool V8DebuggerAgentImpl::isCallFrameWithUnknownScriptOrBlackboxed(JavaScriptCal
// Unknown scripts are blackboxed.
return true;
}
- auto itBlackboxedPositions = m_blackboxedPositions.find(String16::number(frame->sourceID()));
- if (itBlackboxedPositions == m_blackboxedPositions.end())
+ V8DebuggerScript* script = it->second;
+ if (m_blackboxPattern) {
+ String16 scriptSourceURL = script->sourceURL();
+ if (!scriptSourceURL.isEmpty() && m_blackboxPattern->match(scriptSourceURL) != -1)
+ return true;
+ }
+ auto itBlackboxedRangesByHash = m_blackboxRangesByHash.find(script->hash());
+ const Vector<std::pair<int, int>>* ranges = nullptr;
+ if (itBlackboxedRangesByHash != m_blackboxRangesByHash.end()) {
+ ranges = itBlackboxedRangesByHash->second;
+ } else {
+ auto itBlackboxedRangesByURL = m_blackboxRangesByURL.find(script->sourceURL());
+ if (itBlackboxedRangesByURL != m_blackboxRangesByURL.end())
+ ranges = itBlackboxedRangesByURL->second;
+ }
+ if (!ranges)
return false;
-
- protocol::Vector<std::pair<int, int>>* ranges = itBlackboxedPositions->second;
auto itRange = std::lower_bound(ranges->begin(), ranges->end(), std::make_pair(frame->line(), frame->column()), positionComparator);
// Ranges array contains positions in script where blackbox state is changed.
// [(0,0) ... ranges[0]) isn't blackboxed, [ranges[0] ... ranges[1]) is blackboxed...
@@ -1050,42 +1121,92 @@ void V8DebuggerAgentImpl::allAsyncTasksCanceled()
#endif
}
-void V8DebuggerAgentImpl::setBlackboxedRanges(ErrorString* error, const String16& scriptId, PassOwnPtr<protocol::Array<protocol::Debugger::ScriptPosition>> inPositions)
+void V8DebuggerAgentImpl::setBlackboxPatterns(ErrorString* errorString, PassOwnPtr<protocol::Array<String16>> patterns)
{
- if (!m_scripts.contains(scriptId)) {
- *error = "No script with passed id.";
+ if (!patterns->length()) {
+ m_blackboxPattern = nullptr;
+ m_state->setArray(DebuggerAgentState::blackboxPatterns, patterns->serialize());
return;
}
- if (!inPositions->length()) {
- m_blackboxedPositions.remove(scriptId);
+ String16 pattern;
+ for (size_t i = 0; i < patterns->length() - 1; ++i)
+ pattern = pattern + patterns->get(i) + "|";
+ pattern = "(" + pattern + patterns->get(patterns->length() - 1) + ")";
+
+ OwnPtr<V8Regex> regex = adoptPtr(new V8Regex(m_debugger, pattern, true /** caseSensitive */, false /** multiline */));
+ if (!regex->isValid()) {
+ *errorString = "Pattern parser error: " + regex->errorMessage();
return;
}
- protocol::Vector<std::pair<int, int>> positions(inPositions->length());
- for (size_t i = 0; i < positions.size(); ++i) {
- protocol::Debugger::ScriptPosition* position = inPositions->get(i);
- if (position->getLine() < 0) {
- *error = "Position missing 'line' or 'line' < 0.";
- return;
- }
- if (position->getColumn() < 0) {
- *error = "Position missing 'column' or 'column' < 0.";
- return;
+ m_blackboxPattern = regex.release();
+ m_state->setArray(DebuggerAgentState::blackboxPatterns, patterns->serialize());
+}
+
+void V8DebuggerAgentImpl::setScriptBlackboxed(ErrorString* errorString, const Maybe<String16>& hash, const Maybe<String16>& url, const Maybe<protocol::Array<protocol::Runtime::SourceRange>>& optRanges)
+{
+ using protocol::Runtime::SourceRange;
+
+ if (!hash.isJust() && !url.isJust()) {
+ *errorString = "Hash or URL should be set";
+ return;
+ }
+ BlackboxRangesByString& idToBlackboxRanges = hash.isJust() ? m_blackboxRangesByHash : m_blackboxRangesByURL;
+ String16 id = hash.isJust() ? hash.fromJust() : url.fromJust();
+
+ if (!optRanges.isJust()) {
+ const String16& stateKey = hash.isJust() ? DebuggerAgentState::blackboxScriptsByHash : DebuggerAgentState::blackboxScriptsByURL;
+ protocol::ListValue* stateBlackboxedScripts = m_state->getArray(stateKey);
+ if (!stateBlackboxedScripts) {
+ m_state->setArray(stateKey, protocol::ListValue::create());
+ stateBlackboxedScripts = m_state->getArray(stateKey);
}
- positions[i] = std::make_pair(position->getLine(), position->getColumn());
+
+ Vector<std::pair<int, int>> blackboxedRanges(1);
+ idToBlackboxRanges.set(id, blackboxedRanges);
+ stateBlackboxedScripts->pushValue(protocol::StringValue::create(id));
+ return;
}
- for (size_t i = 1; i < positions.size(); ++i) {
- if (positions[i - 1].first < positions[i].first)
- continue;
- if (positions[i - 1].first == positions[i].first && positions[i - 1].second < positions[i].second)
- continue;
- *error = "Input positions array is not sorted or contains duplicate values.";
+ const String16& stateKey = hash.isJust() ? DebuggerAgentState::blackboxRangesByHash : DebuggerAgentState::blackboxRangesByURL;
+ protocol::DictionaryValue* stateMap = m_state->getObject(stateKey);
+ if (!stateMap) {
+ m_state->setObject(stateKey, protocol::DictionaryValue::create());
+ stateMap = m_state->getObject(stateKey);
+ }
+ protocol::Array<SourceRange>* ranges = optRanges.fromJust();
+ if (!ranges->length()) {
+ idToBlackboxRanges.remove(id);
+ stateMap->remove(id);
return;
}
- m_blackboxedPositions.set(scriptId, positions);
+ String16 errors;
dgozman 2016/04/20 02:06:40 Let's extract validation into a helper function.
+ for (size_t i = 0; i < ranges->length(); ++i) {
+ SourceRange* range = ranges->get(i);
+ if (range->getStartLine() > range->getEndLine())
+ errors = errors + " 'startLine' should be not more then 'endLine' in (" + String16::number(i + 1) + ").";
+ if (range->getStartLine() == range->getEndLine() && range->getStartColumn() >= range->getEndColumn())
+ errors = errors + " 'startColumn' should be less then 'endColumn' if 'startLine' == 'endLine' in (" + String16::number(i + 1) + ").";
+ if (i > 0) {
+ SourceRange* prevRange = ranges->get(i - 1);
+ if (prevRange->getEndLine() > range->getStartLine() || (prevRange->getEndLine() == range->getStartLine() && prevRange->getEndColumn() > range->getStartColumn()))
+ errors = errors + " Records in ranges array should be sorted and disjoint.";
+ }
+ }
+ if (!errors.isEmpty()) {
+ *errorString = errors;
+ return;
+ }
+ Vector<std::pair<int, int>> blackboxedRanges(ranges->length() * 2);
+ for (size_t i = 0; i < ranges->length(); ++i) {
+ SourceRange* range = ranges->get(i);
+ blackboxedRanges[i * 2] = std::make_pair(range->getStartLine(), range->getStartColumn());
+ blackboxedRanges[i * 2 + 1] = std::make_pair(range->getEndLine(), range->getEndColumn());
+ }
+ idToBlackboxRanges.set(id, blackboxedRanges);
+ stateMap->setArray(id, ranges->serialize());
}
void V8DebuggerAgentImpl::willExecuteScript(int scriptId)
@@ -1415,7 +1536,6 @@ void V8DebuggerAgentImpl::reset()
return;
m_scheduledDebuggerStep = NoStep;
m_scripts.clear();
- m_blackboxedPositions.clear();
m_breakpointIdToDebuggerBreakpointIds.clear();
allAsyncTasksCanceled();
}

Powered by Google App Engine
This is Rietveld 408576698