Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Public Types | Public Member Functions | Static Public Member Functions | Friends | List of all members
dart::Debugger Class Reference

#include <debugger.h>

Public Types

enum  ResumeAction {
  kContinue , kStepInto , kStepOver , kStepOut ,
  kStepRewind , kStepOverAsyncSuspension
}
 

Public Member Functions

 Debugger (Isolate *isolate)
 
 ~Debugger ()
 
Isolateisolate () const
 
void NotifyIsolateCreated ()
 
void Shutdown ()
 
void NotifyDoneLoading ()
 
BreakpointSetBreakpointAtEntry (const Function &target_function, bool single_shot)
 
BreakpointSetBreakpointAtActivation (const Instance &closure, bool single_shot)
 
BreakpointBreakpointAtActivation (const Instance &closure)
 
BreakpointSetBreakpointAtLine (const String &script_url, intptr_t line_number)
 
BreakpointSetBreakpointAtLineCol (const String &script_url, intptr_t line_number, intptr_t column_number)
 
BreakpointLocationBreakpointLocationAtLineCol (const String &script_url, intptr_t line_number, intptr_t column_number)
 
bool SetBreakpointState (Breakpoint *bpt, bool enable)
 
void RemoveBreakpoint (intptr_t bp_id)
 
BreakpointGetBreakpointById (intptr_t id)
 
void AsyncStepInto (const Closure &awaiter)
 
void Continue ()
 
bool SetResumeAction (ResumeAction action, intptr_t frame_index=1, const char **error=nullptr)
 
bool IsStepping () const
 
bool IsSingleStepping () const
 
bool IsPaused () const
 
bool ignore_breakpoints () const
 
void set_ignore_breakpoints (bool ignore_breakpoints)
 
void EnterSingleStepMode ()
 
const ServiceEventPauseEvent () const
 
void SetExceptionPauseInfo (Dart_ExceptionPauseInfo pause_info)
 
Dart_ExceptionPauseInfo GetExceptionPauseInfo () const
 
void VisitObjectPointers (ObjectPointerVisitor *visitor)
 
DebuggerStackTraceStackTrace ()
 
DebuggerStackTraceAsyncAwaiterStackTrace ()
 
ErrorPtr PauseBreakpoint ()
 
ErrorPtr PauseStepping ()
 
ErrorPtr PauseInterrupted ()
 
ErrorPtr PausePostRequest ()
 
void PauseException (const Instance &exc)
 
void PauseDeveloper (const String &msg)
 
void PrintBreakpointsToJSONArray (JSONArray *jsarr) const
 
void PrintSettingsToJSONObject (JSONObject *jsobj) const
 
intptr_t limitBreakpointId ()
 
void RewindPostDeopt ()
 
void SetBreakpointAtResumption (const Object &function_data)
 
void ResumptionBreakpoint ()
 

Static Public Member Functions

static bool IsDebuggable (const Function &func)
 

Friends

class Isolate
 
class BreakpointLocation
 

Detailed Description

Definition at line 657 of file debugger.h.

Member Enumeration Documentation

◆ ResumeAction

Enumerator
kContinue 
kStepInto 
kStepOver 
kStepOut 
kStepRewind 
kStepOverAsyncSuspension 

Definition at line 659 of file debugger.h.

Constructor & Destructor Documentation

◆ Debugger()

dart::Debugger::Debugger ( Isolate isolate)
explicit

Definition at line 1408 of file debugger.cc.

1409 : isolate_(isolate),
1410 next_id_(1),
1411 latent_locations_(nullptr),
1412 breakpoint_locations_(nullptr),
1413 resume_action_(kContinue),
1414 resume_frame_index_(-1),
1415 post_deopt_frame_index_(-1),
1416 ignore_breakpoints_(false),
1417 pause_event_(nullptr),
1418 stack_trace_(nullptr),
1419 async_awaiter_stack_trace_(nullptr),
1420 stepping_fp_(0),
1421 last_stepping_fp_(0),
1422 last_stepping_pos_(TokenPosition::kNoSource),
1423 skip_next_step_(false),
1424 exc_pause_info_(kNoPauseOnExceptions) {}
Isolate * isolate() const
Definition debugger.h:671
@ kNoPauseOnExceptions
Definition debugger.h:503

◆ ~Debugger()

dart::Debugger::~Debugger ( )

Definition at line 1426 of file debugger.cc.

1426 {
1427 ASSERT(!IsPaused());
1428 ASSERT(latent_locations_ == nullptr);
1429 ASSERT(breakpoint_locations_ == nullptr);
1430 ASSERT(stack_trace_ == nullptr);
1431 ASSERT(async_awaiter_stack_trace_ == nullptr);
1432}
bool IsPaused() const
Definition debugger.h:714
#define ASSERT(E)

Member Function Documentation

◆ AsyncAwaiterStackTrace()

DebuggerStackTrace * dart::Debugger::AsyncAwaiterStackTrace ( )

Definition at line 1802 of file debugger.cc.

1802 {
1803 return (async_awaiter_stack_trace_ != nullptr)
1804 ? async_awaiter_stack_trace_
1806}
static DebuggerStackTrace * CollectAsyncAwaiters()
Definition debugger.cc:1732

◆ AsyncStepInto()

void dart::Debugger::AsyncStepInto ( const Closure awaiter)

Definition at line 4142 of file debugger.cc.

4142 {
4143 Zone* zone = Thread::Current()->zone();
4144
4145 auto& suspend_state = SuspendState::Handle(zone);
4146 if (StackTraceUtils::GetSuspendState(awaiter, &suspend_state)) {
4147 const auto& function_data =
4148 Object::Handle(zone, suspend_state.function_data());
4149 SetBreakpointAtResumption(function_data);
4150 } else {
4151 SetBreakpointAtActivation(awaiter, /*single_shot=*/true);
4152 }
4153 Continue();
4154}
Breakpoint * SetBreakpointAtActivation(const Instance &closure, bool single_shot)
Definition debugger.cc:2720
void SetBreakpointAtResumption(const Object &function_data)
Definition debugger.cc:2753
static Object & Handle()
Definition object.h:407
static bool GetSuspendState(const Closure &closure, Object *suspend_state)
Zone * zone() const
static Thread * Current()
Definition thread.h:361

◆ BreakpointAtActivation()

Breakpoint * dart::Debugger::BreakpointAtActivation ( const Instance closure)

Definition at line 2733 of file debugger.cc.

2733 {
2734 if (!closure.IsClosure()) {
2735 return nullptr;
2736 }
2737
2738 BreakpointLocation* loc = breakpoint_locations_;
2739 while (loc != nullptr) {
2740 Breakpoint* bpt = loc->breakpoints();
2741 while (bpt != nullptr) {
2742 if (closure.ptr() == bpt->closure()) {
2743 return bpt;
2744 }
2745 bpt = bpt->next();
2746 }
2747 loc = loc->next();
2748 }
2749
2750 return nullptr;
2751}
Breakpoint * next() const
Definition debugger.h:61
friend class BreakpointLocation
Definition debugger.h:925
std::function< void()> closure
Definition closure.h:14

◆ BreakpointLocationAtLineCol()

BreakpointLocation * dart::Debugger::BreakpointLocationAtLineCol ( const String script_url,
intptr_t  line_number,
intptr_t  column_number 
)

Definition at line 2817 of file debugger.cc.

2820 {
2821 Zone* zone = Thread::Current()->zone();
2822 Library& lib = Library::Handle(zone);
2823 GrowableHandlePtrArray<const Script> scripts(zone, 1);
2824 const GrowableObjectArray& libs = GrowableObjectArray::Handle(
2825 isolate_->group()->object_store()->libraries());
2826 bool is_package = script_url.StartsWith(Symbols::PackageScheme());
2827 bool is_dart_colon = script_url.StartsWith(Symbols::DartScheme());
2828 Script& script_for_lib = Script::Handle(zone);
2829 for (intptr_t i = 0; i < libs.Length(); i++) {
2830 lib ^= libs.At(i);
2831 // Ensure that all top-level members are loaded so their scripts
2832 // are available for look up. When certain script only contains
2833 // top level functions, scripts could still be loaded correctly.
2834 lib.EnsureTopLevelClassIsFinalized();
2835 bool useResolvedUri = !is_package && !is_dart_colon;
2836 script_for_lib = lib.LookupScript(script_url, useResolvedUri);
2837 if (!script_for_lib.IsNull()) {
2838 scripts.Add(script_for_lib);
2839 }
2840 }
2841 if (scripts.length() == 0) {
2842 // No script found with given url. Create a latent breakpoint which
2843 // will be set if the url is loaded later.
2844 BreakpointLocation* latent_bpt =
2845 GetLatentBreakpoint(script_url, line_number, column_number);
2846 if (FLAG_verbose_debug) {
2848 "Set latent breakpoint in url '%s' at "
2849 "line %" Pd " col %" Pd "\n",
2850 script_url.ToCString(), line_number, column_number);
2851 }
2852 return latent_bpt;
2853 }
2854 TokenPosition first_token_idx = TokenPosition::kNoSource;
2855 TokenPosition last_token_idx = TokenPosition::kNoSource;
2856 // Assume all scripts with the same URL have the same token positions.
2857 scripts.At(0).TokenRangeAtLine(line_number, &first_token_idx,
2858 &last_token_idx);
2859 if (!first_token_idx.IsReal()) {
2860 // Script does not contain the given line number.
2861 if (FLAG_verbose_debug) {
2862 OS::PrintErr("Script '%s' does not contain line number %" Pd "\n",
2863 script_url.ToCString(), line_number);
2864 }
2865 return nullptr;
2866 } else if (!last_token_idx.IsReal()) {
2867 // Line does not contain any tokens.
2868 if (FLAG_verbose_debug) {
2869 OS::PrintErr("No executable code at line %" Pd " in '%s'\n", line_number,
2870 script_url.ToCString());
2871 }
2872 return nullptr;
2873 }
2874
2875 BreakpointLocation* loc = nullptr;
2876 ASSERT(first_token_idx <= last_token_idx);
2877 while ((loc == nullptr) && (first_token_idx <= last_token_idx)) {
2878 loc = SetBreakpoint(scripts, first_token_idx, last_token_idx, line_number,
2879 column_number, Function::Handle());
2880 first_token_idx = first_token_idx.Next();
2881 }
2882 if ((loc == nullptr) && FLAG_verbose_debug) {
2883 OS::PrintErr("No executable code at line %" Pd " in '%s'\n", line_number,
2884 script_url.ToCString());
2885 }
2886 return loc;
2887}
ObjectStore * object_store() const
Definition isolate.h:505
IsolateGroup * group() const
Definition isolate.h:990
static void static void PrintErr(const char *format,...) PRINTF_ATTRIBUTE(1
#define Pd
Definition globals.h:408

◆ Continue()

void dart::Debugger::Continue ( )

Definition at line 4156 of file debugger.cc.

4156 {
4158 ResetSteppingFramePointer();
4159 NotifySingleStepping(false);
4160}
bool SetResumeAction(ResumeAction action, intptr_t frame_index=1, const char **error=nullptr)
Definition debugger.cc:1486

◆ EnterSingleStepMode()

void dart::Debugger::EnterSingleStepMode ( )

Definition at line 3079 of file debugger.cc.

3079 {
3080 ResetSteppingFramePointer();
3081 NotifySingleStepping(true);
3082}

◆ GetBreakpointById()

Breakpoint * dart::Debugger::GetBreakpointById ( intptr_t  id)

Definition at line 4118 of file debugger.cc.

4118 {
4119 Breakpoint* bpt = GetBreakpointByIdInTheList(id, breakpoint_locations_);
4120 if (bpt != nullptr) {
4121 return bpt;
4122 }
4123 return GetBreakpointByIdInTheList(id, latent_locations_);
4124}

◆ GetExceptionPauseInfo()

Dart_ExceptionPauseInfo dart::Debugger::GetExceptionPauseInfo ( ) const

Definition at line 1867 of file debugger.cc.

1867 {
1868 return exc_pause_info_;
1869}

◆ ignore_breakpoints()

bool dart::Debugger::ignore_breakpoints ( ) const
inline

Definition at line 716 of file debugger.h.

716{ return ignore_breakpoints_; }

◆ IsDebuggable()

bool dart::Debugger::IsDebuggable ( const Function func)
static

Definition at line 3403 of file debugger.cc.

3403 {
3404 if (!func.is_debuggable()) {
3405 return false;
3406 }
3407 const Class& cls = Class::Handle(func.Owner());
3408 const Library& lib = Library::Handle(cls.library());
3409 return lib.IsDebuggable();
3410}

◆ isolate()

Isolate * dart::Debugger::isolate ( ) const
inline

Definition at line 671 of file debugger.h.

671{ return isolate_; }

◆ IsPaused()

bool dart::Debugger::IsPaused ( ) const
inline

Definition at line 714 of file debugger.h.

714{ return pause_event_ != nullptr; }

◆ IsSingleStepping()

bool dart::Debugger::IsSingleStepping ( ) const
inline

Definition at line 712 of file debugger.h.

712{ return resume_action_ == kStepInto; }

◆ IsStepping()

bool dart::Debugger::IsStepping ( ) const
inline

Definition at line 710 of file debugger.h.

710{ return resume_action_ != kContinue; }

◆ limitBreakpointId()

intptr_t dart::Debugger::limitBreakpointId ( )
inline

Definition at line 770 of file debugger.h.

770{ return next_id_; }

◆ NotifyDoneLoading()

void dart::Debugger::NotifyDoneLoading ( )

Definition at line 3749 of file debugger.cc.

3749 {
3750 if (latent_locations_ == nullptr) {
3751 // Common, fast path.
3752 return;
3753 }
3754 auto thread = Thread::Current();
3755 auto isolate_group = thread->isolate_group();
3756 auto zone = thread->zone();
3757 Library& lib = Library::Handle(zone);
3758 Script& script = Script::Handle(zone);
3759 String& url = String::Handle(zone);
3760 BreakpointLocation* loc = latent_locations_;
3761 BreakpointLocation* prev_loc = nullptr;
3762 const GrowableObjectArray& libs =
3763 GrowableObjectArray::Handle(isolate_group->object_store()->libraries());
3764
3765 GrowableHandlePtrArray<const Script> scripts(zone, 1);
3766 while (loc != nullptr) {
3767 url = loc->url();
3768 bool found_match = false;
3769 bool is_package = url.StartsWith(Symbols::PackageScheme());
3770 for (intptr_t i = 0; i < libs.Length(); i++) {
3771 lib ^= libs.At(i);
3772 script = lib.LookupScript(url, !is_package);
3773 if (!script.IsNull()) {
3774 scripts.Add(script);
3775 }
3776 }
3777 if (scripts.length() > 0) {
3778 // Found a script with matching url for this latent breakpoint.
3779 // Unlink the latent breakpoint from the list.
3780 found_match = true;
3781 BreakpointLocation* matched_loc = loc;
3782 loc = loc->next();
3783 if (prev_loc == nullptr) {
3784 latent_locations_ = loc;
3785 } else {
3786 prev_loc->set_next(loc);
3787 }
3788 // Now find the token range at the requested line and make a
3789 // new unresolved source breakpoint.
3790 intptr_t line_number = matched_loc->requested_line_number();
3791 intptr_t column_number = matched_loc->requested_column_number();
3792 ASSERT(line_number >= 0);
3793 TokenPosition first_token_pos = TokenPosition::kNoSource;
3794 TokenPosition last_token_pos = TokenPosition::kNoSource;
3795 scripts.At(0).TokenRangeAtLine(line_number, &first_token_pos,
3796 &last_token_pos);
3797 if (!first_token_pos.IsDebugPause() || !last_token_pos.IsDebugPause()) {
3798 // Script does not contain the given line number or there are no
3799 // tokens on the line. Drop the breakpoint silently.
3800 Breakpoint* bpt = matched_loc->breakpoints();
3801 while (bpt != nullptr) {
3802 if (FLAG_verbose_debug) {
3803 OS::PrintErr("No code found at line %" Pd
3804 ": "
3805 "dropping latent breakpoint %" Pd " in '%s'\n",
3806 line_number, bpt->id(), url.ToCString());
3807 }
3808 Breakpoint* prev = bpt;
3809 bpt = bpt->next();
3810 delete prev;
3811 }
3812 delete matched_loc;
3813 } else {
3814 // We don't expect to already have a breakpoint for this location.
3815 // If there is one, assert in debug build but silently drop
3816 // the latent breakpoint in release build.
3817 BreakpointLocation* existing_loc =
3818 GetBreakpointLocation(url, first_token_pos, -1, column_number);
3819 ASSERT(existing_loc == nullptr);
3820 if (existing_loc == nullptr) {
3821 // Create and register a new source breakpoint for the
3822 // latent breakpoint.
3823 BreakpointLocation* unresolved_loc = new BreakpointLocation(
3824 this, scripts, first_token_pos, last_token_pos, line_number,
3825 column_number);
3826 RegisterBreakpointLocation(unresolved_loc);
3827
3828 // Move breakpoints over.
3829 Breakpoint* bpt = matched_loc->breakpoints();
3830 unresolved_loc->set_breakpoints(bpt);
3831 matched_loc->set_breakpoints(nullptr);
3832 while (bpt != nullptr) {
3833 bpt->set_bpt_location(unresolved_loc);
3834 if (FLAG_verbose_debug) {
3836 "Converted latent breakpoint "
3837 "%" Pd " in '%s' at line %" Pd " col %" Pd "\n",
3838 bpt->id(), url.ToCString(), line_number, column_number);
3839 }
3840 bpt = bpt->next();
3841 }
3842 group_debugger()->SyncBreakpointLocation(unresolved_loc);
3843 }
3844 delete matched_loc;
3845 // Break out of the iteration over loaded libraries. If the
3846 // same url has been loaded into more than one library, we
3847 // only set a breakpoint in the first one.
3848 // TODO(hausner): There is one possible pitfall here.
3849 // If the user sets a latent breakpoint using a partial url that
3850 // ends up matching more than one script, the breakpoint might
3851 // get set in the wrong script.
3852 // It would be better if we could warn the user if multiple
3853 // scripts are matching.
3854 break;
3855 }
3856 }
3857 if (!found_match) {
3858 // No matching url found in any of the libraries.
3859 if (FLAG_verbose_debug) {
3860 Breakpoint* bpt = loc->breakpoints();
3861 while (bpt != nullptr) {
3863 "No match found for latent breakpoint id "
3864 "%" Pd " with url '%s'\n",
3865 bpt->id(), url.ToCString());
3866 bpt = bpt->next();
3867 }
3868 }
3869 loc = loc->next();
3870 }
3871 }
3872}
static float prev(float f)
void SyncBreakpointLocation(BreakpointLocation *loc)
Definition debugger.cc:2683

◆ NotifyIsolateCreated()

void dart::Debugger::NotifyIsolateCreated ( )

Definition at line 3726 of file debugger.cc.

3726 {
3727 if (NeedsIsolateEvents()) {
3728 ServiceEvent event(isolate_, ServiceEvent::kIsolateStart);
3730 }
3731}
FlKeyEvent * event
static void InvokeEventHandler(ServiceEvent *event)
Definition debugger.cc:284

◆ PauseBreakpoint()

ErrorPtr dart::Debugger::PauseBreakpoint ( )

Definition at line 3610 of file debugger.cc.

3610 {
3611 // We ignore this breakpoint when the VM is executing code invoked
3612 // by the debugger to evaluate variables values, or when we see a nested
3613 // breakpoint or exception event.
3614 if (ignore_breakpoints_ || IsPaused()) {
3615 return Error::null();
3616 }
3617 DebuggerStackTrace* stack_trace = DebuggerStackTrace::Collect();
3618 ASSERT(stack_trace->Length() > 0);
3619 ActivationFrame* top_frame = stack_trace->FrameAt(0);
3620 ASSERT(top_frame != nullptr);
3621 if (!Library::Handle(top_frame->Library()).IsDebuggable()) {
3622 return Error::null();
3623 }
3624
3625 BreakpointLocation* bpt_location = nullptr;
3626 const char* cbpt_tostring = nullptr;
3627 {
3628 SafepointReadRwLocker cbl(Thread::Current(),
3629 group_debugger()->code_breakpoints_lock());
3630 CodeBreakpoint* cbpt = nullptr;
3631 bpt_location = group_debugger()->GetBreakpointLocationFor(
3632 this, top_frame->pc(), &cbpt);
3633 if (bpt_location == nullptr) {
3634 // There might be no breakpoint locations for this isolate/debugger.
3635 return Error::null();
3636 }
3637 ASSERT(cbpt != nullptr);
3638 if (FLAG_verbose_debug) {
3639 cbpt_tostring = cbpt->ToCString();
3640 }
3641 }
3642
3643 Breakpoint* bpt_hit = bpt_location->FindHitBreakpoint(top_frame);
3644 if (bpt_hit == nullptr) {
3645 return Error::null();
3646 }
3647
3648 if (FLAG_verbose_debug) {
3649 OS::PrintErr(">>> hit %" Pd
3650 " %s"
3651 " (func %s token %s address %#" Px " offset %#" Px ")\n",
3652 bpt_hit->id(), cbpt_tostring,
3653 String::Handle(top_frame->QualifiedFunctionName()).ToCString(),
3654 bpt_location->token_pos().ToCString(), top_frame->pc(),
3655 top_frame->pc() - top_frame->code().PayloadStart());
3656 }
3657
3658 CacheStackTraces(stack_trace, DebuggerStackTrace::CollectAsyncAwaiters());
3659 SignalPausedEvent(top_frame, bpt_hit);
3660 // When we single step from a user breakpoint, our next stepping
3661 // point will be at the exact same pc. Skip it.
3662 HandleSteppingRequest(/*skip_next_step=*/true);
3663 ClearCachedStackTraces();
3664
3665 // If any error occurred while in the debug message loop, return it here.
3667}
static DebuggerStackTrace * Collect()
Definition debugger.cc:1671
BreakpointLocation * GetBreakpointLocationFor(Debugger *debugger, uword breakpoint_address, CodeBreakpoint **pcbpt)
Definition debugger.cc:3893
static ObjectPtr null()
Definition object.h:433
virtual const char * ToCString() const
Definition object.h:366
DART_WARN_UNUSED_RESULT ErrorPtr StealStickyError()
Definition thread.cc:243
#define Px
Definition globals.h:410

◆ PauseDeveloper()

void dart::Debugger::PauseDeveloper ( const String msg)

Definition at line 3705 of file debugger.cc.

3705 {
3706 // We ignore this breakpoint when the VM is executing code invoked
3707 // by the debugger to evaluate variables values, or when we see a nested
3708 // breakpoint or exception event.
3709 if (ignore_breakpoints_ || IsPaused()) {
3710 return;
3711 }
3712
3713 DebuggerStackTrace* stack_trace = DebuggerStackTrace::Collect();
3714 ASSERT(stack_trace->Length() > 0);
3715 CacheStackTraces(stack_trace, DebuggerStackTrace::CollectAsyncAwaiters());
3716 // TODO(johnmccutchan): Send |msg| to Observatory.
3717
3718 // We are in the native call to Developer_debugger. the developer
3719 // gets a better experience by not seeing this call. To accomplish
3720 // this, we continue execution until the call exits (step out).
3722 HandleSteppingRequest();
3723 ClearCachedStackTraces();
3724}

◆ PauseEvent()

const ServiceEvent * dart::Debugger::PauseEvent ( ) const
inline

Definition at line 731 of file debugger.h.

731{ return pause_event_; }

◆ PauseException()

void dart::Debugger::PauseException ( const Instance exc)

Definition at line 1914 of file debugger.cc.

1914 {
1915 if (FLAG_stress_async_stacks) {
1917 }
1918 // We ignore this exception event when the VM is executing code invoked
1919 // by the debugger to evaluate variables values, when we see a nested
1920 // breakpoint or exception event, or if the debugger is not
1921 // interested in exception events.
1922 if (ignore_breakpoints_ || IsPaused() ||
1923 (exc_pause_info_ == kNoPauseOnExceptions)) {
1924 return;
1925 }
1926 DebuggerStackTrace* async_awaiter_stack_trace =
1928 DebuggerStackTrace* stack_trace = DebuggerStackTrace::Collect();
1929 if (async_awaiter_stack_trace != nullptr) {
1930 if (!ShouldPauseOnException(async_awaiter_stack_trace, exc)) {
1931 return;
1932 }
1933 } else {
1934 if (!ShouldPauseOnException(stack_trace, exc)) {
1935 return;
1936 }
1937 }
1938 ServiceEvent event(isolate_, ServiceEvent::kPauseException);
1939 event.set_exception(&exc);
1940 if (stack_trace->Length() > 0) {
1941 event.set_top_frame(stack_trace->FrameAt(0));
1942 }
1943 CacheStackTraces(stack_trace, async_awaiter_stack_trace);
1944 Pause(&event);
1945 HandleSteppingRequest(); // we may get a rewind request
1946 ClearCachedStackTraces();
1947}

◆ PauseInterrupted()

ErrorPtr dart::Debugger::PauseInterrupted ( )

Definition at line 289 of file debugger.cc.

289 {
290 return PauseRequest(ServiceEvent::kPauseInterrupted);
291}

◆ PausePostRequest()

ErrorPtr dart::Debugger::PausePostRequest ( )

Definition at line 293 of file debugger.cc.

293 {
294 return PauseRequest(ServiceEvent::kPausePostRequest);
295}

◆ PauseStepping()

ErrorPtr dart::Debugger::PauseStepping ( )

Definition at line 3524 of file debugger.cc.

3524 {
3525 ASSERT(isolate_->single_step());
3526 // Don't pause recursively.
3527 if (IsPaused()) {
3528 return Error::null();
3529 }
3530 if (skip_next_step_) {
3531 skip_next_step_ = false;
3532 return Error::null();
3533 }
3534
3535 // Check whether we are in a Dart function that the user is
3536 // interested in. If we saved the frame pointer of a stack frame
3537 // the user is interested in, we ignore the single step if we are
3538 // in a callee of that frame. Note that we assume that the stack
3539 // grows towards lower addresses.
3540 ActivationFrame* frame = TopDartFrame();
3541 ASSERT(frame != nullptr);
3542
3543 if (stepping_fp_ != 0) {
3544 // There is an "interesting frame" set. Only pause at appropriate
3545 // locations in this frame.
3546 const ActivationFrame::Relation relation = frame->CompareTo(stepping_fp_);
3547 if (relation == ActivationFrame::kCallee) {
3548 // We are in a callee of the frame we're interested in.
3549 // Ignore this stepping break.
3550 return Error::null();
3551 } else if (relation == ActivationFrame::kCaller) {
3552 // We returned from the "interesting frame", there can be no more
3553 // stepping breaks for it. Pause at the next appropriate location
3554 // and let the user set the "interesting" frame again.
3555 ResetSteppingFramePointer();
3556 }
3557 }
3558
3559 if (!frame->IsDebuggable()) {
3560 return Error::null();
3561 }
3562 if (!frame->TokenPos().IsDebugPause()) {
3563 return Error::null();
3564 }
3565
3566 if (frame->fp() == last_stepping_fp_ &&
3567 frame->TokenPos() == last_stepping_pos_) {
3568 // Do not stop multiple times for the same token position.
3569 // Several 'debug checked' opcodes may be issued in the same token range.
3570 return Error::null();
3571 }
3572
3573 // TODO(dartbug.com/48378): Consider aligning async/async* functions
3574 // with regular function wrt the first stop in the function prologue.
3575 if ((frame->function().IsAsyncFunction() ||
3576 frame->function().IsAsyncGenerator()) &&
3577 frame->GetSuspendStateVar() == Object::null()) {
3578 return Error::null();
3579 }
3580
3581 // We are stopping in this frame at the token pos.
3582 last_stepping_fp_ = frame->fp();
3583 last_stepping_pos_ = frame->TokenPos();
3584
3585 // If there is an active breakpoint at this pc, then we should have
3586 // already bailed out of this function in the skip_next_step_ test
3587 // above.
3588 ASSERT(!group_debugger()->HasActiveBreakpoint(frame->pc()));
3589
3590 if (FLAG_verbose_debug) {
3591 OS::PrintErr(">>> single step break at %s:%" Pd ":%" Pd
3592 " (func %s token %s address %#" Px " offset %#" Px ")\n",
3593 String::Handle(frame->SourceUrl()).ToCString(),
3594 frame->LineNumber(), frame->ColumnNumber(),
3595 String::Handle(frame->QualifiedFunctionName()).ToCString(),
3596 frame->TokenPos().ToCString(), frame->pc(),
3597 frame->pc() - frame->code().PayloadStart());
3598 }
3599
3600 CacheStackTraces(DebuggerStackTrace::Collect(),
3602 SignalPausedEvent(frame, nullptr);
3603 HandleSteppingRequest();
3604 ClearCachedStackTraces();
3605
3606 // If any error occurred while in the debug message loop, return it here.
3608}
bool single_step() const
Definition isolate.h:1086
double frame
Definition examples.cpp:31
static ActivationFrame * TopDartFrame()
Definition debugger.cc:1779

◆ PrintBreakpointsToJSONArray()

void dart::Debugger::PrintBreakpointsToJSONArray ( JSONArray jsarr) const

Definition at line 451 of file debugger.cc.

451 {
452 PrintBreakpointsListToJSONArray(breakpoint_locations_, jsarr);
453 PrintBreakpointsListToJSONArray(latent_locations_, jsarr);
454}

◆ PrintSettingsToJSONObject()

void dart::Debugger::PrintSettingsToJSONObject ( JSONObject jsobj) const

Definition at line 468 of file debugger.cc.

468 {
469 // This won't cut it when we support filtering by class, etc.
470 switch (GetExceptionPauseInfo()) {
472 jsobj->AddProperty("_exceptions", "none");
473 break;
475 jsobj->AddProperty("_exceptions", "all");
476 break;
478 jsobj->AddProperty("_exceptions", "unhandled");
479 break;
480 default:
481 UNREACHABLE();
482 }
483}
#define UNREACHABLE()
Definition assert.h:248
Dart_ExceptionPauseInfo GetExceptionPauseInfo() const
Definition debugger.cc:1867
@ kPauseOnUnhandledExceptions
Definition debugger.h:504
@ kPauseOnAllExceptions
Definition debugger.h:505

◆ RemoveBreakpoint()

void dart::Debugger::RemoveBreakpoint ( intptr_t  bp_id)

Definition at line 3944 of file debugger.cc.

3944 {
3945 SafepointWriteRwLocker sl(Thread::Current(),
3946 group_debugger()->breakpoint_locations_lock());
3947 if (RemoveBreakpointFromTheList(bp_id, &breakpoint_locations_)) {
3948 return;
3949 }
3950 RemoveBreakpointFromTheList(bp_id, &latent_locations_);
3951}

◆ ResumptionBreakpoint()

void dart::Debugger::ResumptionBreakpoint ( )

Definition at line 2760 of file debugger.cc.

2760 {
2761 ASSERT(!breakpoints_at_resumption_.is_empty());
2763
2764 ActivationFrame* top_frame = TopDartFrame();
2765 ASSERT(top_frame->function().IsSuspendableFunction());
2766 const auto& function_data =
2767 Object::Handle(top_frame->GetSuspendableFunctionData());
2768
2769 for (intptr_t i = 0, n = breakpoints_at_resumption_.length(); i < n; ++i) {
2770 if (breakpoints_at_resumption_[i] == function_data.ptr()) {
2771 breakpoints_at_resumption_.RemoveAt(i);
2772 if (breakpoints_at_resumption_.is_empty()) {
2773 isolate_->set_has_resumption_breakpoints(false);
2774 }
2775 if (FLAG_verbose_debug) {
2777 "ResumptionBreakpoint - hit a breakpoint, continue single "
2778 "stepping\n");
2779 }
2781 return;
2782 }
2783 }
2784}
void EnterSingleStepMode()
Definition debugger.cc:3079
void set_has_resumption_breakpoints(bool value)
Definition isolate.h:1091
bool has_resumption_breakpoints() const
Definition isolate.h:1094

◆ RewindPostDeopt()

void dart::Debugger::RewindPostDeopt ( )

Definition at line 3360 of file debugger.cc.

3360 {
3361 intptr_t rewind_frame = post_deopt_frame_index_;
3362 post_deopt_frame_index_ = -1;
3363 if (FLAG_trace_rewind) {
3364 OS::PrintErr("Post deopt, jumping to frame %" Pd "\n", rewind_frame);
3366 "-------------------------\n"
3367 "All frames...\n\n");
3368 StackFrameIterator iterator(ValidationPolicy::kDontValidateFrames,
3371 StackFrame* frame = iterator.NextFrame();
3372 intptr_t num = 0;
3373 while ((frame != nullptr)) {
3374 OS::PrintErr("#%04" Pd " %s\n", num++, frame->ToCString());
3375 frame = iterator.NextFrame();
3376 }
3377 }
3378
3379 Thread* thread = Thread::Current();
3380 Zone* zone = thread->zone();
3381 Code& code = Code::Handle(zone);
3382
3383 StackFrameIterator iterator(ValidationPolicy::kDontValidateFrames,
3386 intptr_t current_frame = 0;
3387 for (StackFrame* frame = iterator.NextFrame(); frame != nullptr;
3388 frame = iterator.NextFrame()) {
3389 ASSERT(frame->IsValid());
3390 if (frame->IsDartFrame()) {
3391 code = frame->LookupDartCode();
3392 ASSERT(!code.is_optimized());
3393 if (current_frame == rewind_frame) {
3394 RewindToUnoptimizedFrame(frame, code);
3395 UNREACHABLE();
3396 }
3397 current_frame++;
3398 }
3399 }
3400}

◆ set_ignore_breakpoints()

void dart::Debugger::set_ignore_breakpoints ( bool  ignore_breakpoints)
inline

Definition at line 717 of file debugger.h.

717 {
718 ignore_breakpoints_ = ignore_breakpoints;
719 }
bool ignore_breakpoints() const
Definition debugger.h:716

◆ SetBreakpointAtActivation()

Breakpoint * dart::Debugger::SetBreakpointAtActivation ( const Instance closure,
bool  single_shot 
)

Definition at line 2720 of file debugger.cc.

2721 {
2722 if (!closure.IsClosure()) {
2723 return nullptr;
2724 }
2725 const Function& func = Function::Handle(Closure::Cast(closure).function());
2726 const Script& script = Script::Handle(func.script());
2727 BreakpointLocation* bpt_location =
2728 SetBreakpoint(script, func.token_pos(), func.end_token_pos(), -1,
2729 -1 /* no line/col */, func);
2730 return bpt_location->AddBreakpoint(this, Closure::Cast(closure), single_shot);
2731}
Dart_NativeFunction function
Definition fuchsia.cc:51

◆ SetBreakpointAtEntry()

Breakpoint * dart::Debugger::SetBreakpointAtEntry ( const Function target_function,
bool  single_shot 
)

Definition at line 2699 of file debugger.cc.

2700 {
2701 ASSERT(!target_function.IsNull());
2702 if (!target_function.is_debuggable()) {
2703 return nullptr;
2704 }
2705 const Script& script = Script::Handle(target_function.script());
2706 BreakpointLocation* bpt_location = SetBreakpoint(
2707 script, target_function.token_pos(), target_function.end_token_pos(), -1,
2708 -1 /* no requested line/col */, target_function);
2709 if (bpt_location == nullptr) {
2710 return nullptr;
2711 }
2712
2713 if (single_shot) {
2714 return bpt_location->AddSingleShot(this);
2715 } else {
2716 return bpt_location->AddRepeated(this);
2717 }
2718}

◆ SetBreakpointAtLine()

Breakpoint * dart::Debugger::SetBreakpointAtLine ( const String script_url,
intptr_t  line_number 
)

Definition at line 2786 of file debugger.cc.

2787 {
2788 // Prevent future tests from calling this function in the wrong
2789 // execution state. If you hit this assert, consider using
2790 // Dart_SetBreakpoint instead.
2791 ASSERT(Thread::Current()->execution_state() == Thread::kThreadInVM);
2792
2793 BreakpointLocation* loc =
2794 BreakpointLocationAtLineCol(script_url, line_number, -1 /* no column */);
2795 if (loc != nullptr) {
2796 return loc->AddRepeated(this);
2797 }
2798 return nullptr;
2799}
BreakpointLocation * BreakpointLocationAtLineCol(const String &script_url, intptr_t line_number, intptr_t column_number)
Definition debugger.cc:2817

◆ SetBreakpointAtLineCol()

Breakpoint * dart::Debugger::SetBreakpointAtLineCol ( const String script_url,
intptr_t  line_number,
intptr_t  column_number 
)

Definition at line 2801 of file debugger.cc.

2803 {
2804 // Prevent future tests from calling this function in the wrong
2805 // execution state. If you hit this assert, consider using
2806 // Dart_SetBreakpoint instead.
2807 ASSERT(Thread::Current()->execution_state() == Thread::kThreadInVM);
2808
2809 BreakpointLocation* loc =
2810 BreakpointLocationAtLineCol(script_url, line_number, column_number);
2811 if (loc != nullptr) {
2812 return loc->AddRepeated(this);
2813 }
2814 return nullptr;
2815}

◆ SetBreakpointAtResumption()

void dart::Debugger::SetBreakpointAtResumption ( const Object function_data)

Definition at line 2753 of file debugger.cc.

2753 {
2754 ASSERT(!function_data.IsNull());
2755 ASSERT(function_data.IsInstance());
2756 breakpoints_at_resumption_.Add(function_data.ptr());
2757 isolate_->set_has_resumption_breakpoints(true);
2758}

◆ SetBreakpointState()

bool dart::Debugger::SetBreakpointState ( Breakpoint bpt,
bool  enable 
)

Definition at line 3927 of file debugger.cc.

3927 {
3928 SafepointWriteRwLocker sl(Thread::Current(),
3929 group_debugger()->breakpoint_locations_lock());
3930 if (bpt->is_enabled() != enable) {
3931 if (FLAG_verbose_debug) {
3932 OS::PrintErr("Setting breakpoint %" Pd " to state: %s\n", bpt->id(),
3933 enable ? "enabled" : "disabled");
3934 }
3935 enable ? bpt->Enable() : bpt->Disable();
3936 group_debugger()->SyncBreakpointLocation(bpt->bpt_location());
3937 return true;
3938 }
3939 return false;
3940}

◆ SetExceptionPauseInfo()

void dart::Debugger::SetExceptionPauseInfo ( Dart_ExceptionPauseInfo  pause_info)

Definition at line 1860 of file debugger.cc.

1860 {
1861 ASSERT((pause_info == kNoPauseOnExceptions) ||
1862 (pause_info == kPauseOnUnhandledExceptions) ||
1863 (pause_info == kPauseOnAllExceptions));
1864 exc_pause_info_ = pause_info;
1865}

◆ SetResumeAction()

bool dart::Debugger::SetResumeAction ( ResumeAction  action,
intptr_t  frame_index = 1,
const char **  error = nullptr 
)

Definition at line 1486 of file debugger.cc.

1488 {
1489 if (error != nullptr) {
1490 *error = nullptr;
1491 }
1492 resume_frame_index_ = -1;
1493 switch (action) {
1494 case kStepInto:
1495 case kStepOver:
1496 case kStepOut:
1497 case kContinue:
1498 set_resume_action(action);
1499 return true;
1500 case kStepRewind:
1501 if (!CanRewindFrame(frame_index, error)) {
1502 return false;
1503 }
1504 set_resume_action(kStepRewind);
1505 resume_frame_index_ = frame_index;
1506 return true;
1508 return SetupStepOverAsyncSuspension(error);
1509 default:
1510 UNREACHABLE();
1511 return false;
1512 }
1513}
const uint8_t uint32_t uint32_t GError ** error
static bool CanRewindFrame(intptr_t frame_index, const char **error)
Definition debugger.cc:3192

◆ Shutdown()

void dart::Debugger::Shutdown ( )

Definition at line 1434 of file debugger.cc.

1434 {
1435 // TODO(johnmccutchan): Do not create a debugger for isolates that don't need
1436 // them. Then, assert here that isolate_ is not one of those isolates.
1437 if (Isolate::IsSystemIsolate(isolate_)) {
1438 return;
1439 }
1440 {
1441 SafepointWriteRwLocker sl(Thread::Current(),
1442 group_debugger()->breakpoint_locations_lock());
1443 while (breakpoint_locations_ != nullptr) {
1444 BreakpointLocation* loc = breakpoint_locations_;
1445 group_debugger()->UnlinkCodeBreakpoints(loc);
1446 group_debugger()->UnregisterBreakpointLocation(loc);
1447 breakpoint_locations_ = breakpoint_locations_->next();
1448 delete loc;
1449 }
1450 while (latent_locations_ != nullptr) {
1451 BreakpointLocation* loc = latent_locations_;
1452 group_debugger()->UnlinkCodeBreakpoints(loc);
1453 group_debugger()->UnregisterBreakpointLocation(loc);
1454 latent_locations_ = latent_locations_->next();
1455 delete loc;
1456 }
1457 }
1458 if (NeedsIsolateEvents()) {
1459 ServiceEvent event(isolate_, ServiceEvent::kIsolateExit);
1461 }
1462}
void UnregisterBreakpointLocation(BreakpointLocation *location)
Definition debugger.cc:4026
void UnlinkCodeBreakpoints(BreakpointLocation *bpt_location)
Definition debugger.cc:4040
static bool IsSystemIsolate(const Isolate *isolate)
Definition isolate.h:1398

◆ StackTrace()

DebuggerStackTrace * dart::Debugger::StackTrace ( )

Definition at line 1797 of file debugger.cc.

1797 {
1798 return (stack_trace_ != nullptr) ? stack_trace_
1800}

◆ VisitObjectPointers()

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

Definition at line 3014 of file debugger.cc.

3014 {
3015 ASSERT(visitor != nullptr);
3016 BreakpointLocation* loc = breakpoint_locations_;
3017 while (loc != nullptr) {
3018 loc->VisitObjectPointers(visitor);
3019 loc = loc->next();
3020 }
3021 loc = latent_locations_;
3022 while (loc != nullptr) {
3023 loc->VisitObjectPointers(visitor);
3024 loc = loc->next();
3025 }
3026 for (intptr_t i = 0, n = breakpoints_at_resumption_.length(); i < n; ++i) {
3027 visitor->VisitPointer(&breakpoints_at_resumption_[i]);
3028 }
3029}

Friends And Related Symbol Documentation

◆ BreakpointLocation

friend class BreakpointLocation
friend

Definition at line 925 of file debugger.h.

◆ Isolate

friend class Isolate
friend

Definition at line 924 of file debugger.h.


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