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

Side by Side Diff: src/inspector/v8-debugger.cc

Issue 2906153002: [inspector] Support multiple sessions per context group (Closed)
Patch Set: using set per kozy@ Created 3 years, 6 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 unified diff | Download patch
« no previous file with comments | « src/inspector/v8-debugger.h ('k') | src/inspector/v8-debugger-agent-impl.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/inspector/v8-debugger.h" 5 #include "src/inspector/v8-debugger.h"
6 6
7 #include "src/inspector/debugger-script.h" 7 #include "src/inspector/debugger-script.h"
8 #include "src/inspector/inspected-context.h" 8 #include "src/inspector/inspected-context.h"
9 #include "src/inspector/protocol/Protocol.h" 9 #include "src/inspector/protocol/Protocol.h"
10 #include "src/inspector/script-breakpoint.h" 10 #include "src/inspector/script-breakpoint.h"
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 v8::debug::DebugBreak(m_isolate); 340 v8::debug::DebugBreak(m_isolate);
341 else 341 else
342 v8::debug::CancelDebugBreak(m_isolate); 342 v8::debug::CancelDebugBreak(m_isolate);
343 } 343 }
344 344
345 bool V8Debugger::canBreakProgram() { 345 bool V8Debugger::canBreakProgram() {
346 if (!m_breakpointsActivated) return false; 346 if (!m_breakpointsActivated) return false;
347 return !v8::debug::AllFramesOnStackAreBlackboxed(m_isolate); 347 return !v8::debug::AllFramesOnStackAreBlackboxed(m_isolate);
348 } 348 }
349 349
350 bool V8Debugger::breakProgram(int targetContextGroupId) { 350 void V8Debugger::breakProgram(int targetContextGroupId) {
351 // Don't allow nested breaks. 351 // Don't allow nested breaks.
352 if (isPaused()) return true; 352 if (isPaused()) return;
353 if (!canBreakProgram()) return true; 353 if (!canBreakProgram()) return;
354 DCHECK(targetContextGroupId); 354 DCHECK(targetContextGroupId);
355 m_targetContextGroupId = targetContextGroupId; 355 m_targetContextGroupId = targetContextGroupId;
356 v8::debug::BreakRightNow(m_isolate); 356 v8::debug::BreakRightNow(m_isolate);
357 V8InspectorSessionImpl* session =
358 m_inspector->sessionForContextGroup(targetContextGroupId);
359 return session && session->debuggerAgent()->enabled();
360 } 357 }
361 358
362 void V8Debugger::continueProgram(int targetContextGroupId) { 359 void V8Debugger::continueProgram(int targetContextGroupId) {
363 if (m_pausedContextGroupId != targetContextGroupId) return; 360 if (m_pausedContextGroupId != targetContextGroupId) return;
364 if (isPaused()) m_inspector->client()->quitMessageLoopOnPause(); 361 if (isPaused()) m_inspector->client()->quitMessageLoopOnPause();
365 m_pausedContext.Clear(); 362 m_pausedContext.Clear();
366 m_executionState.Clear(); 363 m_executionState.Clear();
367 } 364 }
368 365
369 void V8Debugger::stepIntoStatement(int targetContextGroupId) { 366 void V8Debugger::stepIntoStatement(int targetContextGroupId) {
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 v8::debug::PrepareStep(m_isolate, v8::debug::StepOut); 590 v8::debug::PrepareStep(m_isolate, v8::debug::StepOut);
594 return; 591 return;
595 } 592 }
596 m_targetContextGroupId = 0; 593 m_targetContextGroupId = 0;
597 if (m_stepIntoAsyncCallback) { 594 if (m_stepIntoAsyncCallback) {
598 m_stepIntoAsyncCallback->sendFailure( 595 m_stepIntoAsyncCallback->sendFailure(
599 Response::Error("No async tasks were scheduled before pause.")); 596 Response::Error("No async tasks were scheduled before pause."));
600 m_stepIntoAsyncCallback.reset(); 597 m_stepIntoAsyncCallback.reset();
601 } 598 }
602 m_breakRequested = false; 599 m_breakRequested = false;
603 V8InspectorSessionImpl* session = 600
604 m_inspector->sessionForContextGroup(contextGroupId); 601 bool scheduledOOMBreak = m_scheduledOOMBreak;
605 if (!session || !session->debuggerAgent()->enabled()) return; 602 auto agentCheck = [&scheduledOOMBreak](V8DebuggerAgentImpl* agent) {
606 if (!m_scheduledOOMBreak && session->debuggerAgent()->skipAllPauses()) return; 603 return agent->enabled() && (scheduledOOMBreak || !agent->skipAllPauses());
604 };
605
606 bool hasAgents = false;
607 m_inspector->forEachSession(
608 contextGroupId,
609 [&agentCheck, &hasAgents](V8InspectorSessionImpl* session) {
610 if (agentCheck(session->debuggerAgent())) hasAgents = true;
611 });
612 if (!hasAgents) return;
607 613
608 std::vector<String16> breakpointIds; 614 std::vector<String16> breakpointIds;
609 if (!hitBreakpointNumbers.IsEmpty()) { 615 if (!hitBreakpointNumbers.IsEmpty()) {
610 breakpointIds.reserve(hitBreakpointNumbers->Length()); 616 breakpointIds.reserve(hitBreakpointNumbers->Length());
611 for (uint32_t i = 0; i < hitBreakpointNumbers->Length(); i++) { 617 for (uint32_t i = 0; i < hitBreakpointNumbers->Length(); i++) {
612 v8::Local<v8::Value> hitBreakpointNumber = 618 v8::Local<v8::Value> hitBreakpointNumber =
613 hitBreakpointNumbers->Get(debuggerContext(), i).ToLocalChecked(); 619 hitBreakpointNumbers->Get(debuggerContext(), i).ToLocalChecked();
614 DCHECK(hitBreakpointNumber->IsInt32()); 620 DCHECK(hitBreakpointNumber->IsInt32());
615 breakpointIds.push_back(String16::fromInteger( 621 breakpointIds.push_back(String16::fromInteger(
616 hitBreakpointNumber->Int32Value(debuggerContext()).FromJust())); 622 hitBreakpointNumber->Int32Value(debuggerContext()).FromJust()));
617 } 623 }
618 if (breakpointIds.size() == 1 && 624 if (breakpointIds.size() == 1 &&
619 breakpointIds[0] == m_continueToLocationBreakpointId) { 625 breakpointIds[0] == m_continueToLocationBreakpointId) {
620 v8::Context::Scope contextScope(pausedContext); 626 v8::Context::Scope contextScope(pausedContext);
621 if (!shouldContinueToCurrentLocation()) return; 627 if (!shouldContinueToCurrentLocation()) return;
622 } 628 }
623 } 629 }
624 clearContinueToLocation(); 630 clearContinueToLocation();
625 631
626 DCHECK(contextGroupId); 632 DCHECK(contextGroupId);
627 m_pausedContext = pausedContext; 633 m_pausedContext = pausedContext;
628 m_executionState = executionState; 634 m_executionState = executionState;
629 m_pausedContextGroupId = contextGroupId; 635 m_pausedContextGroupId = contextGroupId;
630 session->debuggerAgent()->didPause( 636
631 InspectedContext::contextId(pausedContext), exception, breakpointIds, 637 m_inspector->forEachSession(
632 isPromiseRejection, isUncaught, m_scheduledOOMBreak); 638 contextGroupId, [&agentCheck, &pausedContext, &exception, &breakpointIds,
639 &isPromiseRejection, &isUncaught,
640 &scheduledOOMBreak](V8InspectorSessionImpl* session) {
641 if (agentCheck(session->debuggerAgent())) {
642 session->debuggerAgent()->didPause(
643 InspectedContext::contextId(pausedContext), exception,
644 breakpointIds, isPromiseRejection, isUncaught, scheduledOOMBreak);
645 }
646 });
633 { 647 {
634 v8::Context::Scope scope(pausedContext); 648 v8::Context::Scope scope(pausedContext);
635 v8::Local<v8::Context> context = m_isolate->GetCurrentContext(); 649 v8::Local<v8::Context> context = m_isolate->GetCurrentContext();
636 CHECK(!context.IsEmpty() && 650 CHECK(!context.IsEmpty() &&
637 context != v8::debug::GetDebugContext(m_isolate)); 651 context != v8::debug::GetDebugContext(m_isolate));
638 m_inspector->client()->runMessageLoopOnPause(contextGroupId); 652 m_inspector->client()->runMessageLoopOnPause(contextGroupId);
639 m_pausedContextGroupId = 0; 653 m_pausedContextGroupId = 0;
640 } 654 }
641 // The agent may have been removed in the nested loop. 655 m_inspector->forEachSession(contextGroupId,
642 session = m_inspector->sessionForContextGroup(contextGroupId); 656 [](V8InspectorSessionImpl* session) {
643 if (session && session->debuggerAgent()->enabled()) 657 if (session->debuggerAgent()->enabled())
644 session->debuggerAgent()->didContinue(); 658 session->debuggerAgent()->didContinue();
659 });
660
645 if (m_scheduledOOMBreak) m_isolate->RestoreOriginalHeapLimit(); 661 if (m_scheduledOOMBreak) m_isolate->RestoreOriginalHeapLimit();
646 m_scheduledOOMBreak = false; 662 m_scheduledOOMBreak = false;
647 m_pausedContext.Clear(); 663 m_pausedContext.Clear();
648 m_executionState.Clear(); 664 m_executionState.Clear();
649 } 665 }
650 666
651 void V8Debugger::v8OOMCallback(void* data) { 667 void V8Debugger::v8OOMCallback(void* data) {
652 V8Debugger* thisPtr = static_cast<V8Debugger*>(data); 668 V8Debugger* thisPtr = static_cast<V8Debugger*>(data);
653 thisPtr->m_isolate->IncreaseHeapLimitForDebugging(); 669 thisPtr->m_isolate->IncreaseHeapLimitForDebugging();
654 thisPtr->m_scheduledOOMBreak = true; 670 thisPtr->m_scheduledOOMBreak = true;
655 v8::Local<v8::Context> context = thisPtr->m_isolate->GetEnteredContext(); 671 v8::Local<v8::Context> context = thisPtr->m_isolate->GetEnteredContext();
656 DCHECK(!context.IsEmpty()); 672 DCHECK(!context.IsEmpty());
657 thisPtr->setPauseOnNextStatement( 673 thisPtr->setPauseOnNextStatement(
658 true, thisPtr->m_inspector->contextGroupId(context)); 674 true, thisPtr->m_inspector->contextGroupId(context));
659 } 675 }
660 676
661 void V8Debugger::ScriptCompiled(v8::Local<v8::debug::Script> script, 677 void V8Debugger::ScriptCompiled(v8::Local<v8::debug::Script> script,
662 bool has_compile_error) { 678 bool has_compile_error) {
663 int contextId; 679 int contextId;
664 if (!script->ContextId().To(&contextId)) return; 680 if (!script->ContextId().To(&contextId)) return;
665 V8InspectorSessionImpl* session = m_inspector->sessionForContextGroup(
666 m_inspector->contextGroupId(contextId));
667 if (!session || !session->debuggerAgent()->enabled()) return;
668 if (script->IsWasm()) { 681 if (script->IsWasm()) {
669 m_wasmTranslation.AddScript(script.As<v8::debug::WasmScript>(), 682 WasmTranslation* wasmTranslation = &m_wasmTranslation;
670 session->debuggerAgent()); 683 m_inspector->forEachSession(
684 m_inspector->contextGroupId(contextId),
685 [&script, &wasmTranslation](V8InspectorSessionImpl* session) {
686 if (!session->debuggerAgent()->enabled()) return;
687 wasmTranslation->AddScript(script.As<v8::debug::WasmScript>(),
688 session->debuggerAgent());
689 });
671 } else if (m_ignoreScriptParsedEventsCounter == 0) { 690 } else if (m_ignoreScriptParsedEventsCounter == 0) {
672 session->debuggerAgent()->didParseSource( 691 v8::Isolate* isolate = m_isolate;
673 V8DebuggerScript::Create(m_isolate, script, inLiveEditScope), 692 m_inspector->forEachSession(
674 !has_compile_error); 693 m_inspector->contextGroupId(contextId),
694 [&isolate, &script,
695 &has_compile_error](V8InspectorSessionImpl* session) {
696 if (!session->debuggerAgent()->enabled()) return;
697 session->debuggerAgent()->didParseSource(
698 V8DebuggerScript::Create(isolate, script, inLiveEditScope),
699 !has_compile_error);
700 });
675 } 701 }
676 } 702 }
677 703
678 void V8Debugger::BreakProgramRequested(v8::Local<v8::Context> pausedContext, 704 void V8Debugger::BreakProgramRequested(v8::Local<v8::Context> pausedContext,
679 v8::Local<v8::Object> execState, 705 v8::Local<v8::Object> execState,
680 v8::Local<v8::Value> breakPointsHit) { 706 v8::Local<v8::Value> breakPointsHit) {
681 v8::Local<v8::Value> argv[] = {breakPointsHit}; 707 v8::Local<v8::Value> argv[] = {breakPointsHit};
682 v8::Local<v8::Value> hitBreakpoints; 708 v8::Local<v8::Value> hitBreakpoints;
683 if (!callDebuggerMethod("getBreakpointNumbers", 1, argv, true) 709 if (!callDebuggerMethod("getBreakpointNumbers", 1, argv, true)
684 .ToLocal(&hitBreakpoints)) { 710 .ToLocal(&hitBreakpoints)) {
(...skipping 12 matching lines...) Expand all
697 bool isPromiseRejection = promise->IsPromise(); 723 bool isPromiseRejection = promise->IsPromise();
698 handleProgramBreak(pausedContext, execState, exception, 724 handleProgramBreak(pausedContext, execState, exception,
699 v8::Local<v8::Array>(), isPromiseRejection, isUncaught); 725 v8::Local<v8::Array>(), isPromiseRejection, isUncaught);
700 } 726 }
701 727
702 bool V8Debugger::IsFunctionBlackboxed(v8::Local<v8::debug::Script> script, 728 bool V8Debugger::IsFunctionBlackboxed(v8::Local<v8::debug::Script> script,
703 const v8::debug::Location& start, 729 const v8::debug::Location& start,
704 const v8::debug::Location& end) { 730 const v8::debug::Location& end) {
705 int contextId; 731 int contextId;
706 if (!script->ContextId().To(&contextId)) return false; 732 if (!script->ContextId().To(&contextId)) return false;
707 V8InspectorSessionImpl* session = m_inspector->sessionForContextGroup( 733 bool hasAgents = false;
708 m_inspector->contextGroupId(contextId)); 734 bool allBlackboxed = true;
709 if (!session || !session->debuggerAgent()->enabled()) return false; 735 String16 scriptId = String16::fromInteger(script->Id());
710 return session->debuggerAgent()->isFunctionBlackboxed( 736 m_inspector->forEachSession(
711 String16::fromInteger(script->Id()), start, end); 737 m_inspector->contextGroupId(contextId),
738 [&hasAgents, &allBlackboxed, &scriptId, &start,
739 &end](V8InspectorSessionImpl* session) {
740 V8DebuggerAgentImpl* agent = session->debuggerAgent();
741 if (!agent->enabled()) return;
742 hasAgents = true;
743 allBlackboxed &= agent->isFunctionBlackboxed(scriptId, start, end);
744 });
745 return hasAgents && allBlackboxed;
712 } 746 }
713 747
714 void V8Debugger::PromiseEventOccurred(v8::debug::PromiseDebugActionType type, 748 void V8Debugger::PromiseEventOccurred(v8::debug::PromiseDebugActionType type,
715 int id, int parentId, 749 int id, int parentId,
716 bool createdByUser) { 750 bool createdByUser) {
717 // Async task events from Promises are given misaligned pointers to prevent 751 // Async task events from Promises are given misaligned pointers to prevent
718 // from overlapping with other Blink task identifiers. 752 // from overlapping with other Blink task identifiers.
719 void* task = reinterpret_cast<void*>(id * 2 + 1); 753 void* task = reinterpret_cast<void*>(id * 2 + 1);
720 void* parentTask = 754 void* parentTask =
721 parentId ? reinterpret_cast<void*>(parentId * 2 + 1) : nullptr; 755 parentId ? reinterpret_cast<void*>(parentId * 2 + 1) : nullptr;
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after
1077 1111
1078 std::unique_ptr<V8StackTraceImpl> V8Debugger::captureStackTrace( 1112 std::unique_ptr<V8StackTraceImpl> V8Debugger::captureStackTrace(
1079 bool fullStack) { 1113 bool fullStack) {
1080 if (!m_isolate->InContext()) return nullptr; 1114 if (!m_isolate->InContext()) return nullptr;
1081 1115
1082 v8::HandleScope handles(m_isolate); 1116 v8::HandleScope handles(m_isolate);
1083 int contextGroupId = currentContextGroupId(); 1117 int contextGroupId = currentContextGroupId();
1084 if (!contextGroupId) return nullptr; 1118 if (!contextGroupId) return nullptr;
1085 1119
1086 int stackSize = 1; 1120 int stackSize = 1;
1087 V8InspectorSessionImpl* session = 1121 if (fullStack) {
1088 m_inspector->sessionForContextGroup(contextGroupId);
1089 if (fullStack || (session && session->runtimeAgent()->enabled())) {
1090 stackSize = V8StackTraceImpl::maxCallStackSizeToCapture; 1122 stackSize = V8StackTraceImpl::maxCallStackSizeToCapture;
1123 } else {
1124 m_inspector->forEachSession(
1125 contextGroupId, [&stackSize](V8InspectorSessionImpl* session) {
1126 if (session->runtimeAgent()->enabled())
1127 stackSize = V8StackTraceImpl::maxCallStackSizeToCapture;
1128 });
1091 } 1129 }
1092 return V8StackTraceImpl::capture(this, contextGroupId, stackSize); 1130 return V8StackTraceImpl::capture(this, contextGroupId, stackSize);
1093 } 1131 }
1094 1132
1095 int V8Debugger::currentContextGroupId() { 1133 int V8Debugger::currentContextGroupId() {
1096 if (!m_isolate->InContext()) return 0; 1134 if (!m_isolate->InContext()) return 0;
1097 return m_inspector->contextGroupId(m_isolate->GetCurrentContext()); 1135 return m_inspector->contextGroupId(m_isolate->GetCurrentContext());
1098 } 1136 }
1099 1137
1100 void V8Debugger::collectOldAsyncStacksIfNeeded() { 1138 void V8Debugger::collectOldAsyncStacksIfNeeded() {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1155 fprintf(stdout, "Async stacks count: %d\n", m_asyncStacksCount); 1193 fprintf(stdout, "Async stacks count: %d\n", m_asyncStacksCount);
1156 fprintf(stdout, "Scheduled async tasks: %zu\n", m_asyncTaskStacks.size()); 1194 fprintf(stdout, "Scheduled async tasks: %zu\n", m_asyncTaskStacks.size());
1157 fprintf(stdout, "Created async tasks: %zu\n", 1195 fprintf(stdout, "Created async tasks: %zu\n",
1158 m_asyncTaskCreationStacks.size()); 1196 m_asyncTaskCreationStacks.size());
1159 fprintf(stdout, "Async tasks with parent: %zu\n", m_parentTask.size()); 1197 fprintf(stdout, "Async tasks with parent: %zu\n", m_parentTask.size());
1160 fprintf(stdout, "Recurring async tasks: %zu\n", m_recurringTasks.size()); 1198 fprintf(stdout, "Recurring async tasks: %zu\n", m_recurringTasks.size());
1161 fprintf(stdout, "\n"); 1199 fprintf(stdout, "\n");
1162 } 1200 }
1163 1201
1164 } // namespace v8_inspector 1202 } // namespace v8_inspector
OLDNEW
« no previous file with comments | « src/inspector/v8-debugger.h ('k') | src/inspector/v8-debugger-agent-impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698