Flutter Engine
The Flutter Engine
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 659 of file debugger.h.

Member Enumeration Documentation

◆ ResumeAction

Enumerator
kContinue 
kStepInto 
kStepOver 
kStepOut 
kStepRewind 
kStepOverAsyncSuspension 

Definition at line 661 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:673
@ kNoPauseOnExceptions
Definition: debugger.h:505

◆ ~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:716
#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 4165 of file debugger.cc.

4165 {
4166 Zone* zone = Thread::Current()->zone();
4167
4168 auto& suspend_state = SuspendState::Handle(zone);
4169 if (StackTraceUtils::GetSuspendState(awaiter, &suspend_state)) {
4170 const auto& function_data =
4171 Object::Handle(zone, suspend_state.function_data());
4172 SetBreakpointAtResumption(function_data);
4173 } else {
4174 SetBreakpointAtActivation(awaiter, /*single_shot=*/true);
4175 }
4176 Continue();
4177}
Breakpoint * SetBreakpointAtActivation(const Instance &closure, bool single_shot)
Definition: debugger.cc:2743
void Continue()
Definition: debugger.cc:4179
void SetBreakpointAtResumption(const Object &function_data)
Definition: debugger.cc:2776
static Object & Handle()
Definition: object.h:407
static bool GetSuspendState(const Closure &closure, Object *suspend_state)
Definition: stack_trace.cc:754
Zone * zone() const
Definition: thread_state.h:37
static Thread * Current()
Definition: thread.h:362

◆ BreakpointAtActivation()

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

Definition at line 2756 of file debugger.cc.

2756 {
2757 if (!closure.IsClosure()) {
2758 return nullptr;
2759 }
2760
2761 BreakpointLocation* loc = breakpoint_locations_;
2762 while (loc != nullptr) {
2763 Breakpoint* bpt = loc->breakpoints();
2764 while (bpt != nullptr) {
2765 if (closure.ptr() == bpt->closure()) {
2766 return bpt;
2767 }
2768 bpt = bpt->next();
2769 }
2770 loc = loc->next();
2771 }
2772
2773 return nullptr;
2774}
Breakpoint * next() const
Definition: debugger.h:61
friend class BreakpointLocation
Definition: debugger.h:927
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 2840 of file debugger.cc.

2843 {
2844 Zone* zone = Thread::Current()->zone();
2845 Library& lib = Library::Handle(zone);
2846 GrowableHandlePtrArray<const Script> scripts(zone, 1);
2847 const GrowableObjectArray& libs = GrowableObjectArray::Handle(
2848 isolate_->group()->object_store()->libraries());
2849 bool is_package = script_url.StartsWith(Symbols::PackageScheme());
2850 bool is_dart_colon = script_url.StartsWith(Symbols::DartScheme());
2851 Script& script_for_lib = Script::Handle(zone);
2852 for (intptr_t i = 0; i < libs.Length(); i++) {
2853 lib ^= libs.At(i);
2854 // Ensure that all top-level members are loaded so their scripts
2855 // are available for look up. When certain script only contains
2856 // top level functions, scripts could still be loaded correctly.
2857 lib.EnsureTopLevelClassIsFinalized();
2858 bool useResolvedUri = !is_package && !is_dart_colon;
2859 script_for_lib = lib.LookupScript(script_url, useResolvedUri);
2860 if (!script_for_lib.IsNull()) {
2861 scripts.Add(script_for_lib);
2862 }
2863 }
2864 if (scripts.length() == 0) {
2865 // No script found with given url. Create a latent breakpoint which
2866 // will be set if the url is loaded later.
2867 BreakpointLocation* latent_bpt =
2868 GetLatentBreakpoint(script_url, line_number, column_number);
2869 if (FLAG_verbose_debug) {
2871 "Set latent breakpoint in url '%s' at "
2872 "line %" Pd " col %" Pd "\n",
2873 script_url.ToCString(), line_number, column_number);
2874 }
2875 return latent_bpt;
2876 }
2877 TokenPosition first_token_idx = TokenPosition::kNoSource;
2878 TokenPosition last_token_idx = TokenPosition::kNoSource;
2879 // Assume all scripts with the same URL have the same token positions.
2880 scripts.At(0).TokenRangeAtLine(line_number, &first_token_idx,
2881 &last_token_idx);
2882 if (!first_token_idx.IsReal()) {
2883 // Script does not contain the given line number.
2884 if (FLAG_verbose_debug) {
2885 OS::PrintErr("Script '%s' does not contain line number %" Pd "\n",
2886 script_url.ToCString(), line_number);
2887 }
2888 return nullptr;
2889 } else if (!last_token_idx.IsReal()) {
2890 // Line does not contain any tokens.
2891 if (FLAG_verbose_debug) {
2892 OS::PrintErr("No executable code at line %" Pd " in '%s'\n", line_number,
2893 script_url.ToCString());
2894 }
2895 return nullptr;
2896 }
2897
2898 BreakpointLocation* loc = nullptr;
2899 ASSERT(first_token_idx <= last_token_idx);
2900 while ((loc == nullptr) && (first_token_idx <= last_token_idx)) {
2901 loc = SetBreakpoint(scripts, first_token_idx, last_token_idx, line_number,
2902 column_number, Function::Handle());
2903 first_token_idx = first_token_idx.Next();
2904 }
2905 if ((loc == nullptr) && FLAG_verbose_debug) {
2906 OS::PrintErr("No executable code at line %" Pd " in '%s'\n", line_number,
2907 script_url.ToCString());
2908 }
2909 return loc;
2910}
ObjectStore * object_store() const
Definition: isolate.h:510
IsolateGroup * group() const
Definition: isolate.h:1037
static void static void PrintErr(const char *format,...) PRINTF_ATTRIBUTE(1
scripts
Printing Glyph Map Stats.
#define Pd
Definition: globals.h:408

◆ Continue()

void dart::Debugger::Continue ( )

Definition at line 4179 of file debugger.cc.

4179 {
4181 ResetSteppingFramePointer();
4182 NotifySingleStepping(false);
4183}
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 3102 of file debugger.cc.

3102 {
3103 ResetSteppingFramePointer();
3104 NotifySingleStepping(true);
3105}

◆ GetBreakpointById()

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

Definition at line 4141 of file debugger.cc.

4141 {
4142 Breakpoint* bpt = GetBreakpointByIdInTheList(id, breakpoint_locations_);
4143 if (bpt != nullptr) {
4144 return bpt;
4145 }
4146 return GetBreakpointByIdInTheList(id, latent_locations_);
4147}

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

718{ return ignore_breakpoints_; }

◆ IsDebuggable()

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

Definition at line 3426 of file debugger.cc.

3426 {
3427 if (!func.is_debuggable()) {
3428 return false;
3429 }
3430 const Class& cls = Class::Handle(func.Owner());
3431 const Library& lib = Library::Handle(cls.library());
3432 return lib.IsDebuggable();
3433}

◆ isolate()

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

Definition at line 673 of file debugger.h.

673{ return isolate_; }

◆ IsPaused()

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

Definition at line 716 of file debugger.h.

716{ return pause_event_ != nullptr; }

◆ IsSingleStepping()

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

Definition at line 714 of file debugger.h.

714{ return resume_action_ == kStepInto; }

◆ IsStepping()

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

Definition at line 712 of file debugger.h.

712{ return resume_action_ != kContinue; }

◆ limitBreakpointId()

intptr_t dart::Debugger::limitBreakpointId ( )
inline

Definition at line 772 of file debugger.h.

772{ return next_id_; }

◆ NotifyDoneLoading()

void dart::Debugger::NotifyDoneLoading ( )

Definition at line 3772 of file debugger.cc.

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

◆ NotifyIsolateCreated()

void dart::Debugger::NotifyIsolateCreated ( )

Definition at line 3749 of file debugger.cc.

3749 {
3750 if (NeedsIsolateEvents()) {
3751 ServiceEvent event(isolate_, ServiceEvent::kIsolateStart);
3753 }
3754}
FlKeyEvent * event
static void InvokeEventHandler(ServiceEvent *event)
Definition: debugger.cc:284

◆ PauseBreakpoint()

ErrorPtr dart::Debugger::PauseBreakpoint ( )

Definition at line 3633 of file debugger.cc.

3633 {
3634 // We ignore this breakpoint when the VM is executing code invoked
3635 // by the debugger to evaluate variables values, or when we see a nested
3636 // breakpoint or exception event.
3637 if (ignore_breakpoints_ || IsPaused()) {
3638 return Error::null();
3639 }
3640 DebuggerStackTrace* stack_trace = DebuggerStackTrace::Collect();
3641 ASSERT(stack_trace->Length() > 0);
3642 ActivationFrame* top_frame = stack_trace->FrameAt(0);
3643 ASSERT(top_frame != nullptr);
3644 if (!Library::Handle(top_frame->Library()).IsDebuggable()) {
3645 return Error::null();
3646 }
3647
3648 BreakpointLocation* bpt_location = nullptr;
3649 const char* cbpt_tostring = nullptr;
3650 {
3651 SafepointReadRwLocker cbl(Thread::Current(),
3652 group_debugger()->code_breakpoints_lock());
3653 CodeBreakpoint* cbpt = nullptr;
3654 bpt_location = group_debugger()->GetBreakpointLocationFor(
3655 this, top_frame->pc(), &cbpt);
3656 if (bpt_location == nullptr) {
3657 // There might be no breakpoint locations for this isolate/debugger.
3658 return Error::null();
3659 }
3660 ASSERT(cbpt != nullptr);
3661 if (FLAG_verbose_debug) {
3662 cbpt_tostring = cbpt->ToCString();
3663 }
3664 }
3665
3666 Breakpoint* bpt_hit = bpt_location->FindHitBreakpoint(top_frame);
3667 if (bpt_hit == nullptr) {
3668 return Error::null();
3669 }
3670
3671 if (FLAG_verbose_debug) {
3672 OS::PrintErr(">>> hit %" Pd
3673 " %s"
3674 " (func %s token %s address %#" Px " offset %#" Px ")\n",
3675 bpt_hit->id(), cbpt_tostring,
3676 String::Handle(top_frame->QualifiedFunctionName()).ToCString(),
3677 bpt_location->token_pos().ToCString(), top_frame->pc(),
3678 top_frame->pc() - top_frame->code().PayloadStart());
3679 }
3680
3681 CacheStackTraces(stack_trace, DebuggerStackTrace::CollectAsyncAwaiters());
3682 SignalPausedEvent(top_frame, bpt_hit);
3683 // When we single step from a user breakpoint, our next stepping
3684 // point will be at the exact same pc. Skip it.
3685 HandleSteppingRequest(/*skip_next_step=*/true);
3686 ClearCachedStackTraces();
3687
3688 // If any error occurred while in the debug message loop, return it here.
3690}
static DebuggerStackTrace * Collect()
Definition: debugger.cc:1671
BreakpointLocation * GetBreakpointLocationFor(Debugger *debugger, uword breakpoint_address, CodeBreakpoint **pcbpt)
Definition: debugger.cc:3916
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:245
#define Px
Definition: globals.h:410

◆ PauseDeveloper()

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

Definition at line 3728 of file debugger.cc.

3728 {
3729 // We ignore this breakpoint when the VM is executing code invoked
3730 // by the debugger to evaluate variables values, or when we see a nested
3731 // breakpoint or exception event.
3732 if (ignore_breakpoints_ || IsPaused()) {
3733 return;
3734 }
3735
3736 DebuggerStackTrace* stack_trace = DebuggerStackTrace::Collect();
3737 ASSERT(stack_trace->Length() > 0);
3738 CacheStackTraces(stack_trace, DebuggerStackTrace::CollectAsyncAwaiters());
3739 // TODO(johnmccutchan): Send |msg| to Observatory.
3740
3741 // We are in the native call to Developer_debugger. the developer
3742 // gets a better experience by not seeing this call. To accomplish
3743 // this, we continue execution until the call exits (step out).
3745 HandleSteppingRequest();
3746 ClearCachedStackTraces();
3747}

◆ PauseEvent()

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

Definition at line 733 of file debugger.h.

733{ 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 3547 of file debugger.cc.

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

◆ RemoveBreakpoint()

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

Definition at line 3967 of file debugger.cc.

3967 {
3968 SafepointWriteRwLocker sl(Thread::Current(),
3969 group_debugger()->breakpoint_locations_lock());
3970 if (RemoveBreakpointFromTheList(bp_id, &breakpoint_locations_)) {
3971 return;
3972 }
3973 RemoveBreakpointFromTheList(bp_id, &latent_locations_);
3974}

◆ ResumptionBreakpoint()

void dart::Debugger::ResumptionBreakpoint ( )

Definition at line 2783 of file debugger.cc.

2783 {
2784 ASSERT(!breakpoints_at_resumption_.is_empty());
2786
2787 ActivationFrame* top_frame = TopDartFrame();
2788 ASSERT(top_frame->function().IsSuspendableFunction());
2789 const auto& function_data =
2790 Object::Handle(top_frame->GetSuspendableFunctionData());
2791
2792 for (intptr_t i = 0, n = breakpoints_at_resumption_.length(); i < n; ++i) {
2793 if (breakpoints_at_resumption_[i] == function_data.ptr()) {
2794 breakpoints_at_resumption_.RemoveAt(i);
2795 if (breakpoints_at_resumption_.is_empty()) {
2796 isolate_->set_has_resumption_breakpoints(false);
2797 }
2798 if (FLAG_verbose_debug) {
2800 "ResumptionBreakpoint - hit a breakpoint, continue single "
2801 "stepping\n");
2802 }
2804 return;
2805 }
2806 }
2807}
void EnterSingleStepMode()
Definition: debugger.cc:3102
void set_has_resumption_breakpoints(bool value)
Definition: isolate.h:1138
bool has_resumption_breakpoints() const
Definition: isolate.h:1141

◆ RewindPostDeopt()

void dart::Debugger::RewindPostDeopt ( )

Definition at line 3383 of file debugger.cc.

3383 {
3384 intptr_t rewind_frame = post_deopt_frame_index_;
3385 post_deopt_frame_index_ = -1;
3386 if (FLAG_trace_rewind) {
3387 OS::PrintErr("Post deopt, jumping to frame %" Pd "\n", rewind_frame);
3389 "-------------------------\n"
3390 "All frames...\n\n");
3391 StackFrameIterator iterator(ValidationPolicy::kDontValidateFrames,
3394 StackFrame* frame = iterator.NextFrame();
3395 intptr_t num = 0;
3396 while ((frame != nullptr)) {
3397 OS::PrintErr("#%04" Pd " %s\n", num++, frame->ToCString());
3398 frame = iterator.NextFrame();
3399 }
3400 }
3401
3402 Thread* thread = Thread::Current();
3403 Zone* zone = thread->zone();
3404 Code& code = Code::Handle(zone);
3405
3406 StackFrameIterator iterator(ValidationPolicy::kDontValidateFrames,
3409 intptr_t current_frame = 0;
3410 for (StackFrame* frame = iterator.NextFrame(); frame != nullptr;
3411 frame = iterator.NextFrame()) {
3412 ASSERT(frame->IsValid());
3413 if (frame->IsDartFrame()) {
3414 code = frame->LookupDartCode();
3415 ASSERT(!code.is_optimized());
3416 if (current_frame == rewind_frame) {
3417 RewindToUnoptimizedFrame(frame, code);
3418 UNREACHABLE();
3419 }
3420 current_frame++;
3421 }
3422 }
3423}

◆ set_ignore_breakpoints()

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

Definition at line 719 of file debugger.h.

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

◆ SetBreakpointAtActivation()

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

Definition at line 2743 of file debugger.cc.

2744 {
2745 if (!closure.IsClosure()) {
2746 return nullptr;
2747 }
2748 const Function& func = Function::Handle(Closure::Cast(closure).function());
2749 const Script& script = Script::Handle(func.script());
2750 BreakpointLocation* bpt_location =
2751 SetBreakpoint(script, func.token_pos(), func.end_token_pos(), -1,
2752 -1 /* no line/col */, func);
2753 return bpt_location->AddBreakpoint(this, Closure::Cast(closure), single_shot);
2754}
Dart_NativeFunction function
Definition: fuchsia.cc:51

◆ SetBreakpointAtEntry()

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

Definition at line 2722 of file debugger.cc.

2723 {
2724 ASSERT(!target_function.IsNull());
2725 if (!target_function.is_debuggable()) {
2726 return nullptr;
2727 }
2728 const Script& script = Script::Handle(target_function.script());
2729 BreakpointLocation* bpt_location = SetBreakpoint(
2730 script, target_function.token_pos(), target_function.end_token_pos(), -1,
2731 -1 /* no requested line/col */, target_function);
2732 if (bpt_location == nullptr) {
2733 return nullptr;
2734 }
2735
2736 if (single_shot) {
2737 return bpt_location->AddSingleShot(this);
2738 } else {
2739 return bpt_location->AddRepeated(this);
2740 }
2741}

◆ SetBreakpointAtLine()

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

Definition at line 2809 of file debugger.cc.

2810 {
2811 // Prevent future tests from calling this function in the wrong
2812 // execution state. If you hit this assert, consider using
2813 // Dart_SetBreakpoint instead.
2814 ASSERT(Thread::Current()->execution_state() == Thread::kThreadInVM);
2815
2816 BreakpointLocation* loc =
2817 BreakpointLocationAtLineCol(script_url, line_number, -1 /* no column */);
2818 if (loc != nullptr) {
2819 return loc->AddRepeated(this);
2820 }
2821 return nullptr;
2822}
BreakpointLocation * BreakpointLocationAtLineCol(const String &script_url, intptr_t line_number, intptr_t column_number)
Definition: debugger.cc:2840

◆ SetBreakpointAtLineCol()

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

Definition at line 2824 of file debugger.cc.

2826 {
2827 // Prevent future tests from calling this function in the wrong
2828 // execution state. If you hit this assert, consider using
2829 // Dart_SetBreakpoint instead.
2830 ASSERT(Thread::Current()->execution_state() == Thread::kThreadInVM);
2831
2832 BreakpointLocation* loc =
2833 BreakpointLocationAtLineCol(script_url, line_number, column_number);
2834 if (loc != nullptr) {
2835 return loc->AddRepeated(this);
2836 }
2837 return nullptr;
2838}

◆ SetBreakpointAtResumption()

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

Definition at line 2776 of file debugger.cc.

2776 {
2777 ASSERT(!function_data.IsNull());
2778 ASSERT(function_data.IsInstance());
2779 breakpoints_at_resumption_.Add(function_data.ptr());
2780 isolate_->set_has_resumption_breakpoints(true);
2781}

◆ SetBreakpointState()

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

Definition at line 3950 of file debugger.cc.

3950 {
3951 SafepointWriteRwLocker sl(Thread::Current(),
3952 group_debugger()->breakpoint_locations_lock());
3953 if (bpt->is_enabled() != enable) {
3954 if (FLAG_verbose_debug) {
3955 OS::PrintErr("Setting breakpoint %" Pd " to state: %s\n", bpt->id(),
3956 enable ? "enabled" : "disabled");
3957 }
3958 enable ? bpt->Enable() : bpt->Disable();
3959 group_debugger()->SyncBreakpointLocation(bpt->bpt_location());
3960 return true;
3961 }
3962 return false;
3963}

◆ 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:3215

◆ 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:4049
void UnlinkCodeBreakpoints(BreakpointLocation *bpt_location)
Definition: debugger.cc:4063
static bool IsSystemIsolate(const Isolate *isolate)
Definition: isolate.h:1445

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

3037 {
3038 ASSERT(visitor != nullptr);
3039 BreakpointLocation* loc = breakpoint_locations_;
3040 while (loc != nullptr) {
3041 loc->VisitObjectPointers(visitor);
3042 loc = loc->next();
3043 }
3044 loc = latent_locations_;
3045 while (loc != nullptr) {
3046 loc->VisitObjectPointers(visitor);
3047 loc = loc->next();
3048 }
3049 for (intptr_t i = 0, n = breakpoints_at_resumption_.length(); i < n; ++i) {
3050 visitor->VisitPointer(&breakpoints_at_resumption_[i]);
3051 }
3052}

Friends And Related Function Documentation

◆ BreakpointLocation

friend class BreakpointLocation
friend

Definition at line 927 of file debugger.h.

◆ Isolate

friend class Isolate
friend

Definition at line 926 of file debugger.h.


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