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) {
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);
ENTER_V8_DO_NOT_USE(isolate);
isolate->debug()->HandleDebugBreak(i::kIgnoreIfAllFramesBlackboxed);
isolate->debug()->HandleDebugBreak(i::kIgnoreIfAllFramesBlackboxed,
break_reasons);
}
void SetTerminateOnResume(Isolate* v8_isolate) {
......
......@@ -15,6 +15,7 @@
#include "include/v8-promise.h"
#include "include/v8-script.h"
#include "include/v8-util.h"
#include "src/base/enum-set.h"
#include "src/base/vector.h"
#include "src/common/globals.h"
#include "src/debug/interface-types.h"
......@@ -119,9 +120,20 @@ enum StepAction {
// 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 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
// should be set shortly before resuming, i.e. shortly before returning into
......@@ -221,8 +233,6 @@ enum ExceptionType { kException, kPromiseRejection };
class DebugDelegate {
public:
// Encodes whether a requested break is (also) due to a step action.
enum StepBreak { kIsStepBreak, kIsNoStepBreak };
virtual ~DebugDelegate() = default;
virtual void ScriptCompiled(v8::Local<Script> script, bool is_live_edited,
bool has_compile_error) {}
......@@ -231,7 +241,7 @@ class DebugDelegate {
virtual void BreakProgramRequested(
v8::Local<v8::Context> paused_context,
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,
v8::Local<v8::Value> exception,
v8::Local<v8::Value> promise, bool is_uncaught,
......
......@@ -2145,7 +2145,8 @@ void Debug::OnException(Handle<Object> exception, Handle<Object> promise,
}
void Debug::OnDebugBreak(Handle<FixedArray> break_points_hit,
StepAction lastStepAction) {
StepAction lastStepAction,
v8::debug::BreakReasons break_reasons) {
RCS_SCOPE(isolate_, RuntimeCallCounterId::kDebugger);
DCHECK(!break_points_hit.is_null());
// The caller provided for DebugScope.
......@@ -2178,11 +2179,11 @@ void Debug::OnDebugBreak(Handle<FixedArray> break_points_hit,
{
RCS_SCOPE(isolate_, RuntimeCallCounterId::kDebuggerCallback);
Handle<Context> native_context(isolate_->native_context());
debug_delegate_->BreakProgramRequested(
v8::Utils::ToLocal(native_context), inspector_break_points_hit,
lastStepAction != StepAction::StepNone
? debug::DebugDelegate::StepBreak::kIsStepBreak
: debug::DebugDelegate::StepBreak::kIsNoStepBreak);
if (lastStepAction != StepAction::StepNone)
break_reasons.Add(debug::BreakReason::kStep);
debug_delegate_->BreakProgramRequested(v8::Utils::ToLocal(native_context),
inspector_break_points_hit,
break_reasons);
}
}
......@@ -2370,7 +2371,8 @@ void Debug::UpdateHookOnFunctionCall() {
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);
// Ignore debug break during bootstrapping.
if (isolate_->bootstrapper()->IsActive()) return;
......@@ -2413,7 +2415,7 @@ void Debug::HandleDebugBreak(IgnoreBreakMode ignore_break_mode) {
DebugScope debug_scope(this);
OnDebugBreak(break_points.is_null() ? isolate_->factory()->empty_fixed_array()
: break_points.ToHandleChecked(),
lastStepAction);
lastStepAction, break_reasons);
}
#ifdef DEBUG
......
......@@ -8,6 +8,7 @@
#include <memory>
#include <vector>
#include "src/base/enum-set.h"
#include "src/codegen/source-position-table.h"
#include "src/common/globals.h"
#include "src/debug/debug-interface.h"
......@@ -215,7 +216,8 @@ class V8_EXPORT_PRIVATE Debug {
Debug& operator=(const Debug&) = delete;
// 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)
V8_WARN_UNUSED_RESULT;
......@@ -223,7 +225,8 @@ class V8_EXPORT_PRIVATE Debug {
void OnCompileError(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
// breaking before entering a function that cannot contain break points.
......
......@@ -420,7 +420,7 @@ void GdbServer::DebugDelegate::BreakProgramRequested(
// Executed in the isolate thread.
Local<v8::Context> paused_context,
const std::vector<debug::BreakpointId>& inspector_break_points_hit,
StepBreak is_step_break) {
v8::debug::BreakReasons break_reasons) {
gdb_server_->GetTarget().OnProgramBreak(
isolate_, WasmModuleDebug::GetCallStack(id_, isolate_));
gdb_server_->RunMessageLoopOnPause();
......
......@@ -153,7 +153,7 @@ class GdbServer {
void BreakProgramRequested(
Local<v8::Context> paused_context,
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,
Local<Value> exception, Local<Value> promise,
bool is_uncaught,
......
......@@ -19,6 +19,7 @@ include_rules = [
"+src/debug/debug-interface.h",
"+src/debug/interface-types.h",
"+src/base/vector.h",
"+src/base/enum-set.h",
"+third_party/inspector_protocol/crdtp",
"+../../third_party/inspector_protocol/crdtp",
]
......@@ -382,7 +382,7 @@ void V8DebuggerAgentImpl::enableImpl() {
if (isPaused()) {
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(
void V8DebuggerAgentImpl::didPause(
int contextId, v8::Local<v8::Value> exception,
const std::vector<v8::debug::BreakpointId>& hitBreakpoints,
v8::debug::ExceptionType exceptionType, bool isUncaught, bool isOOMBreak,
bool isAssert, bool isStepAction) {
v8::debug::ExceptionType exceptionType, bool isUncaught,
v8::debug::BreakReasons breakReasons) {
v8::HandleScope handles(m_isolate);
std::vector<BreakReason> hitReasons;
if (isOOMBreak) {
if (breakReasons.contains(v8::debug::BreakReason::kOOM)) {
hitReasons.push_back(
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(
protocol::Debugger::Paused::ReasonEnum::Assert, nullptr));
} else if (!exception.IsEmpty()) {
} else if (breakReasons.contains(v8::debug::BreakReason::kException)) {
InjectedScript* injectedScript = nullptr;
m_session->findInjectedScript(contextId, injectedScript);
if (injectedScript) {
......@@ -1824,9 +1824,12 @@ void V8DebuggerAgentImpl::didPause(
// Make sure that we only include (other: nullptr) once.
const BreakReason otherHitReason =
std::make_pair(protocol::Debugger::Paused::ReasonEnum::Other, nullptr);
if ((hitRegularBreakpoint || isStepAction) &&
std::find(hitReasons.begin(), hitReasons.end(), otherHitReason) ==
hitReasons.end()) {
const bool otherBreakReasons =
hitRegularBreakpoint ||
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(
std::make_pair(protocol::Debugger::Paused::ReasonEnum::Other, nullptr));
}
......
......@@ -10,9 +10,9 @@
#include <unordered_map>
#include <vector>
#include "src/base/enum-set.h"
#include "src/base/macros.h"
#include "src/debug/debug-interface.h"
#include "src/debug/interface-types.h"
#include "src/inspector/protocol/Debugger.h"
#include "src/inspector/protocol/Forward.h"
......@@ -152,7 +152,7 @@ class V8DebuggerAgentImpl : public protocol::Debugger::Backend {
void didPause(int contextId, v8::Local<v8::Value> exception,
const std::vector<v8::debug::BreakpointId>& hitBreakpoints,
v8::debug::ExceptionType exceptionType, bool isUncaught,
bool isOOMBreak, bool isAssert, bool isStepAction);
v8::debug::BreakReasons breakReasons);
void didContinue();
void didParseSource(std::unique_ptr<V8DebuggerScript>, bool success);
......
......@@ -239,7 +239,8 @@ void V8Debugger::breakProgramOnAssert(int targetContextGroupId) {
DCHECK(targetContextGroupId);
m_targetContextGroupId = targetContextGroupId;
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,
......@@ -397,8 +398,8 @@ void V8Debugger::clearContinueToLocation() {
void V8Debugger::handleProgramBreak(
v8::Local<v8::Context> pausedContext, v8::Local<v8::Value> exception,
const std::vector<v8::debug::BreakpointId>& breakpointIds,
StepBreak isStepAction, v8::debug::ExceptionType exceptionType,
bool isUncaught) {
v8::debug::BreakReasons breakReasons,
v8::debug::ExceptionType exceptionType, bool isUncaught) {
// Don't allow nested breaks.
if (isPaused()) return;
......@@ -415,8 +416,11 @@ void V8Debugger::handleProgramBreak(
m_taskWithScheduledBreakPauseRequested = false;
bool scheduledOOMBreak = m_scheduledOOMBreak;
DCHECK(scheduledOOMBreak ==
breakReasons.contains(v8::debug::BreakReason::kOOM));
bool scheduledAssertBreak = m_scheduledAssertBreak;
bool hasAgents = false;
m_inspector->forEachSession(
contextGroupId,
[&scheduledOOMBreak, &hasAgents](V8InspectorSessionImpl* session) {
......@@ -472,7 +476,7 @@ void V8Debugger::handleProgramBreak(
session->debuggerAgent()->didPause(
InspectedContext::contextId(pausedContext), {},
instrumentationBreakpointIds,
v8::debug::ExceptionType::kException, false, false, false, false);
v8::debug::ExceptionType::kException, false, {});
});
{
v8::Context::Scope scope(pausedContext);
......@@ -505,16 +509,13 @@ void V8Debugger::handleProgramBreak(
// want to trigger two pause events if we only break because of an
// instrumentation.
m_inspector->forEachSession(
contextGroupId,
[&pausedContext, &exception, &regularBreakpointIds, &exceptionType,
&isUncaught, &scheduledOOMBreak, &scheduledAssertBreak,
&isStepAction](V8InspectorSessionImpl* session) {
contextGroupId, [&pausedContext, &exception, &regularBreakpointIds,
&exceptionType, &isUncaught, &scheduledOOMBreak,
&breakReasons](V8InspectorSessionImpl* session) {
if (session->debuggerAgent()->acceptsPause(scheduledOOMBreak)) {
session->debuggerAgent()->didPause(
InspectedContext::contextId(pausedContext), exception,
regularBreakpointIds, exceptionType, isUncaught,
scheduledOOMBreak, scheduledAssertBreak,
isStepAction == kIsStepBreak);
regularBreakpointIds, exceptionType, isUncaught, breakReasons);
}
});
{
......@@ -553,7 +554,14 @@ size_t V8Debugger::nearHeapLimitCallback(void* data, size_t current_heap_limit,
thisPtr->m_targetContextGroupId =
context.IsEmpty() ? 0 : thisPtr->m_inspector->contextGroupId(context);
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);
return HeapLimitForDebugging(initial_heap_limit);
}
......@@ -584,9 +592,9 @@ void V8Debugger::ScriptCompiled(v8::Local<v8::debug::Script> script,
void V8Debugger::BreakProgramRequested(
v8::Local<v8::Context> pausedContext,
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,
is_step_break);
reasons);
}
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::debug::ExceptionType exceptionType) {
std::vector<v8::debug::BreakpointId> break_points_hit;
handleProgramBreak(pausedContext, exception, break_points_hit, kIsNoStepBreak,
exceptionType, isUncaught);
handleProgramBreak(
pausedContext, exception, break_points_hit,
v8::debug::BreakReasons({v8::debug::BreakReason::kException}),
exceptionType, isUncaught);
}
bool V8Debugger::IsFunctionBlackboxed(v8::Local<v8::debug::Script> script,
......
......@@ -142,7 +142,7 @@ class V8Debugger : public v8::debug::DebugDelegate,
void handleProgramBreak(
v8::Local<v8::Context> pausedContext, v8::Local<v8::Value> exception,
const std::vector<v8::debug::BreakpointId>& hitBreakpoints,
StepBreak isStepBreak = StepBreak::kIsNoStepBreak,
v8::debug::BreakReasons break_reasons,
v8::debug::ExceptionType exception_type = v8::debug::kException,
bool isUncaught = false);
......@@ -180,7 +180,7 @@ class V8Debugger : public v8::debug::DebugDelegate,
void BreakProgramRequested(
v8::Local<v8::Context> paused_context,
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,
v8::Local<v8::Value> exception,
v8::Local<v8::Value> promise, bool is_uncaught,
......
......@@ -137,7 +137,9 @@ RUNTIME_FUNCTION(Runtime_HandleDebuggerStatement) {
SealHandleScope shs(isolate);
DCHECK_EQ(0, args.length());
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();
}
......
......@@ -2922,7 +2922,7 @@ class CountBreakDebugDelegate : public v8::debug::DebugDelegate {
public:
void BreakProgramRequested(v8::Local<v8::Context> paused_context,
const std::vector<int>&,
StepBreak is_step_break) override {
v8::debug::BreakReasons break_reasons) override {
debug_break_count++;
}
int debug_break_count = 0;
......
......@@ -197,7 +197,7 @@ class DebugEventCounter : public v8::debug::DebugDelegate {
public:
void BreakProgramRequested(v8::Local<v8::Context>,
const std::vector<v8::debug::BreakpointId>&,
StepBreak is_step_break) override {
v8::debug::BreakReasons break_reasons) override {
break_point_hit_count++;
// Perform a full deoptimization when the specified number of
// breaks have been hit.
......@@ -220,7 +220,7 @@ class DebugEventBreakPointCollectGarbage : public v8::debug::DebugDelegate {
public:
void BreakProgramRequested(v8::Local<v8::Context>,
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
// on the number of break points hit either scavenge or mark compact
// collector is used.
......@@ -241,7 +241,7 @@ class DebugEventBreak : public v8::debug::DebugDelegate {
public:
void BreakProgramRequested(v8::Local<v8::Context>,
const std::vector<v8::debug::BreakpointId>&,
StepBreak is_step_break) override {
v8::debug::BreakReasons break_reasons) override {
// Count the number of breaks.
break_point_hit_count++;
......@@ -266,7 +266,7 @@ class DebugEventBreakMax : public v8::debug::DebugDelegate {
public:
void BreakProgramRequested(v8::Local<v8::Context>,
const std::vector<v8::debug::BreakpointId>&,
StepBreak is_step_break) override {
v8::debug::BreakReasons break_reasons) override {
v8::Isolate* v8_isolate = CcTest::isolate();
v8::internal::Isolate* isolate = CcTest::i_isolate();
if (break_point_hit_count < max_break_point_hit_count) {
......@@ -3312,7 +3312,7 @@ class ContextCheckEventListener : public v8::debug::DebugDelegate {
void BreakProgramRequested(
v8::Local<v8::Context> paused_context,
const std::vector<v8::debug::BreakpointId>& inspector_break_points_hit,
StepBreak is_step_break) override {
v8::debug::BreakReasons break_reasons) override {
CheckContext();
}
void ScriptCompiled(v8::Local<v8::debug::Script> script, bool is_live_edited,
......@@ -3828,7 +3828,7 @@ class DebugBreakInlineListener : public v8::debug::DebugDelegate {
void BreakProgramRequested(
v8::Local<v8::Context> paused_context,
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_line_number[] = {1, 4, 7, 13};
......@@ -3911,7 +3911,7 @@ class DebugBreakStackTraceListener : public v8::debug::DebugDelegate {
void BreakProgramRequested(
v8::Local<v8::Context> paused_context,
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);
}
};
......@@ -3952,7 +3952,7 @@ class DebugBreakTriggerTerminate : public v8::debug::DebugDelegate {
void BreakProgramRequested(
v8::Local<v8::Context> paused_context,
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;
terminate_requested_semaphore.Signal();
// Wait for at most 2 seconds for the terminate request.
......@@ -4062,7 +4062,7 @@ class ArchiveRestoreThread : public v8::base::Thread,
void BreakProgramRequested(v8::Local<v8::Context> context,
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_);
if (!stack_traces->Done()) {
v8::debug::Location location = stack_traces->GetSourceLocation();
......@@ -4283,7 +4283,7 @@ class DebugStepOverFunctionWithCaughtExceptionListener
void BreakProgramRequested(
v8::Local<v8::Context> paused_context,
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;
if (break_point_hit_count >= 3) return;
PrepareStep(StepOver);
......@@ -4785,7 +4785,7 @@ class SetBreakpointOnScriptCompiled : public v8::debug::DebugDelegate {
void BreakProgramRequested(
v8::Local<v8::Context> paused_context,
const std::vector<v8::debug::BreakpointId>& inspector_break_points_hit,
StepBreak is_step_break) override {
v8::debug::BreakReasons break_reasons) override {
++break_count_;
CHECK_EQ(inspector_break_points_hit[0], id_);
}
......@@ -5212,7 +5212,7 @@ class SetTerminateOnResumeDelegate : public v8::debug::DebugDelegate {
void BreakProgramRequested(
v8::Local<v8::Context> paused_context,
const std::vector<v8::debug::BreakpointId>& inspector_break_points_hit,
StepBreak is_step_break) override {
v8::debug::BreakReasons break_reasons) override {
break_count_++;
v8::Isolate* isolate = paused_context->GetIsolate();
v8::debug::SetTerminateOnResume(isolate);
......@@ -5590,7 +5590,7 @@ class SemaphoreTriggerOnBreak : public v8::debug::DebugDelegate {
void BreakProgramRequested(
v8::Local<v8::Context> paused_context,
const std::vector<v8::debug::BreakpointId>& inspector_break_points_hit,
StepBreak is_step_break) override {
v8::debug::BreakReasons break_reasons) override {
break_count_++;
enter_.Signal();
exit_.Wait();
......
......@@ -111,7 +111,7 @@ class BreakHandler : public debug::DebugDelegate {
void BreakProgramRequested(v8::Local<v8::Context> paused_context,
const std::vector<int>&,
StepBreak is_step_break) override {
v8::debug::BreakReasons break_reasons) override {
printf("Break #%d\n", count_);
CHECK_GT(expected_breaks_.size(), count_);
......@@ -223,7 +223,7 @@ class CollectValuesBreakHandler : public debug::DebugDelegate {
void BreakProgramRequested(v8::Local<v8::Context> paused_context,
const std::vector<int>&,
StepBreak is_step_break) override {
v8::debug::BreakReasons break_reasons) override {
printf("Break #%d\n", count_);
CHECK_GT(expected_values_.size(), count_);
auto& expected = expected_values_[count_];
......
......@@ -15,3 +15,6 @@ Paused with reason: ambiguous and data: {"reasons":[{"reason":"instrumentation",
Running test: testOnlyReportOtherWithEmptyDataOnce
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([
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 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