Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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 571 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:634

◆ ~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 618 of file debugger.h.

618 {
619 return breakpoint_locations_lock_.get();
620 }

◆ code_breakpoints_lock()

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

Definition at line 614 of file debugger.h.

614 {
615 return code_breakpoints_lock_.get();
616 }

◆ EnsureLocationIsInFunction()

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

Definition at line 2916 of file debugger.cc.

2918 {
2919 const String& url = String::Handle(zone, location->url());
2920 if (!FunctionOverlaps(function, url, location->token_pos(),
2921 location->end_token_pos())) {
2922 return false;
2923 }
2924
2925 TokenPosition token_pos = location->token_pos();
2926#if !defined(DART_PRECOMPILED_RUNTIME)
2927 TokenPosition end_token_pos = location->end_token_pos();
2928 if (token_pos != end_token_pos && location->requested_column_number() >= 0) {
2929 // Narrow down the token position range to a single value
2930 // if requested column number is provided so that inner
2931 // Closure won't be missed.
2932 const Script& script = Script::Handle(location->script());
2933 token_pos = FindExactTokenPosition(script, token_pos,
2934 location->requested_column_number());
2935 }
2936#endif // !defined(DART_PRECOMPILED_RUNTIME)
2937 const Function& inner_function =
2938 Function::Handle(zone, FindInnermostClosure(zone, function, token_pos));
2939 if (!inner_function.IsNull()) {
2940 if (FLAG_verbose_debug) {
2942 "Pending breakpoint remains unresolved in "
2943 "inner function '%s'\n",
2944 inner_function.ToFullyQualifiedCString());
2945 }
2946 return false;
2947 }
2948
2949 // There is no local function within function that contains the
2950 // breakpoint token position.
2951 return true;
2952}
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:3736
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:2891

◆ GetBreakpointLocationFor()

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

Definition at line 3893 of file debugger.cc.

3896 {
3897 ASSERT(pcbpt != nullptr);
3898 SafepointReadRwLocker sl(Thread::Current(), code_breakpoints_lock());
3899 *pcbpt = code_breakpoints_;
3900 while (*pcbpt != nullptr) {
3901 if ((*pcbpt)->pc() == breakpoint_address) {
3902 return (*pcbpt)->FindBreakpointForDebugger(debugger);
3903 }
3904 *pcbpt = (*pcbpt)->next();
3905 }
3906 return nullptr;
3907}
SafepointRwLock * code_breakpoints_lock()
Definition debugger.h:614
static Thread * Current()
Definition thread.h:361

◆ GetCodeBreakpoint()

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

Definition at line 3882 of file debugger.cc.

3882 {
3883 CodeBreakpoint* cbpt = code_breakpoints_;
3884 while (cbpt != nullptr) {
3885 if (cbpt->pc() == breakpoint_address) {
3886 return cbpt;
3887 }
3888 cbpt = cbpt->next();
3889 }
3890 return nullptr;
3891}

◆ GetPatchedStubAddress()

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

Definition at line 3917 of file debugger.cc.

3917 {
3918 SafepointReadRwLocker sl(Thread::Current(), code_breakpoints_lock());
3919 CodeBreakpoint* cbpt = GetCodeBreakpoint(breakpoint_address);
3920 if (cbpt != nullptr) {
3921 return cbpt->OrigStubAddress();
3922 }
3923 UNREACHABLE();
3924 return Code::null();
3925}
#define UNREACHABLE()
Definition assert.h:248
CodeBreakpoint * GetCodeBreakpoint(uword breakpoint_address)
Definition debugger.cc:3882
static ObjectPtr null()
Definition object.h:433

◆ HasActiveBreakpoint()

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

Definition at line 3876 of file debugger.cc.

3876 {
3877 SafepointReadRwLocker sl(Thread::Current(), code_breakpoints_lock());
3878 CodeBreakpoint* cbpt = GetCodeBreakpoint(pc);
3879 return (cbpt != nullptr) && (cbpt->IsEnabled());
3880}

◆ HasBreakpoint()

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

Definition at line 3441 of file debugger.cc.

3441 {
3442 bool hasBreakpoint = false;
3443 // Don't need to worry about the lock if mutators are stopped.
3444 if (thread->IsInStoppedMutatorsScope()) {
3445 hasBreakpoint = HasBreakpointUnsafe(thread, function);
3446 } else {
3447 SafepointReadRwLocker sl(thread, breakpoint_locations_lock());
3448 hasBreakpoint = HasBreakpointUnsafe(thread, function);
3449 }
3450 if (hasBreakpoint) {
3451 return true;
3452 }
3453
3454 // TODO(aam): do we have to iterate over both code breakpoints and
3455 // breakpoint locations? Wouldn't be sufficient to iterate over only
3456 // one list? Could you have a CodeBreakpoint without corresponding
3457 // BreakpointLocation?
3459 return true;
3460 }
3461
3462 return false;
3463}
bool HasCodeBreakpointInFunction(const Function &func)
Definition debugger.cc:427
bool HasBreakpointUnsafe(Thread *thread, const Function &function)
Definition debugger.cc:3424
SafepointRwLock * breakpoint_locations_lock()
Definition debugger.h:618

◆ 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 3424 of file debugger.cc.

3425 {
3426 DEBUG_ASSERT(thread->IsInStoppedMutatorsScope() ||
3427 breakpoint_locations_lock()->IsCurrentThreadReader());
3428 // Check if function has any breakpoints.
3429 String& url = String::Handle(thread->zone());
3430 for (intptr_t i = 0; i < breakpoint_locations_.length(); i++) {
3431 BreakpointLocation* location = breakpoint_locations_.At(i);
3432 url = location->url();
3433 if (FunctionOverlaps(function, url, location->token_pos(),
3434 location->end_token_pos())) {
3435 return true;
3436 }
3437 }
3438 return false;
3439}
#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 3465 of file debugger.cc.

3465 {
3466 {
3467 ReadRwLocker ml(thread, single_stepping_set_lock());
3468 if (!single_stepping_set_.IsEmpty()) {
3469 return true;
3470 }
3471 }
3472 return HasBreakpoint(thread, function);
3473}
RwLock * single_stepping_set_lock()
Definition debugger.h:622
bool HasBreakpoint(Thread *thread, const Function &function)
Definition debugger.cc:3441

◆ isolate_group()

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

Definition at line 634 of file debugger.h.

634{ 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 2954 of file debugger.cc.

2954 {
2955 if (!function.is_debuggable()) {
2956 return;
2957 }
2958 Function& resolved_function = Function::Handle(function.ptr());
2959 auto thread = Thread::Current();
2960 auto zone = thread->zone();
2961
2962 // Going through BreakpointLocations of all isolates and debuggers looking
2963 // for those that can be resolved and added code breakpoints at now.
2964 //
2965 // The check below is used instead of breakpoint_locations_lock acquisition.
2966 // We don't need to acquire the lock if always run with stopped mutators.
2967 // We can't acquire the lock if we run with stopped mutators as that could
2968 // result in deadlock.
2969 RELEASE_ASSERT(thread->IsInStoppedMutatorsScope());
2970 for (intptr_t i = 0; i < breakpoint_locations_.length(); i++) {
2971 BreakpointLocation* location = breakpoint_locations_.At(i);
2972 if (EnsureLocationIsInFunction(zone, resolved_function, location)) {
2973 // All mutators are stopped (see RELEASE_ASSERT above). We temporarily
2974 // enter the isolate for which the breakpoint was registered.
2975 // The code path below may issue service events which will use the active
2976 // isolate's object-id ring for naming VM objects.
2977 ActiveIsolateScope active_isolate(thread,
2978 location->debugger()->isolate());
2979
2980 // Ensure the location is resolved for the original function.
2981 TokenPosition exact_token_pos = TokenPosition::kNoSource;
2982#if !defined(DART_PRECOMPILED_RUNTIME)
2983 if (location->token_pos() != location->end_token_pos() &&
2984 location->requested_column_number() >= 0) {
2985 exact_token_pos = FindExactTokenPosition(
2986 Script::Handle(location->script()), location->token_pos(),
2987 location->requested_column_number());
2988 }
2989#endif // !defined(DART_PRECOMPILED_RUNTIME)
2990 location->EnsureIsResolved(function, exact_token_pos);
2991 if (FLAG_verbose_debug) {
2992 Breakpoint* bpt = location->breakpoints();
2993 while (bpt != nullptr) {
2994 OS::PrintErr("Setting breakpoint %" Pd " for %s '%s'\n", bpt->id(),
2995 function.IsClosureFunction() ? "closure" : "function",
2996 function.ToFullyQualifiedCString());
2997 bpt = bpt->next();
2998 }
2999 }
3000 MakeCodeBreakpointAt(function, location);
3001 }
3002 }
3003}
#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:2916
#define Pd
Definition globals.h:408

◆ Pause()

void dart::GroupDebugger::Pause ( )

Definition at line 3072 of file debugger.cc.

3072 {
3073 SafepointWriteRwLocker sl(Thread::Current(), code_breakpoints_lock());
3074 if (needs_breakpoint_cleanup_) {
3075 RemoveUnlinkedCodeBreakpoints();
3076 }
3077}

◆ RegisterBreakpointLocation()

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

Definition at line 4020 of file debugger.cc.

4020 {
4021 DEBUG_ASSERT(breakpoint_locations_lock()->IsCurrentThreadWriter() ||
4022 Thread::Current()->IsInStoppedMutatorsScope());
4023 breakpoint_locations_.Add(location);
4024}

◆ RegisterSingleSteppingDebugger()

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

Definition at line 3412 of file debugger.cc.

3413 {
3414 WriteRwLocker sl(Thread::Current(), single_stepping_set_lock());
3415 single_stepping_set_.Insert(debugger);
3416}
void Insert(const Key &key)
Definition debugger.h:539

◆ RemoveBreakpointLocation()

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

◆ single_stepping_set_lock()

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

Definition at line 622 of file debugger.h.

622{ return single_stepping_set_lock_.get(); }

◆ SyncBreakpointLocation()

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

Definition at line 2683 of file debugger.cc.

2683 {
2684 bool any_enabled = loc->AnyEnabled();
2685 SafepointWriteRwLocker sl(Thread::Current(), code_breakpoints_lock());
2686 CodeBreakpoint* cbpt = code_breakpoints_;
2687 while (cbpt != nullptr) {
2688 if (cbpt->HasBreakpointLocation(loc)) {
2689 if (any_enabled) {
2690 cbpt->Enable();
2691 } else {
2692 cbpt->Disable();
2693 }
2694 }
2695 cbpt = cbpt->next();
2696 }
2697}

◆ UnlinkCodeBreakpoints()

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

Definition at line 4040 of file debugger.cc.

4040 {
4041 ASSERT(bpt_location != nullptr);
4042 SafepointWriteRwLocker sl(Thread::Current(), code_breakpoints_lock());
4043 CodeBreakpoint* curr_bpt = code_breakpoints_;
4044 while (curr_bpt != nullptr) {
4045 if (curr_bpt->FindAndDeleteBreakpointLocation(bpt_location)) {
4046 curr_bpt->Disable();
4047 needs_breakpoint_cleanup_ = true;
4048 }
4049 curr_bpt = curr_bpt->next();
4050 }
4051}

◆ UnregisterBreakpointLocation()

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

Definition at line 4026 of file debugger.cc.

4026 {
4027 ASSERT(breakpoint_locations_lock()->IsCurrentThreadWriter());
4028 for (intptr_t i = 0; i < breakpoint_locations_.length(); i++) {
4029 if (breakpoint_locations_.At(i) == location) {
4030 breakpoint_locations_.EraseAt(i);
4031 return;
4032 }
4033 }
4034}

◆ UnregisterSingleSteppingDebugger()

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

Definition at line 3418 of file debugger.cc.

3419 {
3420 WriteRwLocker sl(Thread::Current(), single_stepping_set_lock());
3421 single_stepping_set_.Remove(debugger);
3422}
void Remove(const Key &key)
Definition debugger.h:544

◆ VisitObjectPointers()

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

Definition at line 3005 of file debugger.cc.

3005 {
3006 CodeBreakpoint* cbpt = code_breakpoints_;
3007 while (cbpt != nullptr) {
3008 cbpt->VisitObjectPointers(visitor);
3009 cbpt = cbpt->next();
3010 }
3011}

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