Commit d8e8dab0 authored by Kim-Anh Tran's avatar Kim-Anh Tran Committed by V8 LUCI CQ

[debugger] Explicitly encode debugger statements in didPause

This CL makes sure to forward the information that we are pausing
because of a debugger statement, and to encode it explicitly
as an 'other' reason when reporting the pause to the front-end.

Drive-by: refactoring the way break reasons are propagated by
introducing a new enum for break reasons

Bug: chromium:1229541, chromium:1133307
Change-Id: I9d2e8d8da54d96a231eff9d1f62b74507955b18f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3306978Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Commit-Queue: Kim-Anh Tran <kimanh@chromium.org>
Cr-Commit-Position: refs/heads/main@{#78202}
parent 70a452ff
...@@ -292,10 +292,12 @@ void ClearStepping(Isolate* v8_isolate) { ...@@ -292,10 +292,12 @@ void ClearStepping(Isolate* v8_isolate) {
isolate->debug()->ClearStepping(); isolate->debug()->ClearStepping();
} }
void BreakRightNow(Isolate* v8_isolate) { void BreakRightNow(Isolate* v8_isolate,
base::EnumSet<debug::BreakReason> break_reasons) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
ENTER_V8_DO_NOT_USE(isolate); ENTER_V8_DO_NOT_USE(isolate);
isolate->debug()->HandleDebugBreak(i::kIgnoreIfAllFramesBlackboxed); isolate->debug()->HandleDebugBreak(i::kIgnoreIfAllFramesBlackboxed,
break_reasons);
} }
void SetTerminateOnResume(Isolate* v8_isolate) { void SetTerminateOnResume(Isolate* v8_isolate) {
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "include/v8-promise.h" #include "include/v8-promise.h"
#include "include/v8-script.h" #include "include/v8-script.h"
#include "include/v8-util.h" #include "include/v8-util.h"
#include "src/base/enum-set.h"
#include "src/base/vector.h" #include "src/base/vector.h"
#include "src/common/globals.h" #include "src/common/globals.h"
#include "src/debug/interface-types.h" #include "src/debug/interface-types.h"
...@@ -119,9 +120,20 @@ enum StepAction { ...@@ -119,9 +120,20 @@ enum StepAction {
// in the current function. // in the current function.
}; };
// Record the reason for why the debugger breaks.
enum class BreakReason : uint8_t {
kStep,
kException,
kAssert,
kDebuggerStatement,
kOOM
};
typedef base::EnumSet<BreakReason> BreakReasons;
void PrepareStep(Isolate* isolate, StepAction action); void PrepareStep(Isolate* isolate, StepAction action);
void ClearStepping(Isolate* isolate); void ClearStepping(Isolate* isolate);
V8_EXPORT_PRIVATE void BreakRightNow(Isolate* isolate); V8_EXPORT_PRIVATE void BreakRightNow(
Isolate* isolate, base::EnumSet<BreakReason> break_reason = {});
// Use `SetTerminateOnResume` to indicate that an TerminateExecution interrupt // Use `SetTerminateOnResume` to indicate that an TerminateExecution interrupt
// should be set shortly before resuming, i.e. shortly before returning into // should be set shortly before resuming, i.e. shortly before returning into
...@@ -221,8 +233,6 @@ enum ExceptionType { kException, kPromiseRejection }; ...@@ -221,8 +233,6 @@ enum ExceptionType { kException, kPromiseRejection };
class DebugDelegate { class DebugDelegate {
public: public:
// Encodes whether a requested break is (also) due to a step action.
enum StepBreak { kIsStepBreak, kIsNoStepBreak };
virtual ~DebugDelegate() = default; virtual ~DebugDelegate() = default;
virtual void ScriptCompiled(v8::Local<Script> script, bool is_live_edited, virtual void ScriptCompiled(v8::Local<Script> script, bool is_live_edited,
bool has_compile_error) {} bool has_compile_error) {}
...@@ -231,7 +241,7 @@ class DebugDelegate { ...@@ -231,7 +241,7 @@ class DebugDelegate {
virtual void BreakProgramRequested( virtual void BreakProgramRequested(
v8::Local<v8::Context> paused_context, v8::Local<v8::Context> paused_context,
const std::vector<debug::BreakpointId>& inspector_break_points_hit, const std::vector<debug::BreakpointId>& inspector_break_points_hit,
StepBreak is_step_break) {} base::EnumSet<BreakReason> break_reasons = {}) {}
virtual void ExceptionThrown(v8::Local<v8::Context> paused_context, virtual void ExceptionThrown(v8::Local<v8::Context> paused_context,
v8::Local<v8::Value> exception, v8::Local<v8::Value> exception,
v8::Local<v8::Value> promise, bool is_uncaught, v8::Local<v8::Value> promise, bool is_uncaught,
......
...@@ -2145,7 +2145,8 @@ void Debug::OnException(Handle<Object> exception, Handle<Object> promise, ...@@ -2145,7 +2145,8 @@ void Debug::OnException(Handle<Object> exception, Handle<Object> promise,
} }
void Debug::OnDebugBreak(Handle<FixedArray> break_points_hit, void Debug::OnDebugBreak(Handle<FixedArray> break_points_hit,
StepAction lastStepAction) { StepAction lastStepAction,
v8::debug::BreakReasons break_reasons) {
RCS_SCOPE(isolate_, RuntimeCallCounterId::kDebugger); RCS_SCOPE(isolate_, RuntimeCallCounterId::kDebugger);
DCHECK(!break_points_hit.is_null()); DCHECK(!break_points_hit.is_null());
// The caller provided for DebugScope. // The caller provided for DebugScope.
...@@ -2178,11 +2179,11 @@ void Debug::OnDebugBreak(Handle<FixedArray> break_points_hit, ...@@ -2178,11 +2179,11 @@ void Debug::OnDebugBreak(Handle<FixedArray> break_points_hit,
{ {
RCS_SCOPE(isolate_, RuntimeCallCounterId::kDebuggerCallback); RCS_SCOPE(isolate_, RuntimeCallCounterId::kDebuggerCallback);
Handle<Context> native_context(isolate_->native_context()); Handle<Context> native_context(isolate_->native_context());
debug_delegate_->BreakProgramRequested( if (lastStepAction != StepAction::StepNone)
v8::Utils::ToLocal(native_context), inspector_break_points_hit, break_reasons.Add(debug::BreakReason::kStep);
lastStepAction != StepAction::StepNone debug_delegate_->BreakProgramRequested(v8::Utils::ToLocal(native_context),
? debug::DebugDelegate::StepBreak::kIsStepBreak inspector_break_points_hit,
: debug::DebugDelegate::StepBreak::kIsNoStepBreak); break_reasons);
} }
} }
...@@ -2370,7 +2371,8 @@ void Debug::UpdateHookOnFunctionCall() { ...@@ -2370,7 +2371,8 @@ void Debug::UpdateHookOnFunctionCall() {
thread_local_.break_on_next_function_call_; thread_local_.break_on_next_function_call_;
} }
void Debug::HandleDebugBreak(IgnoreBreakMode ignore_break_mode) { void Debug::HandleDebugBreak(IgnoreBreakMode ignore_break_mode,
v8::debug::BreakReasons break_reasons) {
RCS_SCOPE(isolate_, RuntimeCallCounterId::kDebugger); RCS_SCOPE(isolate_, RuntimeCallCounterId::kDebugger);
// Ignore debug break during bootstrapping. // Ignore debug break during bootstrapping.
if (isolate_->bootstrapper()->IsActive()) return; if (isolate_->bootstrapper()->IsActive()) return;
...@@ -2413,7 +2415,7 @@ void Debug::HandleDebugBreak(IgnoreBreakMode ignore_break_mode) { ...@@ -2413,7 +2415,7 @@ void Debug::HandleDebugBreak(IgnoreBreakMode ignore_break_mode) {
DebugScope debug_scope(this); DebugScope debug_scope(this);
OnDebugBreak(break_points.is_null() ? isolate_->factory()->empty_fixed_array() OnDebugBreak(break_points.is_null() ? isolate_->factory()->empty_fixed_array()
: break_points.ToHandleChecked(), : break_points.ToHandleChecked(),
lastStepAction); lastStepAction, break_reasons);
} }
#ifdef DEBUG #ifdef DEBUG
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
#include "src/base/enum-set.h"
#include "src/codegen/source-position-table.h" #include "src/codegen/source-position-table.h"
#include "src/common/globals.h" #include "src/common/globals.h"
#include "src/debug/debug-interface.h" #include "src/debug/debug-interface.h"
...@@ -215,7 +216,8 @@ class V8_EXPORT_PRIVATE Debug { ...@@ -215,7 +216,8 @@ class V8_EXPORT_PRIVATE Debug {
Debug& operator=(const Debug&) = delete; Debug& operator=(const Debug&) = delete;
// Debug event triggers. // Debug event triggers.
void OnDebugBreak(Handle<FixedArray> break_points_hit, StepAction stepAction); void OnDebugBreak(Handle<FixedArray> break_points_hit, StepAction stepAction,
debug::BreakReasons break_reasons = {});
base::Optional<Object> OnThrow(Handle<Object> exception) base::Optional<Object> OnThrow(Handle<Object> exception)
V8_WARN_UNUSED_RESULT; V8_WARN_UNUSED_RESULT;
...@@ -223,7 +225,8 @@ class V8_EXPORT_PRIVATE Debug { ...@@ -223,7 +225,8 @@ class V8_EXPORT_PRIVATE Debug {
void OnCompileError(Handle<Script> script); void OnCompileError(Handle<Script> script);
void OnAfterCompile(Handle<Script> script); void OnAfterCompile(Handle<Script> script);
void HandleDebugBreak(IgnoreBreakMode ignore_break_mode); void HandleDebugBreak(IgnoreBreakMode ignore_break_mode,
debug::BreakReasons break_reasons);
// The break target may not be the top-most frame, since we may be // The break target may not be the top-most frame, since we may be
// breaking before entering a function that cannot contain break points. // breaking before entering a function that cannot contain break points.
......
...@@ -420,7 +420,7 @@ void GdbServer::DebugDelegate::BreakProgramRequested( ...@@ -420,7 +420,7 @@ void GdbServer::DebugDelegate::BreakProgramRequested(
// Executed in the isolate thread. // Executed in the isolate thread.
Local<v8::Context> paused_context, Local<v8::Context> paused_context,
const std::vector<debug::BreakpointId>& inspector_break_points_hit, const std::vector<debug::BreakpointId>& inspector_break_points_hit,
StepBreak is_step_break) { v8::debug::BreakReasons break_reasons) {
gdb_server_->GetTarget().OnProgramBreak( gdb_server_->GetTarget().OnProgramBreak(
isolate_, WasmModuleDebug::GetCallStack(id_, isolate_)); isolate_, WasmModuleDebug::GetCallStack(id_, isolate_));
gdb_server_->RunMessageLoopOnPause(); gdb_server_->RunMessageLoopOnPause();
......
...@@ -153,7 +153,7 @@ class GdbServer { ...@@ -153,7 +153,7 @@ class GdbServer {
void BreakProgramRequested( void BreakProgramRequested(
Local<v8::Context> paused_context, Local<v8::Context> paused_context,
const std::vector<debug::BreakpointId>& inspector_break_points_hit, const std::vector<debug::BreakpointId>& inspector_break_points_hit,
StepBreak is_step_break) override; v8::debug::BreakReasons break_reasons) override;
void ExceptionThrown(Local<v8::Context> paused_context, void ExceptionThrown(Local<v8::Context> paused_context,
Local<Value> exception, Local<Value> promise, Local<Value> exception, Local<Value> promise,
bool is_uncaught, bool is_uncaught,
......
...@@ -19,6 +19,7 @@ include_rules = [ ...@@ -19,6 +19,7 @@ include_rules = [
"+src/debug/debug-interface.h", "+src/debug/debug-interface.h",
"+src/debug/interface-types.h", "+src/debug/interface-types.h",
"+src/base/vector.h", "+src/base/vector.h",
"+src/base/enum-set.h",
"+third_party/inspector_protocol/crdtp", "+third_party/inspector_protocol/crdtp",
"+../../third_party/inspector_protocol/crdtp", "+../../third_party/inspector_protocol/crdtp",
] ]
...@@ -382,7 +382,7 @@ void V8DebuggerAgentImpl::enableImpl() { ...@@ -382,7 +382,7 @@ void V8DebuggerAgentImpl::enableImpl() {
if (isPaused()) { if (isPaused()) {
didPause(0, v8::Local<v8::Value>(), std::vector<v8::debug::BreakpointId>(), didPause(0, v8::Local<v8::Value>(), std::vector<v8::debug::BreakpointId>(),
v8::debug::kException, false, false, false, false); v8::debug::kException, false, {});
} }
} }
...@@ -1744,19 +1744,19 @@ void V8DebuggerAgentImpl::setScriptInstrumentationBreakpointIfNeeded( ...@@ -1744,19 +1744,19 @@ void V8DebuggerAgentImpl::setScriptInstrumentationBreakpointIfNeeded(
void V8DebuggerAgentImpl::didPause( void V8DebuggerAgentImpl::didPause(
int contextId, v8::Local<v8::Value> exception, int contextId, v8::Local<v8::Value> exception,
const std::vector<v8::debug::BreakpointId>& hitBreakpoints, const std::vector<v8::debug::BreakpointId>& hitBreakpoints,
v8::debug::ExceptionType exceptionType, bool isUncaught, bool isOOMBreak, v8::debug::ExceptionType exceptionType, bool isUncaught,
bool isAssert, bool isStepAction) { v8::debug::BreakReasons breakReasons) {
v8::HandleScope handles(m_isolate); v8::HandleScope handles(m_isolate);
std::vector<BreakReason> hitReasons; std::vector<BreakReason> hitReasons;
if (isOOMBreak) { if (breakReasons.contains(v8::debug::BreakReason::kOOM)) {
hitReasons.push_back( hitReasons.push_back(
std::make_pair(protocol::Debugger::Paused::ReasonEnum::OOM, nullptr)); std::make_pair(protocol::Debugger::Paused::ReasonEnum::OOM, nullptr));
} else if (isAssert) { } else if (breakReasons.contains(v8::debug::BreakReason::kAssert)) {
hitReasons.push_back(std::make_pair( hitReasons.push_back(std::make_pair(
protocol::Debugger::Paused::ReasonEnum::Assert, nullptr)); protocol::Debugger::Paused::ReasonEnum::Assert, nullptr));
} else if (!exception.IsEmpty()) { } else if (breakReasons.contains(v8::debug::BreakReason::kException)) {
InjectedScript* injectedScript = nullptr; InjectedScript* injectedScript = nullptr;
m_session->findInjectedScript(contextId, injectedScript); m_session->findInjectedScript(contextId, injectedScript);
if (injectedScript) { if (injectedScript) {
...@@ -1824,9 +1824,12 @@ void V8DebuggerAgentImpl::didPause( ...@@ -1824,9 +1824,12 @@ void V8DebuggerAgentImpl::didPause(
// Make sure that we only include (other: nullptr) once. // Make sure that we only include (other: nullptr) once.
const BreakReason otherHitReason = const BreakReason otherHitReason =
std::make_pair(protocol::Debugger::Paused::ReasonEnum::Other, nullptr); std::make_pair(protocol::Debugger::Paused::ReasonEnum::Other, nullptr);
if ((hitRegularBreakpoint || isStepAction) && const bool otherBreakReasons =
std::find(hitReasons.begin(), hitReasons.end(), otherHitReason) == hitRegularBreakpoint ||
hitReasons.end()) { breakReasons.contains(v8::debug::BreakReason::kStep) ||
breakReasons.contains(v8::debug::BreakReason::kDebuggerStatement);
if (otherBreakReasons && std::find(hitReasons.begin(), hitReasons.end(),
otherHitReason) == hitReasons.end()) {
hitReasons.push_back( hitReasons.push_back(
std::make_pair(protocol::Debugger::Paused::ReasonEnum::Other, nullptr)); std::make_pair(protocol::Debugger::Paused::ReasonEnum::Other, nullptr));
} }
......
...@@ -10,9 +10,9 @@ ...@@ -10,9 +10,9 @@
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
#include "src/base/enum-set.h"
#include "src/base/macros.h" #include "src/base/macros.h"
#include "src/debug/debug-interface.h" #include "src/debug/debug-interface.h"
#include "src/debug/interface-types.h"
#include "src/inspector/protocol/Debugger.h" #include "src/inspector/protocol/Debugger.h"
#include "src/inspector/protocol/Forward.h" #include "src/inspector/protocol/Forward.h"
...@@ -152,7 +152,7 @@ class V8DebuggerAgentImpl : public protocol::Debugger::Backend { ...@@ -152,7 +152,7 @@ class V8DebuggerAgentImpl : public protocol::Debugger::Backend {
void didPause(int contextId, v8::Local<v8::Value> exception, void didPause(int contextId, v8::Local<v8::Value> exception,
const std::vector<v8::debug::BreakpointId>& hitBreakpoints, const std::vector<v8::debug::BreakpointId>& hitBreakpoints,
v8::debug::ExceptionType exceptionType, bool isUncaught, v8::debug::ExceptionType exceptionType, bool isUncaught,
bool isOOMBreak, bool isAssert, bool isStepAction); v8::debug::BreakReasons breakReasons);
void didContinue(); void didContinue();
void didParseSource(std::unique_ptr<V8DebuggerScript>, bool success); void didParseSource(std::unique_ptr<V8DebuggerScript>, bool success);
......
...@@ -239,7 +239,8 @@ void V8Debugger::breakProgramOnAssert(int targetContextGroupId) { ...@@ -239,7 +239,8 @@ void V8Debugger::breakProgramOnAssert(int targetContextGroupId) {
DCHECK(targetContextGroupId); DCHECK(targetContextGroupId);
m_targetContextGroupId = targetContextGroupId; m_targetContextGroupId = targetContextGroupId;
m_scheduledAssertBreak = true; m_scheduledAssertBreak = true;
v8::debug::BreakRightNow(m_isolate); v8::debug::BreakRightNow(
m_isolate, v8::debug::BreakReasons({v8::debug::BreakReason::kAssert}));
} }
void V8Debugger::stepIntoStatement(int targetContextGroupId, void V8Debugger::stepIntoStatement(int targetContextGroupId,
...@@ -397,8 +398,8 @@ void V8Debugger::clearContinueToLocation() { ...@@ -397,8 +398,8 @@ void V8Debugger::clearContinueToLocation() {
void V8Debugger::handleProgramBreak( void V8Debugger::handleProgramBreak(
v8::Local<v8::Context> pausedContext, v8::Local<v8::Value> exception, v8::Local<v8::Context> pausedContext, v8::Local<v8::Value> exception,
const std::vector<v8::debug::BreakpointId>& breakpointIds, const std::vector<v8::debug::BreakpointId>& breakpointIds,
StepBreak isStepAction, v8::debug::ExceptionType exceptionType, v8::debug::BreakReasons breakReasons,
bool isUncaught) { v8::debug::ExceptionType exceptionType, bool isUncaught) {
// Don't allow nested breaks. // Don't allow nested breaks.
if (isPaused()) return; if (isPaused()) return;
...@@ -415,8 +416,11 @@ void V8Debugger::handleProgramBreak( ...@@ -415,8 +416,11 @@ void V8Debugger::handleProgramBreak(
m_taskWithScheduledBreakPauseRequested = false; m_taskWithScheduledBreakPauseRequested = false;
bool scheduledOOMBreak = m_scheduledOOMBreak; bool scheduledOOMBreak = m_scheduledOOMBreak;
DCHECK(scheduledOOMBreak ==
breakReasons.contains(v8::debug::BreakReason::kOOM));
bool scheduledAssertBreak = m_scheduledAssertBreak; bool scheduledAssertBreak = m_scheduledAssertBreak;
bool hasAgents = false; bool hasAgents = false;
m_inspector->forEachSession( m_inspector->forEachSession(
contextGroupId, contextGroupId,
[&scheduledOOMBreak, &hasAgents](V8InspectorSessionImpl* session) { [&scheduledOOMBreak, &hasAgents](V8InspectorSessionImpl* session) {
...@@ -472,7 +476,7 @@ void V8Debugger::handleProgramBreak( ...@@ -472,7 +476,7 @@ void V8Debugger::handleProgramBreak(
session->debuggerAgent()->didPause( session->debuggerAgent()->didPause(
InspectedContext::contextId(pausedContext), {}, InspectedContext::contextId(pausedContext), {},
instrumentationBreakpointIds, instrumentationBreakpointIds,
v8::debug::ExceptionType::kException, false, false, false, false); v8::debug::ExceptionType::kException, false, {});
}); });
{ {
v8::Context::Scope scope(pausedContext); v8::Context::Scope scope(pausedContext);
...@@ -505,16 +509,13 @@ void V8Debugger::handleProgramBreak( ...@@ -505,16 +509,13 @@ void V8Debugger::handleProgramBreak(
// want to trigger two pause events if we only break because of an // want to trigger two pause events if we only break because of an
// instrumentation. // instrumentation.
m_inspector->forEachSession( m_inspector->forEachSession(
contextGroupId, contextGroupId, [&pausedContext, &exception, &regularBreakpointIds,
[&pausedContext, &exception, &regularBreakpointIds, &exceptionType, &exceptionType, &isUncaught, &scheduledOOMBreak,
&isUncaught, &scheduledOOMBreak, &scheduledAssertBreak, &breakReasons](V8InspectorSessionImpl* session) {
&isStepAction](V8InspectorSessionImpl* session) {
if (session->debuggerAgent()->acceptsPause(scheduledOOMBreak)) { if (session->debuggerAgent()->acceptsPause(scheduledOOMBreak)) {
session->debuggerAgent()->didPause( session->debuggerAgent()->didPause(
InspectedContext::contextId(pausedContext), exception, InspectedContext::contextId(pausedContext), exception,
regularBreakpointIds, exceptionType, isUncaught, regularBreakpointIds, exceptionType, isUncaught, breakReasons);
scheduledOOMBreak, scheduledAssertBreak,
isStepAction == kIsStepBreak);
} }
}); });
{ {
...@@ -553,7 +554,14 @@ size_t V8Debugger::nearHeapLimitCallback(void* data, size_t current_heap_limit, ...@@ -553,7 +554,14 @@ size_t V8Debugger::nearHeapLimitCallback(void* data, size_t current_heap_limit,
thisPtr->m_targetContextGroupId = thisPtr->m_targetContextGroupId =
context.IsEmpty() ? 0 : thisPtr->m_inspector->contextGroupId(context); context.IsEmpty() ? 0 : thisPtr->m_inspector->contextGroupId(context);
thisPtr->m_isolate->RequestInterrupt( thisPtr->m_isolate->RequestInterrupt(
[](v8::Isolate* isolate, void*) { v8::debug::BreakRightNow(isolate); }, [](v8::Isolate* isolate, void*) {
// There's a redundancy between setting `m_scheduledOOMBreak` and
// passing the reason along in `BreakRightNow`. The
// `m_scheduledOOMBreak` is used elsewhere, so we cannot remove it. And
// for being explicit, we still pass the break reason along.
v8::debug::BreakRightNow(
isolate, v8::debug::BreakReasons({v8::debug::BreakReason::kOOM}));
},
nullptr); nullptr);
return HeapLimitForDebugging(initial_heap_limit); return HeapLimitForDebugging(initial_heap_limit);
} }
...@@ -584,9 +592,9 @@ void V8Debugger::ScriptCompiled(v8::Local<v8::debug::Script> script, ...@@ -584,9 +592,9 @@ void V8Debugger::ScriptCompiled(v8::Local<v8::debug::Script> script,
void V8Debugger::BreakProgramRequested( void V8Debugger::BreakProgramRequested(
v8::Local<v8::Context> pausedContext, v8::Local<v8::Context> pausedContext,
const std::vector<v8::debug::BreakpointId>& break_points_hit, const std::vector<v8::debug::BreakpointId>& break_points_hit,
StepBreak is_step_break) { v8::debug::BreakReasons reasons) {
handleProgramBreak(pausedContext, v8::Local<v8::Value>(), break_points_hit, handleProgramBreak(pausedContext, v8::Local<v8::Value>(), break_points_hit,
is_step_break); reasons);
} }
void V8Debugger::ExceptionThrown(v8::Local<v8::Context> pausedContext, void V8Debugger::ExceptionThrown(v8::Local<v8::Context> pausedContext,
...@@ -594,8 +602,10 @@ void V8Debugger::ExceptionThrown(v8::Local<v8::Context> pausedContext, ...@@ -594,8 +602,10 @@ void V8Debugger::ExceptionThrown(v8::Local<v8::Context> pausedContext,
v8::Local<v8::Value> promise, bool isUncaught, v8::Local<v8::Value> promise, bool isUncaught,
v8::debug::ExceptionType exceptionType) { v8::debug::ExceptionType exceptionType) {
std::vector<v8::debug::BreakpointId> break_points_hit; std::vector<v8::debug::BreakpointId> break_points_hit;
handleProgramBreak(pausedContext, exception, break_points_hit, kIsNoStepBreak, handleProgramBreak(
exceptionType, isUncaught); pausedContext, exception, break_points_hit,
v8::debug::BreakReasons({v8::debug::BreakReason::kException}),
exceptionType, isUncaught);
} }
bool V8Debugger::IsFunctionBlackboxed(v8::Local<v8::debug::Script> script, bool V8Debugger::IsFunctionBlackboxed(v8::Local<v8::debug::Script> script,
......
...@@ -142,7 +142,7 @@ class V8Debugger : public v8::debug::DebugDelegate, ...@@ -142,7 +142,7 @@ class V8Debugger : public v8::debug::DebugDelegate,
void handleProgramBreak( void handleProgramBreak(
v8::Local<v8::Context> pausedContext, v8::Local<v8::Value> exception, v8::Local<v8::Context> pausedContext, v8::Local<v8::Value> exception,
const std::vector<v8::debug::BreakpointId>& hitBreakpoints, const std::vector<v8::debug::BreakpointId>& hitBreakpoints,
StepBreak isStepBreak = StepBreak::kIsNoStepBreak, v8::debug::BreakReasons break_reasons,
v8::debug::ExceptionType exception_type = v8::debug::kException, v8::debug::ExceptionType exception_type = v8::debug::kException,
bool isUncaught = false); bool isUncaught = false);
...@@ -180,7 +180,7 @@ class V8Debugger : public v8::debug::DebugDelegate, ...@@ -180,7 +180,7 @@ class V8Debugger : public v8::debug::DebugDelegate,
void BreakProgramRequested( void BreakProgramRequested(
v8::Local<v8::Context> paused_context, v8::Local<v8::Context> paused_context,
const std::vector<v8::debug::BreakpointId>& break_points_hit, const std::vector<v8::debug::BreakpointId>& break_points_hit,
StepBreak is_step_break) override; v8::debug::BreakReasons break_reasons) override;
void ExceptionThrown(v8::Local<v8::Context> paused_context, void ExceptionThrown(v8::Local<v8::Context> paused_context,
v8::Local<v8::Value> exception, v8::Local<v8::Value> exception,
v8::Local<v8::Value> promise, bool is_uncaught, v8::Local<v8::Value> promise, bool is_uncaught,
......
...@@ -137,7 +137,9 @@ RUNTIME_FUNCTION(Runtime_HandleDebuggerStatement) { ...@@ -137,7 +137,9 @@ RUNTIME_FUNCTION(Runtime_HandleDebuggerStatement) {
SealHandleScope shs(isolate); SealHandleScope shs(isolate);
DCHECK_EQ(0, args.length()); DCHECK_EQ(0, args.length());
if (isolate->debug()->break_points_active()) { if (isolate->debug()->break_points_active()) {
isolate->debug()->HandleDebugBreak(kIgnoreIfTopFrameBlackboxed); isolate->debug()->HandleDebugBreak(
kIgnoreIfTopFrameBlackboxed,
v8::debug::BreakReasons({v8::debug::BreakReason::kDebuggerStatement}));
} }
return isolate->stack_guard()->HandleInterrupts(); return isolate->stack_guard()->HandleInterrupts();
} }
......
...@@ -2922,7 +2922,7 @@ class CountBreakDebugDelegate : public v8::debug::DebugDelegate { ...@@ -2922,7 +2922,7 @@ class CountBreakDebugDelegate : public v8::debug::DebugDelegate {
public: public:
void BreakProgramRequested(v8::Local<v8::Context> paused_context, void BreakProgramRequested(v8::Local<v8::Context> paused_context,
const std::vector<int>&, const std::vector<int>&,
StepBreak is_step_break) override { v8::debug::BreakReasons break_reasons) override {
debug_break_count++; debug_break_count++;
} }
int debug_break_count = 0; int debug_break_count = 0;
......
...@@ -197,7 +197,7 @@ class DebugEventCounter : public v8::debug::DebugDelegate { ...@@ -197,7 +197,7 @@ class DebugEventCounter : public v8::debug::DebugDelegate {
public: public:
void BreakProgramRequested(v8::Local<v8::Context>, void BreakProgramRequested(v8::Local<v8::Context>,
const std::vector<v8::debug::BreakpointId>&, const std::vector<v8::debug::BreakpointId>&,
StepBreak is_step_break) override { v8::debug::BreakReasons break_reasons) override {
break_point_hit_count++; break_point_hit_count++;
// Perform a full deoptimization when the specified number of // Perform a full deoptimization when the specified number of
// breaks have been hit. // breaks have been hit.
...@@ -220,7 +220,7 @@ class DebugEventBreakPointCollectGarbage : public v8::debug::DebugDelegate { ...@@ -220,7 +220,7 @@ class DebugEventBreakPointCollectGarbage : public v8::debug::DebugDelegate {
public: public:
void BreakProgramRequested(v8::Local<v8::Context>, void BreakProgramRequested(v8::Local<v8::Context>,
const std::vector<v8::debug::BreakpointId>&, const std::vector<v8::debug::BreakpointId>&,
StepBreak is_step_break) override { v8::debug::BreakReasons break_reasons) override {
// Perform a garbage collection when break point is hit and continue. Based // Perform a garbage collection when break point is hit and continue. Based
// on the number of break points hit either scavenge or mark compact // on the number of break points hit either scavenge or mark compact
// collector is used. // collector is used.
...@@ -241,7 +241,7 @@ class DebugEventBreak : public v8::debug::DebugDelegate { ...@@ -241,7 +241,7 @@ class DebugEventBreak : public v8::debug::DebugDelegate {
public: public:
void BreakProgramRequested(v8::Local<v8::Context>, void BreakProgramRequested(v8::Local<v8::Context>,
const std::vector<v8::debug::BreakpointId>&, const std::vector<v8::debug::BreakpointId>&,
StepBreak is_step_break) override { v8::debug::BreakReasons break_reasons) override {
// Count the number of breaks. // Count the number of breaks.
break_point_hit_count++; break_point_hit_count++;
...@@ -266,7 +266,7 @@ class DebugEventBreakMax : public v8::debug::DebugDelegate { ...@@ -266,7 +266,7 @@ class DebugEventBreakMax : public v8::debug::DebugDelegate {
public: public:
void BreakProgramRequested(v8::Local<v8::Context>, void BreakProgramRequested(v8::Local<v8::Context>,
const std::vector<v8::debug::BreakpointId>&, const std::vector<v8::debug::BreakpointId>&,
StepBreak is_step_break) override { v8::debug::BreakReasons break_reasons) override {
v8::Isolate* v8_isolate = CcTest::isolate(); v8::Isolate* v8_isolate = CcTest::isolate();
v8::internal::Isolate* isolate = CcTest::i_isolate(); v8::internal::Isolate* isolate = CcTest::i_isolate();
if (break_point_hit_count < max_break_point_hit_count) { if (break_point_hit_count < max_break_point_hit_count) {
...@@ -3312,7 +3312,7 @@ class ContextCheckEventListener : public v8::debug::DebugDelegate { ...@@ -3312,7 +3312,7 @@ class ContextCheckEventListener : public v8::debug::DebugDelegate {
void BreakProgramRequested( void BreakProgramRequested(
v8::Local<v8::Context> paused_context, v8::Local<v8::Context> paused_context,
const std::vector<v8::debug::BreakpointId>& inspector_break_points_hit, const std::vector<v8::debug::BreakpointId>& inspector_break_points_hit,
StepBreak is_step_break) override { v8::debug::BreakReasons break_reasons) override {
CheckContext(); CheckContext();
} }
void ScriptCompiled(v8::Local<v8::debug::Script> script, bool is_live_edited, void ScriptCompiled(v8::Local<v8::debug::Script> script, bool is_live_edited,
...@@ -3828,7 +3828,7 @@ class DebugBreakInlineListener : public v8::debug::DebugDelegate { ...@@ -3828,7 +3828,7 @@ class DebugBreakInlineListener : public v8::debug::DebugDelegate {
void BreakProgramRequested( void BreakProgramRequested(
v8::Local<v8::Context> paused_context, v8::Local<v8::Context> paused_context,
const std::vector<v8::debug::BreakpointId>& inspector_break_points_hit, const std::vector<v8::debug::BreakpointId>& inspector_break_points_hit,
StepBreak is_step_break) override { v8::debug::BreakReasons break_reasons) override {
int expected_frame_count = 4; int expected_frame_count = 4;
int expected_line_number[] = {1, 4, 7, 13}; int expected_line_number[] = {1, 4, 7, 13};
...@@ -3911,7 +3911,7 @@ class DebugBreakStackTraceListener : public v8::debug::DebugDelegate { ...@@ -3911,7 +3911,7 @@ class DebugBreakStackTraceListener : public v8::debug::DebugDelegate {
void BreakProgramRequested( void BreakProgramRequested(
v8::Local<v8::Context> paused_context, v8::Local<v8::Context> paused_context,
const std::vector<v8::debug::BreakpointId>& inspector_break_points_hit, const std::vector<v8::debug::BreakpointId>& inspector_break_points_hit,
StepBreak is_step_break) override { v8::debug::BreakReasons break_reasons) override {
v8::StackTrace::CurrentStackTrace(CcTest::isolate(), 10); v8::StackTrace::CurrentStackTrace(CcTest::isolate(), 10);
} }
}; };
...@@ -3952,7 +3952,7 @@ class DebugBreakTriggerTerminate : public v8::debug::DebugDelegate { ...@@ -3952,7 +3952,7 @@ class DebugBreakTriggerTerminate : public v8::debug::DebugDelegate {
void BreakProgramRequested( void BreakProgramRequested(
v8::Local<v8::Context> paused_context, v8::Local<v8::Context> paused_context,
const std::vector<v8::debug::BreakpointId>& inspector_break_points_hit, const std::vector<v8::debug::BreakpointId>& inspector_break_points_hit,
StepBreak is_step_break) override { v8::debug::BreakReasons break_reasons) override {
if (terminate_already_fired_) return; if (terminate_already_fired_) return;
terminate_requested_semaphore.Signal(); terminate_requested_semaphore.Signal();
// Wait for at most 2 seconds for the terminate request. // Wait for at most 2 seconds for the terminate request.
...@@ -4062,7 +4062,7 @@ class ArchiveRestoreThread : public v8::base::Thread, ...@@ -4062,7 +4062,7 @@ class ArchiveRestoreThread : public v8::base::Thread,
void BreakProgramRequested(v8::Local<v8::Context> context, void BreakProgramRequested(v8::Local<v8::Context> context,
const std::vector<v8::debug::BreakpointId>&, const std::vector<v8::debug::BreakpointId>&,
StepBreak is_step_break) override { v8::debug::BreakReasons break_reasons) override {
auto stack_traces = v8::debug::StackTraceIterator::Create(isolate_); auto stack_traces = v8::debug::StackTraceIterator::Create(isolate_);
if (!stack_traces->Done()) { if (!stack_traces->Done()) {
v8::debug::Location location = stack_traces->GetSourceLocation(); v8::debug::Location location = stack_traces->GetSourceLocation();
...@@ -4283,7 +4283,7 @@ class DebugStepOverFunctionWithCaughtExceptionListener ...@@ -4283,7 +4283,7 @@ class DebugStepOverFunctionWithCaughtExceptionListener
void BreakProgramRequested( void BreakProgramRequested(
v8::Local<v8::Context> paused_context, v8::Local<v8::Context> paused_context,
const std::vector<v8::debug::BreakpointId>& inspector_break_points_hit, const std::vector<v8::debug::BreakpointId>& inspector_break_points_hit,
StepBreak is_step_break) override { v8::debug::BreakReasons break_reasons) override {
++break_point_hit_count; ++break_point_hit_count;
if (break_point_hit_count >= 3) return; if (break_point_hit_count >= 3) return;
PrepareStep(StepOver); PrepareStep(StepOver);
...@@ -4785,7 +4785,7 @@ class SetBreakpointOnScriptCompiled : public v8::debug::DebugDelegate { ...@@ -4785,7 +4785,7 @@ class SetBreakpointOnScriptCompiled : public v8::debug::DebugDelegate {
void BreakProgramRequested( void BreakProgramRequested(
v8::Local<v8::Context> paused_context, v8::Local<v8::Context> paused_context,
const std::vector<v8::debug::BreakpointId>& inspector_break_points_hit, const std::vector<v8::debug::BreakpointId>& inspector_break_points_hit,
StepBreak is_step_break) override { v8::debug::BreakReasons break_reasons) override {
++break_count_; ++break_count_;
CHECK_EQ(inspector_break_points_hit[0], id_); CHECK_EQ(inspector_break_points_hit[0], id_);
} }
...@@ -5212,7 +5212,7 @@ class SetTerminateOnResumeDelegate : public v8::debug::DebugDelegate { ...@@ -5212,7 +5212,7 @@ class SetTerminateOnResumeDelegate : public v8::debug::DebugDelegate {
void BreakProgramRequested( void BreakProgramRequested(
v8::Local<v8::Context> paused_context, v8::Local<v8::Context> paused_context,
const std::vector<v8::debug::BreakpointId>& inspector_break_points_hit, const std::vector<v8::debug::BreakpointId>& inspector_break_points_hit,
StepBreak is_step_break) override { v8::debug::BreakReasons break_reasons) override {
break_count_++; break_count_++;
v8::Isolate* isolate = paused_context->GetIsolate(); v8::Isolate* isolate = paused_context->GetIsolate();
v8::debug::SetTerminateOnResume(isolate); v8::debug::SetTerminateOnResume(isolate);
...@@ -5590,7 +5590,7 @@ class SemaphoreTriggerOnBreak : public v8::debug::DebugDelegate { ...@@ -5590,7 +5590,7 @@ class SemaphoreTriggerOnBreak : public v8::debug::DebugDelegate {
void BreakProgramRequested( void BreakProgramRequested(
v8::Local<v8::Context> paused_context, v8::Local<v8::Context> paused_context,
const std::vector<v8::debug::BreakpointId>& inspector_break_points_hit, const std::vector<v8::debug::BreakpointId>& inspector_break_points_hit,
StepBreak is_step_break) override { v8::debug::BreakReasons break_reasons) override {
break_count_++; break_count_++;
enter_.Signal(); enter_.Signal();
exit_.Wait(); exit_.Wait();
......
...@@ -111,7 +111,7 @@ class BreakHandler : public debug::DebugDelegate { ...@@ -111,7 +111,7 @@ class BreakHandler : public debug::DebugDelegate {
void BreakProgramRequested(v8::Local<v8::Context> paused_context, void BreakProgramRequested(v8::Local<v8::Context> paused_context,
const std::vector<int>&, const std::vector<int>&,
StepBreak is_step_break) override { v8::debug::BreakReasons break_reasons) override {
printf("Break #%d\n", count_); printf("Break #%d\n", count_);
CHECK_GT(expected_breaks_.size(), count_); CHECK_GT(expected_breaks_.size(), count_);
...@@ -223,7 +223,7 @@ class CollectValuesBreakHandler : public debug::DebugDelegate { ...@@ -223,7 +223,7 @@ class CollectValuesBreakHandler : public debug::DebugDelegate {
void BreakProgramRequested(v8::Local<v8::Context> paused_context, void BreakProgramRequested(v8::Local<v8::Context> paused_context,
const std::vector<int>&, const std::vector<int>&,
StepBreak is_step_break) override { v8::debug::BreakReasons break_reasons) override {
printf("Break #%d\n", count_); printf("Break #%d\n", count_);
CHECK_GT(expected_values_.size(), count_); CHECK_GT(expected_values_.size(), count_);
auto& expected = expected_values_[count_]; auto& expected = expected_values_[count_];
......
...@@ -15,3 +15,6 @@ Paused with reason: ambiguous and data: {"reasons":[{"reason":"instrumentation", ...@@ -15,3 +15,6 @@ Paused with reason: ambiguous and data: {"reasons":[{"reason":"instrumentation",
Running test: testOnlyReportOtherWithEmptyDataOnce Running test: testOnlyReportOtherWithEmptyDataOnce
Paused with reason: other and data: {}. Paused with reason: other and data: {}.
Running test: testDebuggerStatementReason
Paused with reason: ambiguous and data: {"reasons":[{"reason":"instrumentation","auxData":{"url":"foo.js","scriptId":"8"}},{"reason":"other"}]}.
...@@ -91,6 +91,18 @@ InspectorTest.runAsyncTestSuite([ ...@@ -91,6 +91,18 @@ InspectorTest.runAsyncTestSuite([
url: 'foo.js', url: 'foo.js',
}); });
await Protocol.Runtime.runScript({scriptId});
await tearDownEnvironment();
},
async function testDebuggerStatementReason() {
await setUpEnvironment();
Protocol.Debugger.onPaused(resumeOnPause);
await Protocol.Debugger.setInstrumentationBreakpoint(
{instrumentation: 'beforeScriptExecution'});
const {result: {scriptId}} = await Protocol.Runtime.compileScript(
{expression: 'debugger;', sourceURL: 'foo.js', persistScript: true});
await Protocol.Runtime.runScript({scriptId}); await Protocol.Runtime.runScript({scriptId});
await tearDownEnvironment(); await tearDownEnvironment();
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment