#include "src/debug/debug.h"
#include <memory>
#include <optional>
#include "src/api/api-inl.h"
#include "src/base/platform/mutex.h"
#include "src/builtins/builtins.h"
#include "src/codegen/compilation-cache.h"
#include "src/codegen/compiler.h"
#include "src/common/assert-scope.h"
#include "src/common/globals.h"
#include "src/common/message-template.h"
#include "src/debug/debug-evaluate.h"
#include "src/debug/liveedit.h"
#include "src/deoptimizer/deoptimizer.h"
#include "src/execution/execution.h"
#include "src/execution/frames-inl.h"
#include "src/execution/isolate-inl.h"
#include "src/execution/protectors-inl.h"
#include "src/execution/v8threads.h"
#include "src/handles/global-handles-inl.h"
#include "src/heap/heap-inl.h"
#include "src/init/bootstrapper.h"
#include "src/interpreter/bytecode-array-iterator.h"
#include "src/logging/counters.h"
#include "src/logging/runtime-call-stats-scope.h"
#include "src/objects/api-callbacks-inl.h"
#include "src/objects/debug-objects-inl.h"
#include "src/objects/js-generator-inl.h"
#include "src/objects/js-promise-inl.h"
#include "src/objects/slots.h"
#include "src/snapshot/embedded/embedded-data.h"
#if V8_ENABLE_WEBASSEMBLY
#include "src/wasm/wasm-debug.h"
#include "src/wasm/wasm-objects-inl.h"
#endif
namespace v8 {
namespace internal {
class Debug::TemporaryObjectsTracker : public HeapObjectAllocationTracker { … };
Debug::Debug(Isolate* isolate)
: … { … }
Debug::~Debug() { … }
BreakLocation BreakLocation::FromFrame(Handle<DebugInfo> debug_info,
JavaScriptFrame* frame) { … }
bool BreakLocation::IsPausedInJsFunctionEntry(JavaScriptFrame* frame) { … }
MaybeHandle<FixedArray> Debug::CheckBreakPointsForLocations(
Handle<DebugInfo> debug_info, std::vector<BreakLocation>& break_locations,
bool* has_break_points) { … }
void BreakLocation::AllAtCurrentStatement(
Handle<DebugInfo> debug_info, JavaScriptFrame* frame,
std::vector<BreakLocation>* result_out) { … }
Tagged<JSGeneratorObject> BreakLocation::GetGeneratorObjectForSuspendedFrame(
JavaScriptFrame* frame) const { … }
int BreakLocation::BreakIndexFromCodeOffset(
Handle<DebugInfo> debug_info, DirectHandle<AbstractCode> abstract_code,
int offset) { … }
bool BreakLocation::HasBreakPoint(Isolate* isolate,
Handle<DebugInfo> debug_info) const { … }
debug::BreakLocationType BreakLocation::type() const { … }
BreakIterator::BreakIterator(Handle<DebugInfo> debug_info)
: … { … }
int BreakIterator::BreakIndexFromPosition(int source_position) { … }
void BreakIterator::Next() { … }
DebugBreakType BreakIterator::GetDebugBreakType() { … }
void BreakIterator::SkipToPosition(int position) { … }
void BreakIterator::SetDebugBreak() { … }
void BreakIterator::ClearDebugBreak() { … }
BreakLocation BreakIterator::GetBreakLocation() { … }
Isolate* BreakIterator::isolate() { … }
void Debug::ThreadInit() { … }
char* Debug::ArchiveDebug(char* storage) { … }
char* Debug::RestoreDebug(char* storage) { … }
int Debug::ArchiveSpacePerThread() { … }
void Debug::Iterate(RootVisitor* v) { … }
char* Debug::Iterate(RootVisitor* v, char* thread_storage) { … }
void Debug::Iterate(RootVisitor* v, ThreadLocal* thread_local_data) { … }
void DebugInfoCollection::Insert(Tagged<SharedFunctionInfo> sfi,
Tagged<DebugInfo> debug_info) { … }
bool DebugInfoCollection::Contains(Tagged<SharedFunctionInfo> sfi) const { … }
std::optional<Tagged<DebugInfo>> DebugInfoCollection::Find(
Tagged<SharedFunctionInfo> sfi) const { … }
void DebugInfoCollection::DeleteSlow(Tagged<SharedFunctionInfo> sfi) { … }
Tagged<DebugInfo> DebugInfoCollection::EntryAsDebugInfo(size_t index) const { … }
void DebugInfoCollection::DeleteIndex(size_t index) { … }
void Debug::Unload() { … }
debug::DebugDelegate::ActionAfterInstrumentation
Debug::OnInstrumentationBreak() { … }
void Debug::Break(JavaScriptFrame* frame,
DirectHandle<JSFunction> break_target) { … }
bool Debug::IsBreakOnInstrumentation(Handle<DebugInfo> debug_info,
const BreakLocation& location) { … }
bool Debug::IsBreakOnDebuggerStatement(
DirectHandle<SharedFunctionInfo> function, const BreakLocation& location) { … }
MaybeHandle<FixedArray> Debug::CheckBreakPoints(Handle<DebugInfo> debug_info,
BreakLocation* location,
bool* has_break_points) { … }
bool Debug::IsMutedAtAnyBreakLocation(
DirectHandle<SharedFunctionInfo> function,
const std::vector<BreakLocation>& locations) { … }
#if V8_ENABLE_WEBASSEMBLY
void Debug::SetMutedWasmLocation(DirectHandle<Script> script, int position) { … }
bool Debug::IsMutedAtWasmLocation(Tagged<Script> script, int position) { … }
#endif
namespace {
bool ToHandle(Isolate* isolate, std::optional<Tagged<DebugInfo>> debug_info,
Handle<DebugInfo>* out) { … }
}
bool Debug::CheckBreakPoint(DirectHandle<BreakPoint> break_point,
bool is_break_at_entry) { … }
bool Debug::SetBreakpoint(Handle<SharedFunctionInfo> shared,
DirectHandle<BreakPoint> break_point,
int* source_position) { … }
bool Debug::SetBreakPointForScript(Handle<Script> script,
DirectHandle<String> condition,
int* source_position, int* id) { … }
int Debug::FindBreakablePosition(Handle<DebugInfo> debug_info,
int source_position) { … }
void Debug::ApplyBreakPoints(Handle<DebugInfo> debug_info) { … }
void Debug::ClearBreakPoints(Handle<DebugInfo> debug_info) { … }
void Debug::ClearBreakPoint(DirectHandle<BreakPoint> break_point) { … }
int Debug::GetFunctionDebuggingId(DirectHandle<JSFunction> function) { … }
bool Debug::SetBreakpointForFunction(Handle<SharedFunctionInfo> shared,
DirectHandle<String> condition, int* id,
BreakPointKind kind) { … }
void Debug::RemoveBreakpoint(int id) { … }
#if V8_ENABLE_WEBASSEMBLY
void Debug::SetInstrumentationBreakpointForWasmScript(Handle<Script> script,
int* id) { … }
void Debug::RemoveBreakpointForWasmScript(DirectHandle<Script> script, int id) { … }
void Debug::RecordWasmScriptWithBreakpoints(Handle<Script> script) { … }
#endif
void Debug::ClearAllBreakPoints() { … }
void Debug::FloodWithOneShot(Handle<SharedFunctionInfo> shared,
bool returns_only) { … }
void Debug::ChangeBreakOnException(ExceptionBreakType type, bool enable) { … }
bool Debug::IsBreakOnException(ExceptionBreakType type) { … }
MaybeHandle<FixedArray> Debug::GetHitBreakPoints(
DirectHandle<DebugInfo> debug_info, int position, bool* has_break_points) { … }
void Debug::SetBreakOnNextFunctionCall() { … }
void Debug::ClearBreakOnNextFunctionCall() { … }
void Debug::PrepareStepIn(DirectHandle<JSFunction> function) { … }
void Debug::PrepareStepInSuspendedGenerator() { … }
void Debug::PrepareStepOnThrow() { … }
void Debug::PrepareStep(StepAction step_action) { … }
Handle<Object> Debug::GetSourceBreakLocations(
Isolate* isolate, DirectHandle<SharedFunctionInfo> shared) { … }
void Debug::ClearStepping() { … }
void Debug::ClearOneShot() { … }
void Debug::ClearMutedLocation() { … }
void Debug::SetMutedLocation(DirectHandle<SharedFunctionInfo> function,
const BreakLocation& location) { … }
namespace {
class DiscardBaselineCodeVisitor : public ThreadVisitor { … };
}
void Debug::DiscardBaselineCode(Tagged<SharedFunctionInfo> shared) { … }
void Debug::DiscardAllBaselineCode() { … }
void Debug::DeoptimizeFunction(DirectHandle<SharedFunctionInfo> shared) { … }
void Debug::PrepareFunctionForDebugExecution(
DirectHandle<SharedFunctionInfo> shared) { … }
namespace {
bool IsJSFunctionAndNeedsTrampoline(Isolate* isolate,
Tagged<Object> maybe_function) { … }
}
void Debug::InstallDebugBreakTrampoline() { … }
namespace {
void FindBreakablePositions(Handle<DebugInfo> debug_info, int start_position,
int end_position,
std::vector<BreakLocation>* locations) { … }
bool CompileTopLevel(Isolate* isolate, Handle<Script> script,
MaybeHandle<SharedFunctionInfo>* result = nullptr) { … }
}
bool Debug::GetPossibleBreakpoints(Handle<Script> script, int start_position,
int end_position, bool restrict_to_function,
std::vector<BreakLocation>* locations) { … }
class SharedFunctionInfoFinder { … };
namespace {
Tagged<SharedFunctionInfo> FindSharedFunctionInfoCandidate(
int position, DirectHandle<Script> script, Isolate* isolate) { … }
}
Handle<SharedFunctionInfo> Debug::FindClosestSharedFunctionInfoFromPosition(
int position, Handle<Script> script,
Handle<SharedFunctionInfo> outer_shared) { … }
bool Debug::FindSharedFunctionInfosIntersectingRange(
Handle<Script> script, int start_position, int end_position,
std::vector<Handle<SharedFunctionInfo>>* intersecting_shared) { … }
MaybeHandle<SharedFunctionInfo> Debug::GetTopLevelWithRecompile(
Handle<Script> script, bool* did_compile) { … }
Handle<Object> Debug::FindInnermostContainingFunctionInfo(Handle<Script> script,
int position) { … }
bool Debug::EnsureBreakInfo(Handle<SharedFunctionInfo> shared) { … }
void Debug::CreateBreakInfo(Handle<SharedFunctionInfo> shared) { … }
Handle<DebugInfo> Debug::GetOrCreateDebugInfo(
DirectHandle<SharedFunctionInfo> shared) { … }
void Debug::InstallCoverageInfo(DirectHandle<SharedFunctionInfo> shared,
Handle<CoverageInfo> coverage_info) { … }
void Debug::RemoveAllCoverageInfos() { … }
void Debug::ClearAllDebuggerHints() { … }
void Debug::ClearAllDebugInfos(const DebugInfoClearFunction& clear_function) { … }
void Debug::RemoveBreakInfoAndMaybeFree(DirectHandle<DebugInfo> debug_info) { … }
bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) { … }
Handle<FixedArray> Debug::GetLoadedScripts() { … }
std::optional<Tagged<DebugInfo>> Debug::TryGetDebugInfo(
Tagged<SharedFunctionInfo> sfi) { … }
bool Debug::HasDebugInfo(Tagged<SharedFunctionInfo> sfi) { … }
bool Debug::HasCoverageInfo(Tagged<SharedFunctionInfo> sfi) { … }
bool Debug::HasBreakInfo(Tagged<SharedFunctionInfo> sfi) { … }
bool Debug::BreakAtEntry(Tagged<SharedFunctionInfo> sfi) { … }
std::optional<Tagged<Object>> Debug::OnThrow(Handle<Object> exception) { … }
void Debug::OnPromiseReject(Handle<Object> promise, Handle<Object> value) { … }
bool Debug::IsFrameBlackboxed(JavaScriptFrame* frame) { … }
void Debug::OnException(Handle<Object> exception,
MaybeHandle<JSPromise> promise,
v8::debug::ExceptionType exception_type) { … }
void Debug::OnDebugBreak(Handle<FixedArray> break_points_hit,
StepAction lastStepAction,
v8::debug::BreakReasons break_reasons) { … }
namespace {
debug::Location GetDebugLocation(DirectHandle<Script> script,
int source_position) { … }
}
bool Debug::IsBlackboxed(DirectHandle<SharedFunctionInfo> shared) { … }
bool Debug::ShouldBeSkipped() { … }
bool Debug::AllFramesOnStackAreBlackboxed() { … }
bool Debug::CanBreakAtEntry(DirectHandle<SharedFunctionInfo> shared) { … }
bool Debug::SetScriptSource(Handle<Script> script, Handle<String> source,
bool preview, bool allow_top_frame_live_editing,
debug::LiveEditResult* result) { … }
void Debug::OnCompileError(DirectHandle<Script> script) { … }
void Debug::OnAfterCompile(DirectHandle<Script> script) { … }
void Debug::ProcessCompileEvent(bool has_compile_error,
DirectHandle<Script> script) { … }
int Debug::CurrentFrameCount() { … }
void Debug::SetDebugDelegate(debug::DebugDelegate* delegate) { … }
void Debug::UpdateState() { … }
void Debug::UpdateHookOnFunctionCall() { … }
void Debug::HandleDebugBreak(IgnoreBreakMode ignore_break_mode,
v8::debug::BreakReasons break_reasons) { … }
#ifdef DEBUG
void Debug::PrintBreakLocation() { … }
#endif
DebugScope::DebugScope(Debug* debug)
: … { … }
void DebugScope::set_terminate_on_resume() { … }
base::TimeDelta DebugScope::ElapsedTimeSinceCreation() { … }
DebugScope::~DebugScope() { … }
ReturnValueScope::ReturnValueScope(Debug* debug) : … { … }
ReturnValueScope::~ReturnValueScope() { … }
void Debug::UpdateDebugInfosForExecutionMode() { … }
void Debug::SetTerminateOnResume() { … }
void Debug::StartSideEffectCheckMode() { … }
void Debug::StopSideEffectCheckMode() { … }
void Debug::ApplySideEffectChecks(DirectHandle<DebugInfo> debug_info) { … }
void Debug::ClearSideEffectChecks(DirectHandle<DebugInfo> debug_info) { … }
bool Debug::PerformSideEffectCheck(Handle<JSFunction> function,
Handle<Object> receiver) { … }
Handle<Object> Debug::return_value_handle() { … }
void Debug::PrepareBuiltinForSideEffectCheck(Isolate* isolate, Builtin id) { … }
bool Debug::PerformSideEffectCheckForAccessor(
DirectHandle<AccessorInfo> accessor_info, Handle<Object> receiver,
AccessorComponent component) { … }
void Debug::IgnoreSideEffectsOnNextCallTo(
Handle<FunctionTemplateInfo> function) { … }
bool Debug::PerformSideEffectCheckForCallback(
Handle<FunctionTemplateInfo> function) { … }
bool Debug::PerformSideEffectCheckForInterceptor(
Handle<InterceptorInfo> interceptor_info) { … }
bool Debug::PerformSideEffectCheckAtBytecode(InterpretedFrame* frame) { … }
bool Debug::PerformSideEffectCheckForObject(Handle<Object> object) { … }
void Debug::SetTemporaryObjectTrackingDisabled(bool disabled) { … }
bool Debug::GetTemporaryObjectTrackingDisabled() const { … }
void Debug::PrepareRestartFrame(JavaScriptFrame* frame,
int inlined_frame_index) { … }
void Debug::NotifyDebuggerPausedEventSent() { … }
}
}