Flutter Engine
The Flutter Engine
Public Member Functions | List of all members
dart::GroupDebugger Class Reference

#include <debugger.h>

Public Member Functions

 GroupDebugger (IsolateGroup *isolate_group)
 
 ~GroupDebugger ()
 
void MakeCodeBreakpointAtUnsafe (const Function &func, BreakpointLocation *bpt)
 
void MakeCodeBreakpointAt (const Function &func, BreakpointLocation *bpt)
 
CodeBreakpointGetCodeBreakpoint (uword breakpoint_address)
 
BreakpointLocationGetBreakpointLocationFor (Debugger *debugger, uword breakpoint_address, CodeBreakpoint **pcbpt)
 
CodePtr GetPatchedStubAddress (uword breakpoint_address)
 
void RegisterBreakpointLocation (BreakpointLocation *location)
 
void UnregisterBreakpointLocation (BreakpointLocation *location)
 
void RemoveBreakpointLocation (BreakpointLocation *bpt_location)
 
void UnlinkCodeBreakpoints (BreakpointLocation *bpt_location)
 
bool HasActiveBreakpoint (uword pc)
 
bool HasCodeBreakpointInFunctionUnsafe (const Function &func)
 
bool HasCodeBreakpointInFunction (const Function &func)
 
bool HasCodeBreakpointInCode (const Code &code)
 
bool HasBreakpointInFunction (const Function &func)
 
bool HasBreakpointInCode (const Code &code)
 
void SyncBreakpointLocation (BreakpointLocation *loc)
 
void Pause ()
 
bool EnsureLocationIsInFunction (Zone *zone, const Function &function, BreakpointLocation *location)
 
void NotifyCompilation (const Function &func)
 
void VisitObjectPointers (ObjectPointerVisitor *visitor)
 
SafepointRwLockcode_breakpoints_lock ()
 
SafepointRwLockbreakpoint_locations_lock ()
 
RwLocksingle_stepping_set_lock ()
 
void RegisterSingleSteppingDebugger (Thread *thread, const Debugger *debugger)
 
void UnregisterSingleSteppingDebugger (Thread *thread, const Debugger *debugger)
 
bool HasBreakpointUnsafe (Thread *thread, const Function &function)
 
bool HasBreakpoint (Thread *thread, const Function &function)
 
bool IsDebugging (Thread *thread, const Function &function)
 
IsolateGroupisolate_group ()
 

Detailed Description

Definition at line 573 of file debugger.h.

Constructor & Destructor Documentation

◆ GroupDebugger()

dart::GroupDebugger::GroupDebugger ( IsolateGroup isolate_group)
explicit

Definition at line 1391 of file debugger.cc.

1392 : isolate_group_(isolate_group),
1393 code_breakpoints_lock_(new SafepointRwLock()),
1394 code_breakpoints_(nullptr),
1395 breakpoint_locations_lock_(new SafepointRwLock()),
1396 single_stepping_set_lock_(new RwLock()),
1397 needs_breakpoint_cleanup_(false) {}
IsolateGroup * isolate_group()
Definition: debugger.h:636

◆ ~GroupDebugger()

dart::GroupDebugger::~GroupDebugger ( )

Definition at line 1399 of file debugger.cc.

1399 {
1400 while (code_breakpoints_ != nullptr) {
1401 CodeBreakpoint* cbpt = code_breakpoints_;
1402 code_breakpoints_ = code_breakpoints_->next();
1403 ASSERT(!cbpt->IsEnabled());
1404 delete cbpt;
1405 }
1406}
#define ASSERT(E)

Member Function Documentation

◆ breakpoint_locations_lock()

SafepointRwLock * dart::GroupDebugger::breakpoint_locations_lock ( )
inline

Definition at line 620 of file debugger.h.

620 {
621 return breakpoint_locations_lock_.get();
622 }

◆ code_breakpoints_lock()

SafepointRwLock * dart::GroupDebugger::code_breakpoints_lock ( )
inline

Definition at line 616 of file debugger.h.

616 {
617 return code_breakpoints_lock_.get();
618 }

◆ EnsureLocationIsInFunction()

bool dart::GroupDebugger::EnsureLocationIsInFunction ( Zone zone,
const Function function,
BreakpointLocation location 
)

Definition at line 2939 of file debugger.cc.

2941 {
2942 const String& url = String::Handle(zone, location->url());
2943 if (!FunctionOverlaps(function, url, location->token_pos(),
2944 location->end_token_pos())) {
2945 return false;
2946 }
2947
2948 TokenPosition token_pos = location->token_pos();
2949#if !defined(DART_PRECOMPILED_RUNTIME)
2950 TokenPosition end_token_pos = location->end_token_pos();
2951 if (token_pos != end_token_pos && location->requested_column_number() >= 0) {
2952 // Narrow down the token position range to a single value
2953 // if requested column number is provided so that inner
2954 // Closure won't be missed.
2955 const Script& script = Script::Handle(location->script());
2956 token_pos = FindExactTokenPosition(script, token_pos,
2957 location->requested_column_number());
2958 }
2959#endif // !defined(DART_PRECOMPILED_RUNTIME)
2960 const Function& inner_function =
2961 Function::Handle(zone, FindInnermostClosure(zone, function, token_pos));
2962 if (!inner_function.IsNull()) {
2963 if (FLAG_verbose_debug) {
2965 "Pending breakpoint remains unresolved in "
2966 "inner function '%s'\n",
2967 inner_function.ToFullyQualifiedCString());
2968 }
2969 return false;
2970 }
2971
2972 // There is no local function within function that contains the
2973 // breakpoint token position.
2974 return true;
2975}
static void static void PrintErr(const char *format,...) PRINTF_ATTRIBUTE(1
static Object & Handle()
Definition: object.h:407
Dart_NativeFunction function
Definition: fuchsia.cc:51
static TokenPosition FindExactTokenPosition(const Script &script, TokenPosition start_of_line, intptr_t column_number)
Definition: debugger.cc:3759
static bool FunctionOverlaps(const Function &func, const String &script_url, TokenPosition token_pos, TokenPosition end_token_pos)
Definition: debugger.cc:378
static FunctionPtr FindInnermostClosure(Zone *zone, const Function &function, TokenPosition token_pos)
Definition: debugger.cc:2914

◆ GetBreakpointLocationFor()

BreakpointLocation * dart::GroupDebugger::GetBreakpointLocationFor ( Debugger debugger,
uword  breakpoint_address,
CodeBreakpoint **  pcbpt 
)

Definition at line 3916 of file debugger.cc.

3919 {
3920 ASSERT(pcbpt != nullptr);
3921 SafepointReadRwLocker sl(Thread::Current(), code_breakpoints_lock());
3922 *pcbpt = code_breakpoints_;
3923 while (*pcbpt != nullptr) {
3924 if ((*pcbpt)->pc() == breakpoint_address) {
3925 return (*pcbpt)->FindBreakpointForDebugger(debugger);
3926 }
3927 *pcbpt = (*pcbpt)->next();
3928 }
3929 return nullptr;
3930}
SafepointRwLock * code_breakpoints_lock()
Definition: debugger.h:616
static Thread * Current()
Definition: thread.h:362

◆ GetCodeBreakpoint()

CodeBreakpoint * dart::GroupDebugger::GetCodeBreakpoint ( uword  breakpoint_address)

Definition at line 3905 of file debugger.cc.

3905 {
3906 CodeBreakpoint* cbpt = code_breakpoints_;
3907 while (cbpt != nullptr) {
3908 if (cbpt->pc() == breakpoint_address) {
3909 return cbpt;
3910 }
3911 cbpt = cbpt->next();
3912 }
3913 return nullptr;
3914}

◆ GetPatchedStubAddress()

CodePtr dart::GroupDebugger::GetPatchedStubAddress ( uword  breakpoint_address)

Definition at line 3940 of file debugger.cc.

3940 {
3941 SafepointReadRwLocker sl(Thread::Current(), code_breakpoints_lock());
3942 CodeBreakpoint* cbpt = GetCodeBreakpoint(breakpoint_address);
3943 if (cbpt != nullptr) {
3944 return cbpt->OrigStubAddress();
3945 }
3946 UNREACHABLE();
3947 return Code::null();
3948}
#define UNREACHABLE()
Definition: assert.h:248
CodeBreakpoint * GetCodeBreakpoint(uword breakpoint_address)
Definition: debugger.cc:3905
static ObjectPtr null()
Definition: object.h:433

◆ HasActiveBreakpoint()

bool dart::GroupDebugger::HasActiveBreakpoint ( uword  pc)

Definition at line 3899 of file debugger.cc.

3899 {
3900 SafepointReadRwLocker sl(Thread::Current(), code_breakpoints_lock());
3901 CodeBreakpoint* cbpt = GetCodeBreakpoint(pc);
3902 return (cbpt != nullptr) && (cbpt->IsEnabled());
3903}

◆ HasBreakpoint()

bool dart::GroupDebugger::HasBreakpoint ( Thread thread,
const Function function 
)

Definition at line 3464 of file debugger.cc.

3464 {
3465 bool hasBreakpoint = false;
3466 // Don't need to worry about the lock if mutators are stopped.
3467 if (thread->IsInStoppedMutatorsScope()) {
3468 hasBreakpoint = HasBreakpointUnsafe(thread, function);
3469 } else {
3470 SafepointReadRwLocker sl(thread, breakpoint_locations_lock());
3471 hasBreakpoint = HasBreakpointUnsafe(thread, function);
3472 }
3473 if (hasBreakpoint) {
3474 return true;
3475 }
3476
3477 // TODO(aam): do we have to iterate over both code breakpoints and
3478 // breakpoint locations? Wouldn't be sufficient to iterate over only
3479 // one list? Could you have a CodeBreakpoint without corresponding
3480 // BreakpointLocation?
3482 return true;
3483 }
3484
3485 return false;
3486}
bool HasCodeBreakpointInFunction(const Function &func)
Definition: debugger.cc:427
bool HasBreakpointUnsafe(Thread *thread, const Function &function)
Definition: debugger.cc:3447
SafepointRwLock * breakpoint_locations_lock()
Definition: debugger.h:620

◆ HasBreakpointInCode()

bool dart::GroupDebugger::HasBreakpointInCode ( const Code code)

Definition at line 438 of file debugger.cc.

438 {
439 auto thread = Thread::Current();
440 SafepointReadRwLocker sl(thread, code_breakpoints_lock());
441 CodeBreakpoint* cbpt = code_breakpoints_;
442 while (cbpt != nullptr) {
443 if (code.ptr() == cbpt->code_) {
444 return true;
445 }
446 cbpt = cbpt->next_;
447 }
448 return false;
449}

◆ HasBreakpointInFunction()

bool dart::GroupDebugger::HasBreakpointInFunction ( const Function func)

◆ HasBreakpointUnsafe()

bool dart::GroupDebugger::HasBreakpointUnsafe ( Thread thread,
const Function function 
)

Definition at line 3447 of file debugger.cc.

3448 {
3449 DEBUG_ASSERT(thread->IsInStoppedMutatorsScope() ||
3450 breakpoint_locations_lock()->IsCurrentThreadReader());
3451 // Check if function has any breakpoints.
3452 String& url = String::Handle(thread->zone());
3453 for (intptr_t i = 0; i < breakpoint_locations_.length(); i++) {
3454 BreakpointLocation* location = breakpoint_locations_.At(i);
3455 url = location->url();
3456 if (FunctionOverlaps(function, url, location->token_pos(),
3457 location->end_token_pos())) {
3458 return true;
3459 }
3460 }
3461 return false;
3462}
#define DEBUG_ASSERT(cond)
Definition: assert.h:321

◆ HasCodeBreakpointInCode()

bool dart::GroupDebugger::HasCodeBreakpointInCode ( const Code code)

◆ HasCodeBreakpointInFunction()

bool dart::GroupDebugger::HasCodeBreakpointInFunction ( const Function func)

Definition at line 427 of file debugger.cc.

427 {
428 auto thread = Thread::Current();
429 // Don't need to worry about the lock if mutators are stopped.
430 if (thread->IsInStoppedMutatorsScope()) {
432 } else {
433 SafepointReadRwLocker sl(thread, code_breakpoints_lock());
435 }
436}
bool HasCodeBreakpointInFunctionUnsafe(const Function &func)
Definition: debugger.cc:414

◆ HasCodeBreakpointInFunctionUnsafe()

bool dart::GroupDebugger::HasCodeBreakpointInFunctionUnsafe ( const Function func)

Definition at line 414 of file debugger.cc.

414 {
415 DEBUG_ASSERT(code_breakpoints_lock()->IsCurrentThreadReader() ||
416 Thread::Current()->IsInStoppedMutatorsScope());
417 CodeBreakpoint* cbpt = code_breakpoints_;
418 while (cbpt != nullptr) {
419 if (func.ptr() == cbpt->function()) {
420 return true;
421 }
422 cbpt = cbpt->next_;
423 }
424 return false;
425}

◆ IsDebugging()

bool dart::GroupDebugger::IsDebugging ( Thread thread,
const Function function 
)

Definition at line 3488 of file debugger.cc.

3488 {
3489 {
3490 ReadRwLocker ml(thread, single_stepping_set_lock());
3491 if (!single_stepping_set_.IsEmpty()) {
3492 return true;
3493 }
3494 }
3495 return HasBreakpoint(thread, function);
3496}
RwLock * single_stepping_set_lock()
Definition: debugger.h:624
bool HasBreakpoint(Thread *thread, const Function &function)
Definition: debugger.cc:3464

◆ isolate_group()

IsolateGroup * dart::GroupDebugger::isolate_group ( )
inline

Definition at line 636 of file debugger.h.

636{ return isolate_group_; }

◆ MakeCodeBreakpointAt()

void dart::GroupDebugger::MakeCodeBreakpointAt ( const Function func,
BreakpointLocation bpt 
)

Definition at line 2269 of file debugger.cc.

2270 {
2271 auto thread = Thread::Current();
2272 if (thread->IsInStoppedMutatorsScope()) {
2273 MakeCodeBreakpointAtUnsafe(func, loc);
2274 } else {
2275 SafepointWriteRwLocker sl(thread, code_breakpoints_lock());
2276 MakeCodeBreakpointAtUnsafe(func, loc);
2277 }
2278}
void MakeCodeBreakpointAtUnsafe(const Function &func, BreakpointLocation *bpt)
Definition: debugger.cc:2211

◆ MakeCodeBreakpointAtUnsafe()

void dart::GroupDebugger::MakeCodeBreakpointAtUnsafe ( const Function func,
BreakpointLocation bpt 
)

Definition at line 2211 of file debugger.cc.

2212 {
2213 DEBUG_ASSERT(Thread::Current()->IsInStoppedMutatorsScope() ||
2214 code_breakpoints_lock()->IsCurrentThreadWriter());
2215
2216 ASSERT(loc->token_pos().IsReal());
2217 ASSERT((loc != nullptr) && loc->IsResolved());
2218 ASSERT(!func.HasOptimizedCode());
2219 ASSERT(func.HasCode());
2220 Code& code = Code::Handle(func.unoptimized_code());
2221 ASSERT(!code.IsNull());
2222 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors());
2223 uword lowest_pc_offset = kUwordMax;
2224 UntaggedPcDescriptors::Kind lowest_kind = UntaggedPcDescriptors::kAnyKind;
2225 // Find the safe point with the lowest compiled code address
2226 // that maps to the token position of the source breakpoint.
2227 PcDescriptors::Iterator iter(desc, kSafepointKind);
2228 while (iter.MoveNext()) {
2229 if (iter.TokenPos() == loc->token_pos_) {
2230 if (iter.PcOffset() < lowest_pc_offset) {
2231 lowest_pc_offset = iter.PcOffset();
2232 lowest_kind = iter.Kind();
2233 }
2234 }
2235 }
2236 if (lowest_pc_offset == kUwordMax) {
2237 return;
2238 }
2239
2240 uword lowest_pc = code.PayloadStart() + lowest_pc_offset;
2241 CodeBreakpoint* code_bpt = GetCodeBreakpoint(lowest_pc);
2242 if (code_bpt == nullptr) {
2243 // No code breakpoint for this code exists; create one.
2244 code_bpt = new CodeBreakpoint(code, loc, lowest_pc, lowest_kind);
2245 if (FLAG_verbose_debug) {
2246 OS::PrintErr("Setting code breakpoint at pos %s pc %#" Px " offset %#" Px
2247 "\n",
2248 loc->token_pos().ToCString(), lowest_pc,
2249 lowest_pc - code.PayloadStart());
2250 }
2251 RegisterCodeBreakpoint(code_bpt);
2252 } else {
2253 if (FLAG_verbose_debug) {
2255 "Adding location to existing code breakpoint at pos %s pc %#" Px
2256 " offset %#" Px "\n",
2257 loc->token_pos().ToCString(), lowest_pc,
2258 lowest_pc - code.PayloadStart());
2259 }
2260 if (!code_bpt->HasBreakpointLocation(loc)) {
2261 code_bpt->AddBreakpointLocation(loc);
2262 }
2263 }
2264 if (loc->AnyEnabled()) {
2265 code_bpt->Enable();
2266 }
2267}
constexpr uword kUwordMax
Definition: globals.h:519
uintptr_t uword
Definition: globals.h:501
const uint8_t kSafepointKind
Definition: debugger.cc:1313
#define Px
Definition: globals.h:410

◆ NotifyCompilation()

void dart::GroupDebugger::NotifyCompilation ( const Function func)

Definition at line 2977 of file debugger.cc.

2977 {
2978 if (!function.is_debuggable()) {
2979 return;
2980 }
2981 Function& resolved_function = Function::Handle(function.ptr());
2982 auto thread = Thread::Current();
2983 auto zone = thread->zone();
2984
2985 // Going through BreakpointLocations of all isolates and debuggers looking
2986 // for those that can be resolved and added code breakpoints at now.
2987 //
2988 // The check below is used instead of breakpoint_locations_lock acquisition.
2989 // We don't need to acquire the lock if always run with stopped mutators.
2990 // We can't acquire the lock if we run with stopped mutators as that could
2991 // result in deadlock.
2992 RELEASE_ASSERT(thread->IsInStoppedMutatorsScope());
2993 for (intptr_t i = 0; i < breakpoint_locations_.length(); i++) {
2994 BreakpointLocation* location = breakpoint_locations_.At(i);
2995 if (EnsureLocationIsInFunction(zone, resolved_function, location)) {
2996 // All mutators are stopped (see RELEASE_ASSERT above). We temporarily
2997 // enter the isolate for which the breakpoint was registered.
2998 // The code path below may issue service events which will use the active
2999 // isolate's object-id ring for naming VM objects.
3000 ActiveIsolateScope active_isolate(thread,
3001 location->debugger()->isolate());
3002
3003 // Ensure the location is resolved for the original function.
3004 TokenPosition exact_token_pos = TokenPosition::kNoSource;
3005#if !defined(DART_PRECOMPILED_RUNTIME)
3006 if (location->token_pos() != location->end_token_pos() &&
3007 location->requested_column_number() >= 0) {
3008 exact_token_pos = FindExactTokenPosition(
3009 Script::Handle(location->script()), location->token_pos(),
3010 location->requested_column_number());
3011 }
3012#endif // !defined(DART_PRECOMPILED_RUNTIME)
3013 location->EnsureIsResolved(function, exact_token_pos);
3014 if (FLAG_verbose_debug) {
3015 Breakpoint* bpt = location->breakpoints();
3016 while (bpt != nullptr) {
3017 OS::PrintErr("Setting breakpoint %" Pd " for %s '%s'\n", bpt->id(),
3018 function.IsClosureFunction() ? "closure" : "function",
3019 function.ToFullyQualifiedCString());
3020 bpt = bpt->next();
3021 }
3022 }
3023 MakeCodeBreakpointAt(function, location);
3024 }
3025 }
3026}
#define RELEASE_ASSERT(cond)
Definition: assert.h:327
void MakeCodeBreakpointAt(const Function &func, BreakpointLocation *bpt)
Definition: debugger.cc:2269
bool EnsureLocationIsInFunction(Zone *zone, const Function &function, BreakpointLocation *location)
Definition: debugger.cc:2939
#define Pd
Definition: globals.h:408

◆ Pause()

void dart::GroupDebugger::Pause ( )

Definition at line 3095 of file debugger.cc.

3095 {
3096 SafepointWriteRwLocker sl(Thread::Current(), code_breakpoints_lock());
3097 if (needs_breakpoint_cleanup_) {
3098 RemoveUnlinkedCodeBreakpoints();
3099 }
3100}

◆ RegisterBreakpointLocation()

void dart::GroupDebugger::RegisterBreakpointLocation ( BreakpointLocation location)

Definition at line 4043 of file debugger.cc.

4043 {
4044 DEBUG_ASSERT(breakpoint_locations_lock()->IsCurrentThreadWriter() ||
4045 Thread::Current()->IsInStoppedMutatorsScope());
4046 breakpoint_locations_.Add(location);
4047}

◆ RegisterSingleSteppingDebugger()

void dart::GroupDebugger::RegisterSingleSteppingDebugger ( Thread thread,
const Debugger debugger 
)

Definition at line 3435 of file debugger.cc.

3436 {
3437 WriteRwLocker sl(Thread::Current(), single_stepping_set_lock());
3438 single_stepping_set_.Insert(debugger);
3439}
void Insert(const Key &key)
Definition: debugger.h:541

◆ RemoveBreakpointLocation()

void dart::GroupDebugger::RemoveBreakpointLocation ( BreakpointLocation bpt_location)

◆ single_stepping_set_lock()

RwLock * dart::GroupDebugger::single_stepping_set_lock ( )
inline

Definition at line 624 of file debugger.h.

624{ return single_stepping_set_lock_.get(); }

◆ SyncBreakpointLocation()

void dart::GroupDebugger::SyncBreakpointLocation ( BreakpointLocation loc)

Definition at line 2706 of file debugger.cc.

2706 {
2707 bool any_enabled = loc->AnyEnabled();
2708 SafepointWriteRwLocker sl(Thread::Current(), code_breakpoints_lock());
2709 CodeBreakpoint* cbpt = code_breakpoints_;
2710 while (cbpt != nullptr) {
2711 if (cbpt->HasBreakpointLocation(loc)) {
2712 if (any_enabled) {
2713 cbpt->Enable();
2714 } else {
2715 cbpt->Disable();
2716 }
2717 }
2718 cbpt = cbpt->next();
2719 }
2720}

◆ UnlinkCodeBreakpoints()

void dart::GroupDebugger::UnlinkCodeBreakpoints ( BreakpointLocation bpt_location)

Definition at line 4063 of file debugger.cc.

4063 {
4064 ASSERT(bpt_location != nullptr);
4065 SafepointWriteRwLocker sl(Thread::Current(), code_breakpoints_lock());
4066 CodeBreakpoint* curr_bpt = code_breakpoints_;
4067 while (curr_bpt != nullptr) {
4068 if (curr_bpt->FindAndDeleteBreakpointLocation(bpt_location)) {
4069 curr_bpt->Disable();
4070 needs_breakpoint_cleanup_ = true;
4071 }
4072 curr_bpt = curr_bpt->next();
4073 }
4074}

◆ UnregisterBreakpointLocation()

void dart::GroupDebugger::UnregisterBreakpointLocation ( BreakpointLocation location)

Definition at line 4049 of file debugger.cc.

4049 {
4050 ASSERT(breakpoint_locations_lock()->IsCurrentThreadWriter());
4051 for (intptr_t i = 0; i < breakpoint_locations_.length(); i++) {
4052 if (breakpoint_locations_.At(i) == location) {
4053 breakpoint_locations_.EraseAt(i);
4054 return;
4055 }
4056 }
4057}

◆ UnregisterSingleSteppingDebugger()

void dart::GroupDebugger::UnregisterSingleSteppingDebugger ( Thread thread,
const Debugger debugger 
)

Definition at line 3441 of file debugger.cc.

3442 {
3443 WriteRwLocker sl(Thread::Current(), single_stepping_set_lock());
3444 single_stepping_set_.Remove(debugger);
3445}
void Remove(const Key &key)
Definition: debugger.h:546

◆ VisitObjectPointers()

void dart::GroupDebugger::VisitObjectPointers ( ObjectPointerVisitor visitor)

Definition at line 3028 of file debugger.cc.

3028 {
3029 CodeBreakpoint* cbpt = code_breakpoints_;
3030 while (cbpt != nullptr) {
3031 cbpt->VisitObjectPointers(visitor);
3032 cbpt = cbpt->next();
3033 }
3034}

The documentation for this class was generated from the following files: