[inspector] use interrupt for pause only as last resort

With this CL we use interrupt for pause in two cases:
- when we process Debugger.pause on interruption,
- when we would like to break as soon as possible after OOM.
In all other cases, e.g. for async step into we use break
on function call by calling StepIn debugger action.

In mentioned cases we should not actually use interrupt as well:
- Debugger.pause in this case scheduled using interrupt and we
  may just break right now without requesting another interrupt,
  unfortunately blink side is not ready,
- we should use more reliable way to break right after near OOM
  callback, otherwise we can get this callback, increase limit,
  request break on next interrupt, before interrupt get another
  huge memory allocation and crash.

There are couple advantages:
- we get much better break locations for async stepping
  (see inspector tests expectations),
- we can remove DEBUG_BREAK interruption
  (it should speedup blackboxing with async tasks, see
  removed todo in debug.cc for details)
- it is required preparation step for async step out,
  (see https://chromium-review.googlesource.com/c/v8/v8/+/1054618)

Bug: v8:7753
Cq-Include-Trybots: luci.chromium.try:linux_chromium_rel_ng;master.tryserver.blink:linux_trusty_blink_rel
Change-Id: Iabd7627dbffa9a0eab1736064caf589d02591926
Reviewed-on: https://chromium-review.googlesource.com/1054155
Commit-Queue: Aleksey Kozyatinskiy <kozyatinskiy@chromium.org>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Dmitry Gozman <dgozman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#53439}
This commit is contained in:
Alexey Kozyatinskiy 2018-05-29 07:54:08 -07:00 committed by Commit Bot
parent f3131cef16
commit 6d87d95785
24 changed files with 192 additions and 158 deletions

View File

@ -9135,13 +9135,14 @@ void debug::SetLiveEditEnabled(Isolate* isolate, bool enable) {
internal_isolate->debug()->set_live_edit_enabled(enable); internal_isolate->debug()->set_live_edit_enabled(enable);
} }
void debug::DebugBreak(Isolate* isolate) { void debug::SetBreakOnNextFunctionCall(Isolate* isolate) {
reinterpret_cast<i::Isolate*>(isolate)->stack_guard()->RequestDebugBreak(); reinterpret_cast<i::Isolate*>(isolate)->debug()->SetBreakOnNextFunctionCall();
} }
void debug::CancelDebugBreak(Isolate* isolate) { void debug::ClearBreakOnNextFunctionCall(Isolate* isolate) {
i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate); reinterpret_cast<i::Isolate*>(isolate)
internal_isolate->stack_guard()->ClearDebugBreak(); ->debug()
->ClearBreakOnNextFunctionCall();
} }
MaybeLocal<Array> debug::GetInternalProperties(Isolate* v8_isolate, MaybeLocal<Array> debug::GetInternalProperties(Isolate* v8_isolate,
@ -9169,11 +9170,6 @@ void debug::SetBreakPointsActive(Isolate* v8_isolate, bool is_active) {
isolate->debug()->set_break_points_active(is_active); isolate->debug()->set_break_points_active(is_active);
} }
void debug::SetOutOfMemoryCallback(Isolate* isolate,
OutOfMemoryCallback callback, void* data) {
// No-op.
}
void debug::PrepareStep(Isolate* v8_isolate, StepAction action) { void debug::PrepareStep(Isolate* v8_isolate, StepAction action) {
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);

View File

@ -71,13 +71,13 @@ MaybeLocal<Value> Call(Local<Context> context, v8::Local<v8::Function> fun,
*/ */
V8_EXPORT_PRIVATE void SetLiveEditEnabled(Isolate* isolate, bool enable); V8_EXPORT_PRIVATE void SetLiveEditEnabled(Isolate* isolate, bool enable);
// Schedule a debugger break to happen when JavaScript code is run // Schedule a debugger break to happen when function is called inside given
// in the given isolate. // isolate.
void DebugBreak(Isolate* isolate); void SetBreakOnNextFunctionCall(Isolate* isolate);
// Remove scheduled debugger break in given isolate if it has not // Remove scheduled debugger break in given isolate if it has not
// happened yet. // happened yet.
void CancelDebugBreak(Isolate* isolate); void ClearBreakOnNextFunctionCall(Isolate* isolate);
/** /**
* Returns array of internal properties specific to the value type. Result has * Returns array of internal properties specific to the value type. Result has
@ -116,19 +116,6 @@ void BreakRightNow(Isolate* isolate);
bool AllFramesOnStackAreBlackboxed(Isolate* isolate); bool AllFramesOnStackAreBlackboxed(Isolate* isolate);
/**
* Out-of-memory callback function.
* The function is invoked when the heap size is close to the hard limit.
*
* \param data the parameter provided during callback installation.
*/
typedef void (*OutOfMemoryCallback)(void* data);
V8_DEPRECATED("Use v8::Isolate::AddNearHeapLimitCallback",
void SetOutOfMemoryCallback(Isolate* isolate,
OutOfMemoryCallback callback,
void* data));
/** /**
* Native wrapper around v8::internal::Script object. * Native wrapper around v8::internal::Script object.
*/ */

View File

@ -351,6 +351,7 @@ void Debug::ThreadInit() {
thread_local_.restart_fp_ = kNullAddress; thread_local_.restart_fp_ = kNullAddress;
base::Relaxed_Store(&thread_local_.current_debug_scope_, base::Relaxed_Store(&thread_local_.current_debug_scope_,
static_cast<base::AtomicWord>(0)); static_cast<base::AtomicWord>(0));
thread_local_.break_on_next_function_call_ = false;
UpdateHookOnFunctionCall(); UpdateHookOnFunctionCall();
} }
@ -474,11 +475,13 @@ void Debug::Break(JavaScriptFrame* frame, Handle<JSFunction> break_target) {
// Find actual break points, if any, and trigger debug break event. // Find actual break points, if any, and trigger debug break event.
MaybeHandle<FixedArray> break_points_hit = MaybeHandle<FixedArray> break_points_hit =
CheckBreakPoints(debug_info, &location); CheckBreakPoints(debug_info, &location);
if (!break_points_hit.is_null()) { if (!break_points_hit.is_null() || break_on_next_function_call()) {
// Clear all current stepping setup. // Clear all current stepping setup.
ClearStepping(); ClearStepping();
// Notify the debug event listeners. // Notify the debug event listeners.
OnDebugBreak(break_points_hit.ToHandleChecked()); OnDebugBreak(!break_points_hit.is_null()
? break_points_hit.ToHandleChecked()
: isolate_->factory()->empty_fixed_array());
return; return;
} }
@ -898,8 +901,24 @@ MaybeHandle<FixedArray> Debug::GetHitBreakPoints(Handle<DebugInfo> debug_info,
return break_points_hit; return break_points_hit;
} }
void Debug::SetBreakOnNextFunctionCall() {
// This method forces V8 to break on next function call regardless current
// last_step_action_. If any break happens between SetBreakOnNextFunctionCall
// and ClearBreakOnNextFunctionCall, we will clear this flag and stepping. If
// break does not happen, e.g. all called functions are blackboxed or no
// function is called, then we will clear this flag and let stepping continue
// its normal business.
thread_local_.break_on_next_function_call_ = true;
UpdateHookOnFunctionCall();
}
void Debug::ClearBreakOnNextFunctionCall() {
thread_local_.break_on_next_function_call_ = false;
UpdateHookOnFunctionCall();
}
void Debug::PrepareStepIn(Handle<JSFunction> function) { void Debug::PrepareStepIn(Handle<JSFunction> function) {
CHECK(last_step_action() >= StepIn); CHECK(last_step_action() >= StepIn || break_on_next_function_call());
if (ignore_events()) return; if (ignore_events()) return;
if (in_debug_scope()) return; if (in_debug_scope()) return;
if (break_disabled()) return; if (break_disabled()) return;
@ -1159,6 +1178,7 @@ void Debug::ClearStepping() {
thread_local_.fast_forward_to_return_ = false; thread_local_.fast_forward_to_return_ = false;
thread_local_.last_frame_count_ = -1; thread_local_.last_frame_count_ = -1;
thread_local_.target_frame_count_ = -1; thread_local_.target_frame_count_ = -1;
thread_local_.break_on_next_function_call_ = false;
UpdateHookOnFunctionCall(); UpdateHookOnFunctionCall();
} }
@ -2157,7 +2177,8 @@ void Debug::UpdateHookOnFunctionCall() {
STATIC_ASSERT(LastStepAction == StepIn); STATIC_ASSERT(LastStepAction == StepIn);
hook_on_function_call_ = hook_on_function_call_ =
thread_local_.last_step_action_ == StepIn || thread_local_.last_step_action_ == StepIn ||
isolate_->debug_execution_mode() == DebugInfo::kSideEffects; isolate_->debug_execution_mode() == DebugInfo::kSideEffects ||
thread_local_.break_on_next_function_call_;
} }
MaybeHandle<Object> Debug::Call(Handle<Object> fun, Handle<Object> data) { MaybeHandle<Object> Debug::Call(Handle<Object> fun, Handle<Object> data) {
@ -2204,19 +2225,7 @@ void Debug::HandleDebugBreak(IgnoreBreakMode ignore_break_mode) {
bool ignore_break = ignore_break_mode == kIgnoreIfTopFrameBlackboxed bool ignore_break = ignore_break_mode == kIgnoreIfTopFrameBlackboxed
? IsBlackboxed(shared) ? IsBlackboxed(shared)
: AllFramesOnStackAreBlackboxed(); : AllFramesOnStackAreBlackboxed();
if (ignore_break) { if (ignore_break) return;
// Inspector uses pause on next statement for asynchronous breakpoints.
// When breakpoint is fired we try to break on first not blackboxed
// statement. To achieve this goal we need to deoptimize current
// function and don't clear requested DebugBreak even if it's blackboxed
// to be able to break on not blackboxed function call.
// TODO(yangguo): introduce break_on_function_entry since current
// implementation is slow.
if (isolate_->stack_guard()->CheckDebugBreak()) {
Deoptimizer::DeoptimizeFunction(*function);
}
return;
}
JSGlobalObject* global = function->context()->global_object(); JSGlobalObject* global = function->context()->global_object();
// Don't stop in debugger functions. // Don't stop in debugger functions.
if (IsDebugGlobal(global)) return; if (IsDebugGlobal(global)) return;
@ -2225,8 +2234,6 @@ void Debug::HandleDebugBreak(IgnoreBreakMode ignore_break_mode) {
} }
} }
isolate_->stack_guard()->ClearDebugBreak();
// Clear stepping to avoid duplicate breaks. // Clear stepping to avoid duplicate breaks.
ClearStepping(); ClearStepping();

View File

@ -266,6 +266,9 @@ class Debug {
void ClearStepping(); void ClearStepping();
void ClearStepOut(); void ClearStepOut();
void SetBreakOnNextFunctionCall();
void ClearBreakOnNextFunctionCall();
void DeoptimizeFunction(Handle<SharedFunctionInfo> shared); void DeoptimizeFunction(Handle<SharedFunctionInfo> shared);
void PrepareFunctionForDebugExecution(Handle<SharedFunctionInfo> shared); void PrepareFunctionForDebugExecution(Handle<SharedFunctionInfo> shared);
void InstallDebugBreakTrampoline(); void InstallDebugBreakTrampoline();
@ -406,6 +409,9 @@ class Debug {
} }
StepAction last_step_action() { return thread_local_.last_step_action_; } StepAction last_step_action() { return thread_local_.last_step_action_; }
bool break_on_next_function_call() const {
return thread_local_.break_on_next_function_call_;
}
DebugFeatureTracker* feature_tracker() { return &feature_tracker_; } DebugFeatureTracker* feature_tracker() { return &feature_tracker_; }
@ -589,6 +595,10 @@ class Debug {
// Last used inspector breakpoint id. // Last used inspector breakpoint id.
int last_breakpoint_id_; int last_breakpoint_id_;
// This flag is true when SetBreakOnNextFunctionCall is called and it forces
// debugger to break on next function call.
bool break_on_next_function_call_;
}; };
// Storage location for registers when handling debug break calls // Storage location for registers when handling debug break calls

View File

@ -514,15 +514,6 @@ Object* StackGuard::HandleInterrupts() {
isolate_->heap()->HandleGCRequest(); isolate_->heap()->HandleGCRequest();
} }
if (CheckDebugBreak()) {
if (FLAG_trace_interrupts) {
if (any_interrupt_handled) PrintF(", ");
PrintF("DEBUG_BREAK");
any_interrupt_handled = true;
}
isolate_->debug()->HandleDebugBreak(kIgnoreIfTopFrameBlackboxed);
}
if (CheckAndClearInterrupt(TERMINATE_EXECUTION)) { if (CheckAndClearInterrupt(TERMINATE_EXECUTION)) {
if (FLAG_trace_interrupts) { if (FLAG_trace_interrupts) {
if (any_interrupt_handled) PrintF(", "); if (any_interrupt_handled) PrintF(", ");

View File

@ -89,12 +89,11 @@ class V8_EXPORT_PRIVATE StackGuard final {
void ClearThread(const ExecutionAccess& lock); void ClearThread(const ExecutionAccess& lock);
#define INTERRUPT_LIST(V) \ #define INTERRUPT_LIST(V) \
V(DEBUGBREAK, DebugBreak, 0) \ V(TERMINATE_EXECUTION, TerminateExecution, 0) \
V(TERMINATE_EXECUTION, TerminateExecution, 1) \ V(GC_REQUEST, GC, 1) \
V(GC_REQUEST, GC, 2) \ V(INSTALL_CODE, InstallCode, 2) \
V(INSTALL_CODE, InstallCode, 3) \ V(API_INTERRUPT, ApiInterrupt, 3) \
V(API_INTERRUPT, ApiInterrupt, 4) \ V(DEOPT_MARKED_ALLOCATION_SITES, DeoptMarkedAllocationSites, 4)
V(DEOPT_MARKED_ALLOCATION_SITES, DeoptMarkedAllocationSites, 5)
#define V(NAME, Name, id) \ #define V(NAME, Name, id) \
inline bool Check##Name() { return CheckInterrupt(NAME); } \ inline bool Check##Name() { return CheckInterrupt(NAME); } \

View File

@ -477,7 +477,7 @@ Response V8DebuggerAgentImpl::setBreakpointsActive(bool active) {
m_debugger->setBreakpointsActive(active); m_debugger->setBreakpointsActive(active);
if (!active && !m_breakReason.empty()) { if (!active && !m_breakReason.empty()) {
clearBreakDetails(); clearBreakDetails();
m_debugger->setPauseOnNextStatement(false, m_session->contextGroupId()); m_debugger->setPauseOnNextCall(false, m_session->contextGroupId());
} }
return Response::OK(); return Response::OK();
} }
@ -1006,7 +1006,7 @@ void V8DebuggerAgentImpl::schedulePauseOnNextStatement(
std::unique_ptr<protocol::DictionaryValue> data) { std::unique_ptr<protocol::DictionaryValue> data) {
if (isPaused() || !acceptsPause(false) || !m_breakpointsActive) return; if (isPaused() || !acceptsPause(false) || !m_breakpointsActive) return;
if (m_breakReason.empty()) { if (m_breakReason.empty()) {
m_debugger->setPauseOnNextStatement(true, m_session->contextGroupId()); m_debugger->setPauseOnNextCall(true, m_session->contextGroupId());
} }
pushBreakDetails(breakReason, std::move(data)); pushBreakDetails(breakReason, std::move(data));
} }
@ -1014,7 +1014,7 @@ void V8DebuggerAgentImpl::schedulePauseOnNextStatement(
void V8DebuggerAgentImpl::cancelPauseOnNextStatement() { void V8DebuggerAgentImpl::cancelPauseOnNextStatement() {
if (isPaused() || !acceptsPause(false) || !m_breakpointsActive) return; if (isPaused() || !acceptsPause(false) || !m_breakpointsActive) return;
if (m_breakReason.size() == 1) { if (m_breakReason.size() == 1) {
m_debugger->setPauseOnNextStatement(false, m_session->contextGroupId()); m_debugger->setPauseOnNextCall(false, m_session->contextGroupId());
} }
popBreakDetails(); popBreakDetails();
} }
@ -1022,10 +1022,14 @@ void V8DebuggerAgentImpl::cancelPauseOnNextStatement() {
Response V8DebuggerAgentImpl::pause() { Response V8DebuggerAgentImpl::pause() {
if (!enabled()) return Response::Error(kDebuggerNotEnabled); if (!enabled()) return Response::Error(kDebuggerNotEnabled);
if (isPaused()) return Response::OK(); if (isPaused()) return Response::OK();
if (m_breakReason.empty()) { if (m_debugger->canBreakProgram()) {
m_debugger->setPauseOnNextStatement(true, m_session->contextGroupId()); m_debugger->interruptAndBreak(m_session->contextGroupId());
} else {
if (m_breakReason.empty()) {
m_debugger->setPauseOnNextCall(true, m_session->contextGroupId());
}
pushBreakDetails(protocol::Debugger::Paused::ReasonEnum::Other, nullptr);
} }
pushBreakDetails(protocol::Debugger::Paused::ReasonEnum::Other, nullptr);
return Response::OK(); return Response::OK();
} }
@ -1668,7 +1672,7 @@ void V8DebuggerAgentImpl::breakProgram(
popBreakDetails(); popBreakDetails();
m_breakReason.swap(currentScheduledReason); m_breakReason.swap(currentScheduledReason);
if (!m_breakReason.empty()) { if (!m_breakReason.empty()) {
m_debugger->setPauseOnNextStatement(true, m_session->contextGroupId()); m_debugger->setPauseOnNextCall(true, m_session->contextGroupId());
} }
} }

View File

@ -259,7 +259,7 @@ void V8Debugger::setPauseOnExceptionsState(
m_pauseOnExceptionsState = pauseOnExceptionsState; m_pauseOnExceptionsState = pauseOnExceptionsState;
} }
void V8Debugger::setPauseOnNextStatement(bool pause, int targetContextGroupId) { void V8Debugger::setPauseOnNextCall(bool pause, int targetContextGroupId) {
if (isPaused()) return; if (isPaused()) return;
DCHECK(targetContextGroupId); DCHECK(targetContextGroupId);
if (!pause && m_targetContextGroupId && if (!pause && m_targetContextGroupId &&
@ -269,9 +269,9 @@ void V8Debugger::setPauseOnNextStatement(bool pause, int targetContextGroupId) {
m_targetContextGroupId = targetContextGroupId; m_targetContextGroupId = targetContextGroupId;
m_breakRequested = pause; m_breakRequested = pause;
if (pause) if (pause)
v8::debug::DebugBreak(m_isolate); v8::debug::SetBreakOnNextFunctionCall(m_isolate);
else else
v8::debug::CancelDebugBreak(m_isolate); v8::debug::ClearBreakOnNextFunctionCall(m_isolate);
} }
bool V8Debugger::canBreakProgram() { bool V8Debugger::canBreakProgram() {
@ -287,6 +287,16 @@ void V8Debugger::breakProgram(int targetContextGroupId) {
v8::debug::BreakRightNow(m_isolate); v8::debug::BreakRightNow(m_isolate);
} }
void V8Debugger::interruptAndBreak(int targetContextGroupId) {
// Don't allow nested breaks.
if (isPaused()) return;
DCHECK(targetContextGroupId);
m_targetContextGroupId = targetContextGroupId;
m_isolate->RequestInterrupt(
[](v8::Isolate* isolate, void*) { v8::debug::BreakRightNow(isolate); },
nullptr);
}
void V8Debugger::continueProgram(int targetContextGroupId) { void V8Debugger::continueProgram(int targetContextGroupId) {
if (m_pausedContextGroupId != targetContextGroupId) return; if (m_pausedContextGroupId != targetContextGroupId) return;
if (isPaused()) m_inspector->client()->quitMessageLoopOnPause(); if (isPaused()) m_inspector->client()->quitMessageLoopOnPause();
@ -522,8 +532,11 @@ size_t V8Debugger::nearHeapLimitCallback(void* data, size_t current_heap_limit,
thisPtr->m_scheduledOOMBreak = true; thisPtr->m_scheduledOOMBreak = true;
v8::Local<v8::Context> context = thisPtr->m_isolate->GetEnteredContext(); v8::Local<v8::Context> context = thisPtr->m_isolate->GetEnteredContext();
DCHECK(!context.IsEmpty()); DCHECK(!context.IsEmpty());
thisPtr->setPauseOnNextStatement( thisPtr->m_targetContextGroupId =
true, thisPtr->m_inspector->contextGroupId(context)); thisPtr->m_inspector->contextGroupId(context);
thisPtr->m_isolate->RequestInterrupt(
[](v8::Isolate* isolate, void*) { v8::debug::BreakRightNow(isolate); },
nullptr);
return HeapLimitForDebugging(initial_heap_limit); return HeapLimitForDebugging(initial_heap_limit);
} }
@ -851,7 +864,7 @@ void V8Debugger::externalAsyncTaskStarted(const V8StackTraceId& parent) {
reinterpret_cast<uintptr_t>(m_taskWithScheduledBreak) == parent.id && reinterpret_cast<uintptr_t>(m_taskWithScheduledBreak) == parent.id &&
m_taskWithScheduledBreakDebuggerId == m_taskWithScheduledBreakDebuggerId ==
debuggerIdToString(parent.debugger_id)) { debuggerIdToString(parent.debugger_id)) {
v8::debug::DebugBreak(m_isolate); v8::debug::SetBreakOnNextFunctionCall(m_isolate);
} }
} }
@ -871,7 +884,7 @@ void V8Debugger::externalAsyncTaskFinished(const V8StackTraceId& parent) {
m_taskWithScheduledBreak = nullptr; m_taskWithScheduledBreak = nullptr;
m_taskWithScheduledBreakDebuggerId = String16(); m_taskWithScheduledBreakDebuggerId = String16();
if (m_breakRequested) return; if (m_breakRequested) return;
v8::debug::CancelDebugBreak(m_isolate); v8::debug::ClearBreakOnNextFunctionCall(m_isolate);
} }
void V8Debugger::asyncTaskScheduled(const StringView& taskName, void* task, void V8Debugger::asyncTaskScheduled(const StringView& taskName, void* task,
@ -980,7 +993,7 @@ void V8Debugger::asyncTaskStartedForStepping(void* task) {
// blackboxing. // blackboxing.
if (m_taskWithScheduledBreakDebuggerId.isEmpty() && if (m_taskWithScheduledBreakDebuggerId.isEmpty() &&
task == m_taskWithScheduledBreak) { task == m_taskWithScheduledBreak) {
v8::debug::DebugBreak(m_isolate); v8::debug::SetBreakOnNextFunctionCall(m_isolate);
} }
} }
@ -991,7 +1004,7 @@ void V8Debugger::asyncTaskFinishedForStepping(void* task) {
} }
m_taskWithScheduledBreak = nullptr; m_taskWithScheduledBreak = nullptr;
if (m_breakRequested) return; if (m_breakRequested) return;
v8::debug::CancelDebugBreak(m_isolate); v8::debug::ClearBreakOnNextFunctionCall(m_isolate);
} }
void V8Debugger::asyncTaskCanceledForStepping(void* task) { void V8Debugger::asyncTaskCanceledForStepping(void* task) {

View File

@ -49,10 +49,11 @@ class V8Debugger : public v8::debug::DebugDelegate {
void setPauseOnExceptionsState(v8::debug::ExceptionBreakState); void setPauseOnExceptionsState(v8::debug::ExceptionBreakState);
bool canBreakProgram(); bool canBreakProgram();
void breakProgram(int targetContextGroupId); void breakProgram(int targetContextGroupId);
void interruptAndBreak(int targetContextGroupId);
void continueProgram(int targetContextGroupId); void continueProgram(int targetContextGroupId);
void breakProgramOnAssert(int targetContextGroupId); void breakProgramOnAssert(int targetContextGroupId);
void setPauseOnNextStatement(bool, int targetContextGroupId); void setPauseOnNextCall(bool, int targetContextGroupId);
void stepIntoStatement(int targetContextGroupId, bool breakOnAsyncCall); void stepIntoStatement(int targetContextGroupId, bool breakOnAsyncCall);
void stepOverStatement(int targetContextGroupId); void stepOverStatement(int targetContextGroupId);
void stepOutOfFunction(int targetContextGroupId); void stepOutOfFunction(int targetContextGroupId);

View File

@ -40,7 +40,6 @@ class JsonParser BASE_EMBEDDED {
public: public:
V8_WARN_UNUSED_RESULT static MaybeHandle<Object> Parse( V8_WARN_UNUSED_RESULT static MaybeHandle<Object> Parse(
Isolate* isolate, Handle<String> source, Handle<Object> reviver) { Isolate* isolate, Handle<String> source, Handle<Object> reviver) {
PostponeInterruptsScope no_debug_breaks(isolate, StackGuard::DEBUGBREAK);
Handle<Object> result; Handle<Object> result;
ASSIGN_RETURN_ON_EXCEPTION(isolate, result, ASSIGN_RETURN_ON_EXCEPTION(isolate, result,
JsonParser(isolate, source).ParseJson(), Object); JsonParser(isolate, source).ParseJson(), Object);

View File

@ -94,7 +94,6 @@ MaybeHandle<Object> JsonStringifier::Stringify(Handle<Object> object,
if (!gap->IsUndefined(isolate_) && !InitializeGap(gap)) { if (!gap->IsUndefined(isolate_) && !InitializeGap(gap)) {
return MaybeHandle<Object>(); return MaybeHandle<Object>();
} }
PostponeInterruptsScope no_debug_breaks(isolate_, StackGuard::DEBUGBREAK);
Result result = SerializeObject(object); Result result = SerializeObject(object);
if (result == UNCHANGED) return factory()->undefined_value(); if (result == UNCHANGED) return factory()->undefined_value();
if (result == SUCCESS) return builder_.Finish(); if (result == SUCCESS) return builder_.Finish();

View File

@ -129,11 +129,12 @@ RUNTIME_FUNCTION(Runtime_HandleDebuggerStatement) {
return isolate->stack_guard()->HandleInterrupts(); return isolate->stack_guard()->HandleInterrupts();
} }
RUNTIME_FUNCTION(Runtime_ScheduleBreak) { RUNTIME_FUNCTION(Runtime_ScheduleBreak) {
SealHandleScope shs(isolate); SealHandleScope shs(isolate);
DCHECK_EQ(0, args.length()); DCHECK_EQ(0, args.length());
isolate->stack_guard()->RequestDebugBreak(); isolate->RequestInterrupt(
[](v8::Isolate* isolate, void*) { v8::debug::BreakRightNow(isolate); },
nullptr);
return isolate->heap()->undefined_value(); return isolate->heap()->undefined_value();
} }
@ -1680,7 +1681,8 @@ RUNTIME_FUNCTION(Runtime_DebugOnFunctionCall) {
if (isolate->debug()->needs_check_on_function_call()) { if (isolate->debug()->needs_check_on_function_call()) {
// Ensure that the callee will perform debug check on function call too. // Ensure that the callee will perform debug check on function call too.
Deoptimizer::DeoptimizeFunction(*fun); Deoptimizer::DeoptimizeFunction(*fun);
if (isolate->debug()->last_step_action() >= StepIn) { if (isolate->debug()->last_step_action() >= StepIn ||
isolate->debug()->break_on_next_function_call()) {
DCHECK_EQ(isolate->debug_execution_mode(), DebugInfo::kBreakpoints); DCHECK_EQ(isolate->debug_execution_mode(), DebugInfo::kBreakpoints);
isolate->debug()->PrepareStepIn(fun); isolate->debug()->PrepareStepIn(fun);
} }

View File

@ -700,10 +700,13 @@ static void DebugEventBreak(
CcTest::CollectGarbage(v8::internal::NEW_SPACE); CcTest::CollectGarbage(v8::internal::NEW_SPACE);
// Set the break flag again to come back here as soon as possible. // Set the break flag again to come back here as soon as possible.
v8::debug::DebugBreak(CcTest::isolate()); v8::debug::SetBreakOnNextFunctionCall(CcTest::isolate());
} }
} }
static void BreakRightNow(v8::Isolate* isolate, void*) {
v8::debug::BreakRightNow(isolate);
}
// Debug event handler which re-issues a debug break until a limit has been // Debug event handler which re-issues a debug break until a limit has been
// reached. // reached.
@ -724,7 +727,7 @@ static void DebugEventBreakMax(
break_point_hit_count++; break_point_hit_count++;
// Set the break flag again to come back here as soon as possible. // Set the break flag again to come back here as soon as possible.
v8::debug::DebugBreak(v8_isolate); v8_isolate->RequestInterrupt(BreakRightNow, nullptr);
} else if (terminate_after_max_break_point_hit) { } else if (terminate_after_max_break_point_hit) {
// Terminate execution after the last break if requested. // Terminate execution after the last break if requested.
@ -3905,7 +3908,7 @@ TEST(DebugBreak) {
f3->Call(context, env->Global(), 0, nullptr).ToLocalChecked(); f3->Call(context, env->Global(), 0, nullptr).ToLocalChecked();
// Set the debug break flag. // Set the debug break flag.
v8::debug::DebugBreak(env->GetIsolate()); v8::debug::SetBreakOnNextFunctionCall(env->GetIsolate());
// Call all functions with different argument count. // Call all functions with different argument count.
break_point_hit_count = 0; break_point_hit_count = 0;
@ -4004,7 +4007,7 @@ TEST(DebugBreakWithoutJS) {
SetDebugEventListener(isolate, DebugEventBreak); SetDebugEventListener(isolate, DebugEventBreak);
// Set the debug break flag. // Set the debug break flag.
v8::debug::DebugBreak(env->GetIsolate()); v8::debug::SetBreakOnNextFunctionCall(env->GetIsolate());
v8::Local<v8::String> json = v8_str("[1]"); v8::Local<v8::String> json = v8_str("[1]");
v8::Local<v8::Value> parsed = v8::JSON::Parse(context, json).ToLocalChecked(); v8::Local<v8::Value> parsed = v8::JSON::Parse(context, json).ToLocalChecked();
@ -4036,11 +4039,11 @@ TEST(DisableBreak) {
v8::Local<v8::Function> f = CompileFunction(&env, src, "f"); v8::Local<v8::Function> f = CompileFunction(&env, src, "f");
// Set, test and cancel debug break. // Set, test and cancel debug break.
v8::debug::DebugBreak(env->GetIsolate()); v8::debug::SetBreakOnNextFunctionCall(env->GetIsolate());
v8::debug::CancelDebugBreak(env->GetIsolate()); v8::debug::ClearBreakOnNextFunctionCall(env->GetIsolate());
// Set the debug break flag. // Set the debug break flag.
v8::debug::DebugBreak(env->GetIsolate()); v8::debug::SetBreakOnNextFunctionCall(env->GetIsolate());
// Call all functions with different argument count. // Call all functions with different argument count.
break_point_hit_count = 0; break_point_hit_count = 0;
@ -4048,7 +4051,7 @@ TEST(DisableBreak) {
CHECK_EQ(1, break_point_hit_count); CHECK_EQ(1, break_point_hit_count);
{ {
v8::debug::DebugBreak(env->GetIsolate()); v8::debug::SetBreakOnNextFunctionCall(env->GetIsolate());
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(env->GetIsolate()); i::Isolate* isolate = reinterpret_cast<i::Isolate*>(env->GetIsolate());
v8::internal::DisableBreak disable_break(isolate->debug()); v8::internal::DisableBreak disable_break(isolate->debug());
f->Call(context, env->Global(), 0, nullptr).ToLocalChecked(); f->Call(context, env->Global(), 0, nullptr).ToLocalChecked();
@ -4094,7 +4097,7 @@ TEST(NoBreakWhenBootstrapping) {
SetDebugEventListener(isolate, DebugEventCounter); SetDebugEventListener(isolate, DebugEventCounter);
// Set the debug break flag. // Set the debug break flag.
v8::debug::DebugBreak(isolate); v8::debug::SetBreakOnNextFunctionCall(isolate);
break_point_hit_count = 0; break_point_hit_count = 0;
{ {
// Create a context with an extension to make sure that some JavaScript // Create a context with an extension to make sure that some JavaScript
@ -5148,7 +5151,7 @@ static void DebugBreakEventListener(const v8::Debug::EventDetails& details) {
if (details.GetEvent() == v8::Break) { if (details.GetEvent() == v8::Break) {
event_listener_break_hit_count++; event_listener_break_hit_count++;
if (event_listener_break_hit_count == 1) { if (event_listener_break_hit_count == 1) {
v8::debug::DebugBreak(details.GetIsolate()); details.GetIsolate()->RequestInterrupt(BreakRightNow, nullptr);
} }
} }
} }
@ -5216,7 +5219,7 @@ static void DebugEventDebugBreak(
// Keep forcing breaks. // Keep forcing breaks.
if (break_point_hit_count < 20) { if (break_point_hit_count < 20) {
v8::debug::DebugBreak(CcTest::isolate()); v8::debug::SetBreakOnNextFunctionCall(CcTest::isolate());
} }
} }
} }
@ -5247,7 +5250,7 @@ TEST(RegExpDebugBreak) {
CHECK_EQ(12, result->Int32Value(context).FromJust()); CHECK_EQ(12, result->Int32Value(context).FromJust());
SetDebugEventListener(env->GetIsolate(), DebugEventDebugBreak); SetDebugEventListener(env->GetIsolate(), DebugEventDebugBreak);
v8::debug::DebugBreak(env->GetIsolate()); v8::debug::SetBreakOnNextFunctionCall(env->GetIsolate());
result = f->Call(context, env->Global(), argc, argv).ToLocalChecked(); result = f->Call(context, env->Global(), argc, argv).ToLocalChecked();
// Check that there was only one break event. Matching RegExp should not // Check that there was only one break event. Matching RegExp should not
@ -5325,7 +5328,7 @@ TEST(AfterCompileEventWhenEventListenerIsReset) {
SetDebugEventListener(env->GetIsolate(), nullptr); SetDebugEventListener(env->GetIsolate(), nullptr);
SetDebugEventListener(env->GetIsolate(), AfterCompileEventListener); SetDebugEventListener(env->GetIsolate(), AfterCompileEventListener);
v8::debug::DebugBreak(env->GetIsolate()); v8::debug::SetBreakOnNextFunctionCall(env->GetIsolate());
v8::Script::Compile(context, v8_str(env->GetIsolate(), script)) v8::Script::Compile(context, v8_str(env->GetIsolate(), script))
.ToLocalChecked() .ToLocalChecked()
->Run(context) ->Run(context)
@ -5416,7 +5419,7 @@ TEST(BreakEventWhenEventListenerIsReset) {
SetDebugEventListener(env->GetIsolate(), nullptr); SetDebugEventListener(env->GetIsolate(), nullptr);
SetDebugEventListener(env->GetIsolate(), AfterCompileEventListener); SetDebugEventListener(env->GetIsolate(), AfterCompileEventListener);
v8::debug::DebugBreak(env->GetIsolate()); v8::debug::SetBreakOnNextFunctionCall(env->GetIsolate());
v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast(
env->Global() env->Global()
->Get(context, v8_str(env->GetIsolate(), "f")) ->Get(context, v8_str(env->GetIsolate(), "f"))
@ -5508,7 +5511,7 @@ TEST(NoDebugBreakInAfterCompileEventListener) {
SetDebugEventListener(env->GetIsolate(), BreakEventListener); SetDebugEventListener(env->GetIsolate(), BreakEventListener);
// Set the debug break flag. // Set the debug break flag.
v8::debug::DebugBreak(env->GetIsolate()); v8::debug::SetBreakOnNextFunctionCall(env->GetIsolate());
// Create a function for testing stepping. // Create a function for testing stepping.
const char* src = "function f() { eval('var x = 10;'); } "; const char* src = "function f() { eval('var x = 10;'); } ";
@ -5518,7 +5521,7 @@ TEST(NoDebugBreakInAfterCompileEventListener) {
CHECK_EQ(1, break_point_hit_count); CHECK_EQ(1, break_point_hit_count);
// Set the debug break flag again. // Set the debug break flag again.
v8::debug::DebugBreak(env->GetIsolate()); v8::debug::SetBreakOnNextFunctionCall(env->GetIsolate());
f->Call(context, env->Global(), 0, nullptr).ToLocalChecked(); f->Call(context, env->Global(), 0, nullptr).ToLocalChecked();
// There should be one more break event when the script is evaluated in 'f'. // There should be one more break event when the script is evaluated in 'f'.
CHECK_EQ(2, break_point_hit_count); CHECK_EQ(2, break_point_hit_count);
@ -5547,7 +5550,7 @@ TEST(DebugBreakFunctionApply) {
SetDebugEventListener(env->GetIsolate(), DebugEventBreakMax); SetDebugEventListener(env->GetIsolate(), DebugEventBreakMax);
// Set the debug break flag before calling the code using function.apply. // Set the debug break flag before calling the code using function.apply.
v8::debug::DebugBreak(env->GetIsolate()); v8::debug::SetBreakOnNextFunctionCall(env->GetIsolate());
// Limit the number of debug breaks. This is a regression test for issue 493 // Limit the number of debug breaks. This is a regression test for issue 493
// where this test would enter an infinite loop. // where this test would enter an infinite loop.
@ -5705,7 +5708,7 @@ static void DebugEventBreakDeoptimize(
} }
} }
v8::debug::DebugBreak(CcTest::isolate()); v8::debug::SetBreakOnNextFunctionCall(CcTest::isolate());
} }
} }
@ -5736,7 +5739,7 @@ TEST(DeoptimizeDuringDebugBreak) {
.ToLocalChecked(); .ToLocalChecked();
// Set debug break and call bar again. // Set debug break and call bar again.
v8::debug::DebugBreak(env->GetIsolate()); v8::debug::SetBreakOnNextFunctionCall(env->GetIsolate());
f->Call(context, v8::Undefined(env->GetIsolate()), 0, nullptr) f->Call(context, v8::Undefined(env->GetIsolate()), 0, nullptr)
.ToLocalChecked(); .ToLocalChecked();
@ -5810,7 +5813,7 @@ static void DebugEventBreakWithOptimizedStack(
static void ScheduleBreak(const v8::FunctionCallbackInfo<v8::Value>& args) { static void ScheduleBreak(const v8::FunctionCallbackInfo<v8::Value>& args) {
SetDebugEventListener(args.GetIsolate(), DebugEventBreakWithOptimizedStack); SetDebugEventListener(args.GetIsolate(), DebugEventBreakWithOptimizedStack);
v8::debug::DebugBreak(args.GetIsolate()); v8::debug::SetBreakOnNextFunctionCall(args.GetIsolate());
} }
@ -5883,7 +5886,7 @@ static void TestDebugBreakInLoop(const char* loop_head,
CompileRun(buffer.start()); CompileRun(buffer.start());
// Set the debug break to enter the debugger as soon as possible. // Set the debug break to enter the debugger as soon as possible.
v8::debug::DebugBreak(CcTest::isolate()); v8::debug::SetBreakOnNextFunctionCall(CcTest::isolate());
// Call function with infinite loop. // Call function with infinite loop.
CompileRun("f();"); CompileRun("f();");
@ -6149,7 +6152,7 @@ static void DebugBreakStackTraceListener(
static void AddDebugBreak(const v8::FunctionCallbackInfo<v8::Value>& args) { static void AddDebugBreak(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::debug::DebugBreak(args.GetIsolate()); v8::debug::SetBreakOnNextFunctionCall(args.GetIsolate());
} }
@ -6215,7 +6218,7 @@ TEST(DebugBreakOffThreadTerminate) {
TerminationThread terminator(isolate); TerminationThread terminator(isolate);
terminator.Start(); terminator.Start();
v8::TryCatch try_catch(env->GetIsolate()); v8::TryCatch try_catch(env->GetIsolate());
v8::debug::DebugBreak(isolate); env->GetIsolate()->RequestInterrupt(BreakRightNow, nullptr);
CompileRun("while (true);"); CompileRun("while (true);");
CHECK(try_catch.HasTerminated()); CHECK(try_catch.HasTerminated());
} }

View File

@ -23,7 +23,7 @@ break aux data: {
} }
] ]
} }
callback (user.js:31:17) callback (user.js:32:2)
doFrameworkWork (framework.js:16:2) doFrameworkWork (framework.js:16:2)
frameworkCall (framework.js:9:12) frameworkCall (framework.js:9:12)
testFunction (user.js:27:12) testFunction (user.js:27:12)

View File

@ -13,10 +13,6 @@ Running test: testFooNotBlackboxed
result : { result : {
} }
} }
foo (test.js:8:12)
testFunction (test.js:15:2)
(anonymous) (expr.js:0:0)
foo (test.js:9:2) foo (test.js:9:2)
testFunction (test.js:15:2) testFunction (test.js:15:2)
(anonymous) (expr.js:0:0) (anonymous) (expr.js:0:0)
@ -32,9 +28,6 @@ Running test: testFooBlackboxed
result : { result : {
} }
} }
testFunction (test.js:14:21)
(anonymous) (expr.js:0:0)
testFunction (test.js:15:2) testFunction (test.js:15:2)
(anonymous) (expr.js:0:0) (anonymous) (expr.js:0:0)
@ -58,10 +51,6 @@ Running test: testBooPartiallyBlackboxed1
result : { result : {
} }
} }
foo (test.js:8:12)
testFunction (test.js:15:2)
(anonymous) (expr.js:0:0)
foo (test.js:9:2) foo (test.js:9:2)
testFunction (test.js:15:2) testFunction (test.js:15:2)
(anonymous) (expr.js:0:0) (anonymous) (expr.js:0:0)
@ -87,10 +76,6 @@ Running test: testBooPartiallyBlackboxed2
result : { result : {
} }
} }
foo (test.js:8:12)
testFunction (test.js:15:2)
(anonymous) (expr.js:0:0)
foo (test.js:9:2) foo (test.js:9:2)
testFunction (test.js:15:2) testFunction (test.js:15:2)
(anonymous) (expr.js:0:0) (anonymous) (expr.js:0:0)
@ -116,10 +101,6 @@ Running test: testBooPartiallyBlackboxed3
result : { result : {
} }
} }
foo (test.js:8:12)
testFunction (test.js:15:2)
(anonymous) (expr.js:0:0)
foo (test.js:9:2) foo (test.js:9:2)
testFunction (test.js:15:2) testFunction (test.js:15:2)
(anonymous) (expr.js:0:0) (anonymous) (expr.js:0:0)

View File

@ -2,12 +2,12 @@ Checks Debugger.pause
Running test: testPause Running test: testPause
paused at: paused at:
#var a = 42; var a = #42;
Running test: testSkipFrameworks Running test: testSkipFrameworks
paused at: paused at:
#var a = 239; var a = #239;
Running test: testSkipOtherContext1 Running test: testSkipOtherContext1
@ -17,26 +17,26 @@ var a = #1;
Running test: testSkipOtherContext2 Running test: testSkipOtherContext2
paused at: paused at:
#var a = 239; var a = #239;
paused at: paused at:
var a = #239; var a = 239#;
Running test: testWithNativeBreakpoint Running test: testWithNativeBreakpoint
paused at: paused at:
#var a = 42; var a = #42;
paused at: paused at:
#var a = 42; var a = #42;
paused at: paused at:
#var a = 42; var a = #42;
Running test: testResumeAnotherGroup Running test: testResumeAnotherGroup
paused at: paused at:
#var a = 42; var a = #42;
{ {
error : { error : {

View File

@ -0,0 +1,4 @@
Checks pause inside blackboxed optimized function call.
bar (test.js:2:4)
foo (framework.js:2:15)
(anonymous) (expr.js:1:12)

View File

@ -0,0 +1,38 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
let {session, contextGroup, Protocol} = InspectorTest.start(
'Checks pause inside blackboxed optimized function call.');
contextGroup.addScript(`
function foo() {
return 1 + bar();
}
//# sourceURL=framework.js
`);
contextGroup.addScript(`
function bar() {
return 2;
}
foo();
foo();
%OptimizeFunctionOnNextCall(foo);
foo();
//# sourceURL=test.js
`);
(async function test(){
Protocol.Debugger.enable();
Protocol.Debugger.setBlackboxPatterns({patterns: ['framework\.js']});
Protocol.Runtime.evaluate({expression: `
inspector.callWithScheduledBreak(foo, 'break', '');
//# sourceURL=expr.js
`});
const {params:{callFrames}} = await Protocol.Debugger.oncePaused();
session.logCallFrames(callFrames);
InspectorTest.completeTest();
})();

View File

@ -37,7 +37,7 @@ asyncCallStackTraceId is set
paused at: paused at:
debugger; debugger;
Promise.resolve().then(#v => v * 2); Promise.resolve().then(v => v #* 2);
} }
@ -61,7 +61,7 @@ asyncCallStackTraceId is set
paused at: paused at:
debugger; debugger;
p.then(#v => v * 2); p.then(v => v #* 2);
resolveCallback(); resolveCallback();
@ -85,7 +85,7 @@ asyncCallStackTraceId is set
paused at: paused at:
debugger; debugger;
Promise.resolve().then(#v => v * 2); Promise.resolve().then(v => v #* 2);
Promise.resolve().then(v => v * 4); Promise.resolve().then(v => v * 4);
@ -114,7 +114,7 @@ asyncCallStackTraceId is set
paused at: paused at:
Promise.resolve().then(v => v * 2); Promise.resolve().then(v => v * 2);
Promise.resolve().then(#v => v * 4); Promise.resolve().then(v => v #* 4);
} }
@ -155,7 +155,7 @@ asyncCallStackTraceId is set
paused at: paused at:
debugger; debugger;
Promise.resolve().then(#v => v * 4); Promise.resolve().then(v => v #* 4);
} }
@ -179,7 +179,7 @@ asyncCallStackTraceId is set
paused at: paused at:
debugger; debugger;
Promise.all([ Promise.resolve(), Promise.resolve() ]).then(#v => v * 2); Promise.all([ Promise.resolve(), Promise.resolve() ]).then(v => v #* 2);
} }
@ -203,7 +203,7 @@ asyncCallStackTraceId is set
paused at: paused at:
debugger; debugger;
createPromise().then(#v => v * 2); createPromise().then(v => v #* 2);
} }
@ -227,7 +227,7 @@ asyncCallStackTraceId is set
paused at: paused at:
debugger; debugger;
createPromise().then(#v => v * 2); createPromise().then(v => v #* 2);
} }
@ -280,7 +280,7 @@ paused at:
asyncCallStackTraceId is set asyncCallStackTraceId is set
paused at: paused at:
function boo() {
function boo#() { #}
} }

View File

@ -44,7 +44,7 @@ paused at:
} }
paused at: paused at:
debugger; debugger;
Promise.resolve().then(#v => v * 2); Promise.resolve().then(v => v #* 2);
} }
@ -66,7 +66,7 @@ paused at:
} }
paused at: paused at:
debugger; debugger;
p.then(#v => v * 2); p.then(v => v #* 2);
resolveCallback(); resolveCallback();
@ -83,7 +83,7 @@ function testTwoAsyncTasks() {
} }
paused at: paused at:
debugger; debugger;
Promise.resolve().then(#v => v * 2); Promise.resolve().then(v => v #* 2);
Promise.resolve().then(v => v * 4); Promise.resolve().then(v => v * 4);
@ -110,7 +110,7 @@ paused at:
} }
paused at: paused at:
Promise.resolve().then(v => v * 2); Promise.resolve().then(v => v * 2);
Promise.resolve().then(#v => v * 4); Promise.resolve().then(v => v #* 4);
} }
@ -142,7 +142,7 @@ paused at:
} }
paused at: paused at:
debugger; debugger;
Promise.resolve().then(#v => v * 4); Promise.resolve().then(v => v #* 4);
} }
@ -164,7 +164,7 @@ paused at:
} }
paused at: paused at:
debugger; debugger;
Promise.all([ Promise.resolve(), Promise.resolve() ]).then(#v => v * 2); Promise.all([ Promise.resolve(), Promise.resolve() ]).then(v => v #* 2);
} }
@ -186,6 +186,6 @@ paused at:
} }
paused at: paused at:
debugger; debugger;
createPromise().then(#v => v * 2); createPromise().then(v => v #* 2);
} }

View File

@ -5,7 +5,7 @@ paused at:
debugger; #setTimeout(() => 1, 0); debugger; #setTimeout(() => 1, 0);
paused at: paused at:
debugger; setTimeout(#() => 1, 0); debugger; setTimeout(() => #1, 0);
Running test: testDebuggerStmtBeforeCallback1 Running test: testDebuggerStmtBeforeCallback1
@ -42,5 +42,5 @@ paused at:
#setTimeout(() => 42, 0) #setTimeout(() => 42, 0)
paused at: paused at:
setTimeout(#() => 42, 0) setTimeout(() => #42, 0)

View File

@ -3,11 +3,11 @@ Test for Debugger.stepInto with breakOnAsyncCall.
Running test: testSetTimeout Running test: testSetTimeout
(anonymous) (test.js:0:0) (anonymous) (test.js:0:0)
asyncCallStackTraceId is set asyncCallStackTraceId is set
setTimeout (test.js:0:11) setTimeout (test.js:0:17)
asyncCallStackTraceId is empty asyncCallStackTraceId is empty
Running test: testPromiseThen Running test: testPromiseThen
(anonymous) (test.js:0:2) (anonymous) (test.js:0:2)
asyncCallStackTraceId is set asyncCallStackTraceId is set
p.then (test.js:0:7) p.then (test.js:0:13)
asyncCallStackTraceId is empty asyncCallStackTraceId is empty

View File

@ -5,7 +5,7 @@ Run stepInto with breakOnAsyncCall flag
Call pauseOnAsyncCall Call pauseOnAsyncCall
Trigger external async task on another context group Trigger external async task on another context group
Dump stack trace Dump stack trace
boo (target.js:1:18) boo (target.js:1:22)
call (framework.js:3:2) call (framework.js:3:2)
(anonymous) (target.js:0:0) (anonymous) (target.js:0:0)
-- remote-task -- -- remote-task --

View File

@ -5,7 +5,7 @@ Run stepInto with breakOnAsyncCall flag
Call pauseOnAsyncCall Call pauseOnAsyncCall
Trigger external async task on another context group Trigger external async task on another context group
Dump stack trace Dump stack trace
boo (target.js:1:18) boo (target.js:1:22)
call (framework.js:3:2) call (framework.js:3:2)
(anonymous) (target.js:0:0) (anonymous) (target.js:0:0)
-- remote-task -- -- remote-task --