mirror of
https://github.com/dart-lang/sdk
synced 2024-09-15 22:59:47 +00:00
[vm] Remove dead pre-Observatory debugger code.
Change-Id: I13779b9a4878f84aa3995043a99fab9253e8e093 Reviewed-on: https://dart-review.googlesource.com/c/85641 Reviewed-by: Siva Annamalai <asiva@google.com> Commit-Queue: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
parent
17a7f513c3
commit
31e4c9de6e
|
@ -49,13 +49,6 @@ DEFINE_FLAG(bool,
|
||||||
"Trace debugger stacktrace collection");
|
"Trace debugger stacktrace collection");
|
||||||
DEFINE_FLAG(bool, trace_rewind, false, "Trace frame rewind");
|
DEFINE_FLAG(bool, trace_rewind, false, "Trace frame rewind");
|
||||||
DEFINE_FLAG(bool, verbose_debug, false, "Verbose debugger messages");
|
DEFINE_FLAG(bool, verbose_debug, false, "Verbose debugger messages");
|
||||||
DEFINE_FLAG(bool,
|
|
||||||
steal_breakpoints,
|
|
||||||
false,
|
|
||||||
"Intercept breakpoints and other pause events before they "
|
|
||||||
"are sent to the embedder and use a generic VM breakpoint "
|
|
||||||
"handler instead. This handler dispatches breakpoints to "
|
|
||||||
"the VM service.");
|
|
||||||
|
|
||||||
DECLARE_FLAG(bool, enable_interpreter);
|
DECLARE_FLAG(bool, enable_interpreter);
|
||||||
DECLARE_FLAG(bool, trace_deoptimization);
|
DECLARE_FLAG(bool, trace_deoptimization);
|
||||||
|
@ -63,21 +56,6 @@ DECLARE_FLAG(bool, warn_on_pause_with_no_debugger);
|
||||||
|
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
|
|
||||||
Debugger::EventHandler* Debugger::event_handler_ = NULL;
|
|
||||||
|
|
||||||
class RemoteObjectCache : public ZoneAllocated {
|
|
||||||
public:
|
|
||||||
explicit RemoteObjectCache(intptr_t initial_size);
|
|
||||||
intptr_t AddObject(const Object& obj);
|
|
||||||
RawObject* GetObj(intptr_t obj_id) const;
|
|
||||||
bool IsValidId(intptr_t obj_id) const { return obj_id < objs_->Length(); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
GrowableObjectArray* objs_;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(RemoteObjectCache);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Create an unresolved breakpoint in given token range and script.
|
// Create an unresolved breakpoint in given token range and script.
|
||||||
BreakpointLocation::BreakpointLocation(const Script& script,
|
BreakpointLocation::BreakpointLocation(const Script& script,
|
||||||
TokenPosition token_pos,
|
TokenPosition token_pos,
|
||||||
|
@ -320,25 +298,18 @@ ActivationFrame::ActivationFrame(const Closure& async_activation)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Debugger::NeedsIsolateEvents() {
|
bool Debugger::NeedsIsolateEvents() {
|
||||||
return (!Isolate::IsVMInternalIsolate(isolate_) &&
|
return !Isolate::IsVMInternalIsolate(isolate_) &&
|
||||||
((event_handler_ != NULL) || Service::isolate_stream.enabled()));
|
Service::isolate_stream.enabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Debugger::NeedsDebugEvents() {
|
bool Debugger::NeedsDebugEvents() {
|
||||||
ASSERT(!Isolate::IsVMInternalIsolate(isolate_));
|
ASSERT(!Isolate::IsVMInternalIsolate(isolate_));
|
||||||
return (FLAG_warn_on_pause_with_no_debugger || (event_handler_ != NULL) ||
|
return FLAG_warn_on_pause_with_no_debugger || Service::debug_stream.enabled();
|
||||||
Service::debug_stream.enabled());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Debugger::InvokeEventHandler(ServiceEvent* event) {
|
void Debugger::InvokeEventHandler(ServiceEvent* event) {
|
||||||
ASSERT(!event->IsPause()); // For pause events, call Pause instead.
|
ASSERT(!event->IsPause()); // For pause events, call Pause instead.
|
||||||
Service::HandleEvent(event);
|
Service::HandleEvent(event);
|
||||||
|
|
||||||
// Call the embedder's event handler, if it exists.
|
|
||||||
if (event_handler_ != NULL) {
|
|
||||||
TransitionVMToNative transition(Thread::Current());
|
|
||||||
(*event_handler_)(event);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RawError* Debugger::PauseInterrupted() {
|
RawError* Debugger::PauseInterrupted() {
|
||||||
|
@ -1637,31 +1608,8 @@ void CodeBreakpoint::Disable() {
|
||||||
ASSERT(!is_enabled_);
|
ASSERT(!is_enabled_);
|
||||||
}
|
}
|
||||||
|
|
||||||
RemoteObjectCache::RemoteObjectCache(intptr_t initial_size) {
|
Debugger::Debugger(Isolate* isolate)
|
||||||
objs_ =
|
: isolate_(isolate),
|
||||||
&GrowableObjectArray::ZoneHandle(GrowableObjectArray::New(initial_size));
|
|
||||||
}
|
|
||||||
|
|
||||||
intptr_t RemoteObjectCache::AddObject(const Object& obj) {
|
|
||||||
intptr_t len = objs_->Length();
|
|
||||||
for (intptr_t i = 0; i < len; i++) {
|
|
||||||
if (objs_->At(i) == obj.raw()) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
objs_->Add(obj);
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
RawObject* RemoteObjectCache::GetObj(intptr_t obj_id) const {
|
|
||||||
ASSERT(IsValidId(obj_id));
|
|
||||||
return objs_->At(obj_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
Debugger::Debugger()
|
|
||||||
: isolate_(NULL),
|
|
||||||
isolate_id_(ILLEGAL_ISOLATE_ID),
|
|
||||||
initialized_(false),
|
|
||||||
next_id_(1),
|
next_id_(1),
|
||||||
latent_locations_(NULL),
|
latent_locations_(NULL),
|
||||||
breakpoint_locations_(NULL),
|
breakpoint_locations_(NULL),
|
||||||
|
@ -1671,7 +1619,6 @@ Debugger::Debugger()
|
||||||
post_deopt_frame_index_(-1),
|
post_deopt_frame_index_(-1),
|
||||||
ignore_breakpoints_(false),
|
ignore_breakpoints_(false),
|
||||||
pause_event_(NULL),
|
pause_event_(NULL),
|
||||||
obj_cache_(NULL),
|
|
||||||
stack_trace_(NULL),
|
stack_trace_(NULL),
|
||||||
async_causal_stack_trace_(NULL),
|
async_causal_stack_trace_(NULL),
|
||||||
awaiter_stack_trace_(NULL),
|
awaiter_stack_trace_(NULL),
|
||||||
|
@ -1684,14 +1631,12 @@ Debugger::Debugger()
|
||||||
exc_pause_info_(kNoPauseOnExceptions) {}
|
exc_pause_info_(kNoPauseOnExceptions) {}
|
||||||
|
|
||||||
Debugger::~Debugger() {
|
Debugger::~Debugger() {
|
||||||
isolate_id_ = ILLEGAL_ISOLATE_ID;
|
|
||||||
ASSERT(!IsPaused());
|
ASSERT(!IsPaused());
|
||||||
ASSERT(latent_locations_ == NULL);
|
ASSERT(latent_locations_ == NULL);
|
||||||
ASSERT(breakpoint_locations_ == NULL);
|
ASSERT(breakpoint_locations_ == NULL);
|
||||||
ASSERT(code_breakpoints_ == NULL);
|
ASSERT(code_breakpoints_ == NULL);
|
||||||
ASSERT(stack_trace_ == NULL);
|
ASSERT(stack_trace_ == NULL);
|
||||||
ASSERT(async_causal_stack_trace_ == NULL);
|
ASSERT(async_causal_stack_trace_ == NULL);
|
||||||
ASSERT(obj_cache_ == NULL);
|
|
||||||
ASSERT(synthetic_async_breakpoint_ == NULL);
|
ASSERT(synthetic_async_breakpoint_ == NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3139,198 +3084,6 @@ BreakpointLocation* Debugger::BreakpointLocationAtLineCol(
|
||||||
return bpt;
|
return bpt;
|
||||||
}
|
}
|
||||||
|
|
||||||
intptr_t Debugger::CacheObject(const Object& obj) {
|
|
||||||
ASSERT(obj_cache_ != NULL);
|
|
||||||
return obj_cache_->AddObject(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Debugger::IsValidObjectId(intptr_t obj_id) {
|
|
||||||
ASSERT(obj_cache_ != NULL);
|
|
||||||
return obj_cache_->IsValidId(obj_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
RawObject* Debugger::GetCachedObject(intptr_t obj_id) {
|
|
||||||
ASSERT(obj_cache_ != NULL);
|
|
||||||
return obj_cache_->GetObj(obj_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(hausner): Merge some of this functionality with the code in
|
|
||||||
// dart_api_impl.cc.
|
|
||||||
RawObject* Debugger::GetInstanceField(const Class& cls,
|
|
||||||
const String& field_name,
|
|
||||||
const Instance& object) {
|
|
||||||
const Function& getter_func =
|
|
||||||
Function::Handle(cls.LookupGetterFunction(field_name));
|
|
||||||
ASSERT(!getter_func.IsNull());
|
|
||||||
|
|
||||||
PassiveObject& result = PassiveObject::Handle();
|
|
||||||
bool saved_ignore_flag = ignore_breakpoints_;
|
|
||||||
ignore_breakpoints_ = true;
|
|
||||||
|
|
||||||
LongJumpScope jump;
|
|
||||||
if (setjmp(*jump.Set()) == 0) {
|
|
||||||
const Array& args = Array::Handle(Array::New(1));
|
|
||||||
args.SetAt(0, object);
|
|
||||||
result = DartEntry::InvokeFunction(getter_func, args);
|
|
||||||
} else {
|
|
||||||
result = Thread::Current()->sticky_error();
|
|
||||||
}
|
|
||||||
ignore_breakpoints_ = saved_ignore_flag;
|
|
||||||
return result.raw();
|
|
||||||
}
|
|
||||||
|
|
||||||
RawObject* Debugger::GetStaticField(const Class& cls,
|
|
||||||
const String& field_name) {
|
|
||||||
const Field& fld =
|
|
||||||
Field::Handle(cls.LookupStaticFieldAllowPrivate(field_name));
|
|
||||||
if (!fld.IsNull()) {
|
|
||||||
// Return the value in the field if it has been initialized already.
|
|
||||||
const Instance& value = Instance::Handle(fld.StaticValue());
|
|
||||||
ASSERT(value.raw() != Object::transition_sentinel().raw());
|
|
||||||
if (value.raw() != Object::sentinel().raw()) {
|
|
||||||
return value.raw();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// There is no field or the field has not been initialized yet.
|
|
||||||
// We must have a getter. Run the getter.
|
|
||||||
const Function& getter_func =
|
|
||||||
Function::Handle(cls.LookupGetterFunction(field_name));
|
|
||||||
ASSERT(!getter_func.IsNull());
|
|
||||||
if (getter_func.IsNull()) {
|
|
||||||
return Object::null();
|
|
||||||
}
|
|
||||||
|
|
||||||
PassiveObject& result = PassiveObject::Handle();
|
|
||||||
bool saved_ignore_flag = ignore_breakpoints_;
|
|
||||||
ignore_breakpoints_ = true;
|
|
||||||
LongJumpScope jump;
|
|
||||||
if (setjmp(*jump.Set()) == 0) {
|
|
||||||
result = DartEntry::InvokeFunction(getter_func, Object::empty_array());
|
|
||||||
} else {
|
|
||||||
result = Thread::Current()->sticky_error();
|
|
||||||
}
|
|
||||||
ignore_breakpoints_ = saved_ignore_flag;
|
|
||||||
return result.raw();
|
|
||||||
}
|
|
||||||
|
|
||||||
RawArray* Debugger::GetInstanceFields(const Instance& obj) {
|
|
||||||
Class& cls = Class::Handle(obj.clazz());
|
|
||||||
Array& fields = Array::Handle();
|
|
||||||
Field& field = Field::Handle();
|
|
||||||
const GrowableObjectArray& field_list =
|
|
||||||
GrowableObjectArray::Handle(GrowableObjectArray::New(8));
|
|
||||||
String& field_name = String::Handle();
|
|
||||||
PassiveObject& field_value = PassiveObject::Handle();
|
|
||||||
// Iterate over fields in class hierarchy to count all instance fields.
|
|
||||||
while (!cls.IsNull()) {
|
|
||||||
fields = cls.fields();
|
|
||||||
for (intptr_t i = 0; i < fields.Length(); i++) {
|
|
||||||
field ^= fields.At(i);
|
|
||||||
if (!field.is_static()) {
|
|
||||||
field_name = field.name();
|
|
||||||
field_list.Add(field_name);
|
|
||||||
field_value = GetInstanceField(cls, field_name, obj);
|
|
||||||
field_list.Add(field_value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cls = cls.SuperClass();
|
|
||||||
}
|
|
||||||
return Array::MakeFixedLength(field_list);
|
|
||||||
}
|
|
||||||
|
|
||||||
RawArray* Debugger::GetStaticFields(const Class& cls) {
|
|
||||||
const GrowableObjectArray& field_list =
|
|
||||||
GrowableObjectArray::Handle(GrowableObjectArray::New(8));
|
|
||||||
Array& fields = Array::Handle(cls.fields());
|
|
||||||
Field& field = Field::Handle();
|
|
||||||
String& field_name = String::Handle();
|
|
||||||
PassiveObject& field_value = PassiveObject::Handle();
|
|
||||||
for (intptr_t i = 0; i < fields.Length(); i++) {
|
|
||||||
field ^= fields.At(i);
|
|
||||||
if (field.is_static()) {
|
|
||||||
field_name = field.name();
|
|
||||||
field_value = GetStaticField(cls, field_name);
|
|
||||||
field_list.Add(field_name);
|
|
||||||
field_list.Add(field_value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Array::MakeFixedLength(field_list);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Debugger::CollectLibraryFields(const GrowableObjectArray& field_list,
|
|
||||||
const Library& lib,
|
|
||||||
const String& prefix,
|
|
||||||
bool include_private_fields) {
|
|
||||||
DictionaryIterator it(lib);
|
|
||||||
Zone* zone = Thread::Current()->zone();
|
|
||||||
Object& entry = Object::Handle(zone);
|
|
||||||
Field& field = Field::Handle(zone);
|
|
||||||
String& field_name = String::Handle(zone);
|
|
||||||
PassiveObject& field_value = PassiveObject::Handle(zone);
|
|
||||||
while (it.HasNext()) {
|
|
||||||
entry = it.GetNext();
|
|
||||||
if (entry.IsField()) {
|
|
||||||
field ^= entry.raw();
|
|
||||||
ASSERT(field.is_static());
|
|
||||||
field_name = field.name();
|
|
||||||
if ((field_name.CharAt(0) == '_') && !include_private_fields) {
|
|
||||||
// Skip library-private field.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// If the field is not initialized yet, report the value to be
|
|
||||||
// "<not initialized>". We don't want to execute the implicit getter
|
|
||||||
// since it may have side effects.
|
|
||||||
if ((field.StaticValue() == Object::sentinel().raw()) ||
|
|
||||||
(field.StaticValue() == Object::transition_sentinel().raw())) {
|
|
||||||
field_value = Symbols::NotInitialized().raw();
|
|
||||||
} else {
|
|
||||||
field_value = field.StaticValue();
|
|
||||||
}
|
|
||||||
if (!prefix.IsNull()) {
|
|
||||||
field_name = String::Concat(prefix, field_name);
|
|
||||||
}
|
|
||||||
field_list.Add(field_name);
|
|
||||||
field_list.Add(field_value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RawArray* Debugger::GetLibraryFields(const Library& lib) {
|
|
||||||
Zone* zone = Thread::Current()->zone();
|
|
||||||
const GrowableObjectArray& field_list =
|
|
||||||
GrowableObjectArray::Handle(GrowableObjectArray::New(8));
|
|
||||||
CollectLibraryFields(field_list, lib, String::Handle(zone), true);
|
|
||||||
return Array::MakeFixedLength(field_list);
|
|
||||||
}
|
|
||||||
|
|
||||||
RawArray* Debugger::GetGlobalFields(const Library& lib) {
|
|
||||||
Zone* zone = Thread::Current()->zone();
|
|
||||||
const GrowableObjectArray& field_list =
|
|
||||||
GrowableObjectArray::Handle(zone, GrowableObjectArray::New(8));
|
|
||||||
String& prefix_name = String::Handle(zone);
|
|
||||||
CollectLibraryFields(field_list, lib, prefix_name, true);
|
|
||||||
Library& imported = Library::Handle(zone);
|
|
||||||
intptr_t num_imports = lib.num_imports();
|
|
||||||
for (intptr_t i = 0; i < num_imports; i++) {
|
|
||||||
imported = lib.ImportLibraryAt(i);
|
|
||||||
ASSERT(!imported.IsNull());
|
|
||||||
CollectLibraryFields(field_list, imported, prefix_name, false);
|
|
||||||
}
|
|
||||||
LibraryPrefix& prefix = LibraryPrefix::Handle(zone);
|
|
||||||
LibraryPrefixIterator it(lib);
|
|
||||||
while (it.HasNext()) {
|
|
||||||
prefix = it.GetNext();
|
|
||||||
prefix_name = prefix.name();
|
|
||||||
ASSERT(!prefix_name.IsNull());
|
|
||||||
prefix_name = String::Concat(prefix_name, Symbols::Dot());
|
|
||||||
for (int32_t i = 0; i < prefix.num_imports(); i++) {
|
|
||||||
imported = prefix.GetLibrary(i);
|
|
||||||
CollectLibraryFields(field_list, imported, prefix_name, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Array::MakeFixedLength(field_list);
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void Debugger::VisitObjectPointers(ObjectPointerVisitor* visitor) {
|
void Debugger::VisitObjectPointers(ObjectPointerVisitor* visitor) {
|
||||||
ASSERT(visitor != NULL);
|
ASSERT(visitor != NULL);
|
||||||
|
@ -3352,20 +3105,13 @@ void Debugger::VisitObjectPointers(ObjectPointerVisitor* visitor) {
|
||||||
visitor->VisitPointer(reinterpret_cast<RawObject**>(&top_frame_awaiter_));
|
visitor->VisitPointer(reinterpret_cast<RawObject**>(&top_frame_awaiter_));
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
|
||||||
void Debugger::SetEventHandler(EventHandler* handler) {
|
|
||||||
event_handler_ = handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Debugger::Pause(ServiceEvent* event) {
|
void Debugger::Pause(ServiceEvent* event) {
|
||||||
ASSERT(event->IsPause()); // Should call InvokeEventHandler instead.
|
ASSERT(event->IsPause()); // Should call InvokeEventHandler instead.
|
||||||
ASSERT(!ignore_breakpoints_); // We shouldn't get here when ignoring bpts.
|
ASSERT(!ignore_breakpoints_); // We shouldn't get here when ignoring bpts.
|
||||||
ASSERT(!IsPaused()); // No recursive pausing.
|
ASSERT(!IsPaused()); // No recursive pausing.
|
||||||
ASSERT(obj_cache_ == NULL);
|
|
||||||
|
|
||||||
pause_event_ = event;
|
pause_event_ = event;
|
||||||
pause_event_->UpdateTimestamp();
|
pause_event_->UpdateTimestamp();
|
||||||
obj_cache_ = new RemoteObjectCache(64);
|
|
||||||
|
|
||||||
// We are about to invoke the debugger's event handler. Disable
|
// We are about to invoke the debugger's event handler. Disable
|
||||||
// interrupts for this thread while waiting for debug commands over
|
// interrupts for this thread while waiting for debug commands over
|
||||||
|
@ -3380,13 +3126,8 @@ void Debugger::Pause(ServiceEvent* event) {
|
||||||
Service::HandleEvent(event);
|
Service::HandleEvent(event);
|
||||||
|
|
||||||
{
|
{
|
||||||
TransitionVMToNative transition(Thread::Current());
|
TransitionVMToNative transition(thread);
|
||||||
if (FLAG_steal_breakpoints || (event_handler_ == NULL)) {
|
isolate_->PauseEventHandler();
|
||||||
// We allow the embedder's default breakpoint handler to be overridden.
|
|
||||||
isolate_->PauseEventHandler();
|
|
||||||
} else if (event_handler_ != NULL) {
|
|
||||||
(*event_handler_)(event);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notify the service that we have resumed.
|
// Notify the service that we have resumed.
|
||||||
|
@ -3406,7 +3147,6 @@ void Debugger::Pause(ServiceEvent* event) {
|
||||||
RemoveUnlinkedCodeBreakpoints();
|
RemoveUnlinkedCodeBreakpoints();
|
||||||
}
|
}
|
||||||
pause_event_ = NULL;
|
pause_event_ = NULL;
|
||||||
obj_cache_ = NULL; // Zone allocated
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Debugger::EnterSingleStepMode() {
|
void Debugger::EnterSingleStepMode() {
|
||||||
|
@ -3785,7 +3525,6 @@ void Debugger::SignalPausedEvent(ActivationFrame* top_frame, Breakpoint* bpt) {
|
||||||
ResetSteppingFramePointers();
|
ResetSteppingFramePointers();
|
||||||
isolate_->set_single_step(false);
|
isolate_->set_single_step(false);
|
||||||
ASSERT(!IsPaused());
|
ASSERT(!IsPaused());
|
||||||
ASSERT(obj_cache_ == NULL);
|
|
||||||
if ((bpt != NULL) && bpt->IsSingleShot()) {
|
if ((bpt != NULL) && bpt->IsSingleShot()) {
|
||||||
RemoveBreakpoint(bpt->id());
|
RemoveBreakpoint(bpt->id());
|
||||||
bpt = NULL;
|
bpt = NULL;
|
||||||
|
@ -4049,19 +3788,6 @@ void Debugger::PauseDeveloper(const String& msg) {
|
||||||
ClearCachedStackTraces();
|
ClearCachedStackTraces();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Debugger::Initialize(Isolate* isolate) {
|
|
||||||
if (initialized_) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
isolate_ = isolate;
|
|
||||||
|
|
||||||
// Use the isolate's control port as the isolate_id for debugging.
|
|
||||||
// This port will be used as a unique ID to represent the isolate in
|
|
||||||
// the debugger embedder api.
|
|
||||||
isolate_id_ = isolate_->main_port();
|
|
||||||
initialized_ = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Debugger::NotifyIsolateCreated() {
|
void Debugger::NotifyIsolateCreated() {
|
||||||
if (NeedsIsolateEvents()) {
|
if (NeedsIsolateEvents()) {
|
||||||
ServiceEvent event(isolate_, ServiceEvent::kIsolateStart);
|
ServiceEvent event(isolate_, ServiceEvent::kIsolateStart);
|
||||||
|
|
|
@ -32,7 +32,6 @@ class Isolate;
|
||||||
class JSONArray;
|
class JSONArray;
|
||||||
class JSONStream;
|
class JSONStream;
|
||||||
class ObjectPointerVisitor;
|
class ObjectPointerVisitor;
|
||||||
class RemoteObjectCache;
|
|
||||||
class BreakpointLocation;
|
class BreakpointLocation;
|
||||||
class StackFrame;
|
class StackFrame;
|
||||||
|
|
||||||
|
@ -469,12 +468,9 @@ class Debugger {
|
||||||
kStepOverAsyncSuspension,
|
kStepOverAsyncSuspension,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void EventHandler(ServiceEvent* event);
|
explicit Debugger(Isolate* isolate);
|
||||||
|
|
||||||
Debugger();
|
|
||||||
~Debugger();
|
~Debugger();
|
||||||
|
|
||||||
void Initialize(Isolate* isolate);
|
|
||||||
void NotifyIsolateCreated();
|
void NotifyIsolateCreated();
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
|
||||||
|
@ -540,9 +536,6 @@ class Debugger {
|
||||||
|
|
||||||
void VisitObjectPointers(ObjectPointerVisitor* visitor);
|
void VisitObjectPointers(ObjectPointerVisitor* visitor);
|
||||||
|
|
||||||
// Called from Runtime when a breakpoint in Dart code is reached.
|
|
||||||
void BreakpointCallback();
|
|
||||||
|
|
||||||
// Returns true if there is at least one breakpoint set in func or code.
|
// Returns true if there is at least one breakpoint set in func or code.
|
||||||
// Checks for both user-defined and internal temporary breakpoints.
|
// Checks for both user-defined and internal temporary breakpoints.
|
||||||
// This may be called from different threads, therefore do not use the,
|
// This may be called from different threads, therefore do not use the,
|
||||||
|
@ -572,27 +565,9 @@ class Debugger {
|
||||||
// to query local variables in the returned stack.
|
// to query local variables in the returned stack.
|
||||||
DebuggerStackTrace* StackTraceFrom(const class StackTrace& dart_stacktrace);
|
DebuggerStackTrace* StackTraceFrom(const class StackTrace& dart_stacktrace);
|
||||||
|
|
||||||
RawArray* GetInstanceFields(const Instance& obj);
|
|
||||||
RawArray* GetStaticFields(const Class& cls);
|
|
||||||
RawArray* GetLibraryFields(const Library& lib);
|
|
||||||
RawArray* GetGlobalFields(const Library& lib);
|
|
||||||
|
|
||||||
intptr_t CacheObject(const Object& obj);
|
|
||||||
RawObject* GetCachedObject(intptr_t obj_id);
|
|
||||||
bool IsValidObjectId(intptr_t obj_id);
|
|
||||||
|
|
||||||
Dart_Port GetIsolateId() { return isolate_id_; }
|
|
||||||
|
|
||||||
static void SetEventHandler(EventHandler* handler);
|
|
||||||
|
|
||||||
// Utility functions.
|
// Utility functions.
|
||||||
static const char* QualifiedFunctionName(const Function& func);
|
static const char* QualifiedFunctionName(const Function& func);
|
||||||
|
|
||||||
RawObject* GetInstanceField(const Class& cls,
|
|
||||||
const String& field_name,
|
|
||||||
const Instance& object);
|
|
||||||
RawObject* GetStaticField(const Class& cls, const String& field_name);
|
|
||||||
|
|
||||||
// Pause execution for a breakpoint. Called from generated code.
|
// Pause execution for a breakpoint. Called from generated code.
|
||||||
RawError* PauseBreakpoint();
|
RawError* PauseBreakpoint();
|
||||||
|
|
||||||
|
@ -717,11 +692,6 @@ class Debugger {
|
||||||
bool ShouldPauseOnException(DebuggerStackTrace* stack_trace,
|
bool ShouldPauseOnException(DebuggerStackTrace* stack_trace,
|
||||||
const Instance& exc);
|
const Instance& exc);
|
||||||
|
|
||||||
void CollectLibraryFields(const GrowableObjectArray& field_list,
|
|
||||||
const Library& lib,
|
|
||||||
const String& prefix,
|
|
||||||
bool include_private_fields);
|
|
||||||
|
|
||||||
// Handles any events which pause vm execution. Breakpoints,
|
// Handles any events which pause vm execution. Breakpoints,
|
||||||
// interrupts, etc.
|
// interrupts, etc.
|
||||||
void Pause(ServiceEvent* event);
|
void Pause(ServiceEvent* event);
|
||||||
|
@ -750,8 +720,6 @@ class Debugger {
|
||||||
void SetAsyncSteppingFramePointer();
|
void SetAsyncSteppingFramePointer();
|
||||||
|
|
||||||
Isolate* isolate_;
|
Isolate* isolate_;
|
||||||
Dart_Port isolate_id_; // A unique ID for the isolate in the debugger.
|
|
||||||
bool initialized_;
|
|
||||||
|
|
||||||
// ID number generator.
|
// ID number generator.
|
||||||
intptr_t next_id_;
|
intptr_t next_id_;
|
||||||
|
@ -776,9 +744,6 @@ class Debugger {
|
||||||
// exceptions.
|
// exceptions.
|
||||||
ServiceEvent* pause_event_;
|
ServiceEvent* pause_event_;
|
||||||
|
|
||||||
// An id -> object map. Valid only while IsPaused().
|
|
||||||
RemoteObjectCache* obj_cache_;
|
|
||||||
|
|
||||||
// Current stack trace. Valid only while IsPaused().
|
// Current stack trace. Valid only while IsPaused().
|
||||||
DebuggerStackTrace* stack_trace_;
|
DebuggerStackTrace* stack_trace_;
|
||||||
DebuggerStackTrace* async_causal_stack_trace_;
|
DebuggerStackTrace* async_causal_stack_trace_;
|
||||||
|
@ -806,8 +771,6 @@ class Debugger {
|
||||||
|
|
||||||
Dart_ExceptionPauseInfo exc_pause_info_;
|
Dart_ExceptionPauseInfo exc_pause_info_;
|
||||||
|
|
||||||
static EventHandler* event_handler_;
|
|
||||||
|
|
||||||
friend class Isolate;
|
friend class Isolate;
|
||||||
friend class BreakpointLocation;
|
friend class BreakpointLocation;
|
||||||
DISALLOW_COPY_AND_ASSIGN(Debugger);
|
DISALLOW_COPY_AND_ASSIGN(Debugger);
|
||||||
|
|
|
@ -83,82 +83,6 @@ DART_EXPORT Dart_Handle Dart_GetActivationFrame(Dart_StackTrace trace,
|
||||||
return Api::Success();
|
return Api::Success();
|
||||||
}
|
}
|
||||||
|
|
||||||
static Dart_PausedEventHandler* paused_event_handler = NULL;
|
|
||||||
static Dart_BreakpointResolvedHandler* bp_resolved_handler = NULL;
|
|
||||||
static Dart_ExceptionThrownHandler* exc_thrown_handler = NULL;
|
|
||||||
static Dart_IsolateEventHandler* isolate_event_handler = NULL;
|
|
||||||
|
|
||||||
static void DebuggerEventHandler(ServiceEvent* event) {
|
|
||||||
Thread* thread = Thread::Current();
|
|
||||||
Isolate* isolate = thread->isolate();
|
|
||||||
ASSERT(isolate != NULL);
|
|
||||||
Dart_EnterScope();
|
|
||||||
Dart_IsolateId isolate_id = isolate->debugger()->GetIsolateId();
|
|
||||||
if (event->kind() == ServiceEvent::kPauseBreakpoint) {
|
|
||||||
if (paused_event_handler != NULL) {
|
|
||||||
Dart_CodeLocation location;
|
|
||||||
ActivationFrame* top_frame = event->top_frame();
|
|
||||||
location.script_url = Api::NewHandle(thread, top_frame->SourceUrl());
|
|
||||||
const Library& lib = Library::Handle(top_frame->Library());
|
|
||||||
location.library_id = lib.index();
|
|
||||||
location.token_pos = top_frame->TokenPos().Pos();
|
|
||||||
intptr_t bp_id = 0;
|
|
||||||
if (event->breakpoint() != NULL) {
|
|
||||||
ASSERT(event->breakpoint()->id() != ILLEGAL_BREAKPOINT_ID);
|
|
||||||
bp_id = event->breakpoint()->id();
|
|
||||||
}
|
|
||||||
(*paused_event_handler)(isolate_id, bp_id, location);
|
|
||||||
}
|
|
||||||
} else if (event->kind() == ServiceEvent::kBreakpointAdded ||
|
|
||||||
event->kind() == ServiceEvent::kBreakpointResolved) {
|
|
||||||
Breakpoint* bpt = event->breakpoint();
|
|
||||||
ASSERT(bpt != NULL);
|
|
||||||
if (bp_resolved_handler != NULL && bpt->bpt_location()->IsResolved() &&
|
|
||||||
!bpt->IsSingleShot()) {
|
|
||||||
Dart_CodeLocation location;
|
|
||||||
Zone* zone = thread->zone();
|
|
||||||
Library& library = Library::Handle(zone);
|
|
||||||
Script& script = Script::Handle(zone);
|
|
||||||
TokenPosition token_pos;
|
|
||||||
bpt->bpt_location()->GetCodeLocation(&library, &script, &token_pos);
|
|
||||||
location.script_url = Api::NewHandle(thread, script.url());
|
|
||||||
location.library_id = library.index();
|
|
||||||
location.token_pos = token_pos.Pos();
|
|
||||||
(*bp_resolved_handler)(isolate_id, bpt->id(), location);
|
|
||||||
}
|
|
||||||
} else if (event->kind() == ServiceEvent::kBreakpointRemoved) {
|
|
||||||
// Ignore.
|
|
||||||
} else if (event->kind() == ServiceEvent::kPauseException) {
|
|
||||||
if (exc_thrown_handler != NULL) {
|
|
||||||
Dart_Handle exception = Api::NewHandle(thread, event->exception()->raw());
|
|
||||||
Dart_StackTrace trace =
|
|
||||||
reinterpret_cast<Dart_StackTrace>(isolate->debugger()->StackTrace());
|
|
||||||
(*exc_thrown_handler)(isolate_id, exception, trace);
|
|
||||||
}
|
|
||||||
} else if (event->kind() == ServiceEvent::kIsolateStart) {
|
|
||||||
if (isolate_event_handler != NULL) {
|
|
||||||
(*isolate_event_handler)(event->isolate_id(), kCreated);
|
|
||||||
}
|
|
||||||
} else if (event->kind() == ServiceEvent::kPauseInterrupted ||
|
|
||||||
event->kind() == ServiceEvent::kPausePostRequest) {
|
|
||||||
if (isolate_event_handler != NULL) {
|
|
||||||
(*isolate_event_handler)(event->isolate_id(), kInterrupted);
|
|
||||||
}
|
|
||||||
} else if (event->kind() == ServiceEvent::kIsolateExit) {
|
|
||||||
if (isolate_event_handler != NULL) {
|
|
||||||
(*isolate_event_handler)(event->isolate_id(), kShutdown);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
UNIMPLEMENTED();
|
|
||||||
}
|
|
||||||
Dart_ExitScope();
|
|
||||||
}
|
|
||||||
|
|
||||||
DART_EXPORT void Dart_SetPausedEventHandler(Dart_PausedEventHandler handler) {
|
|
||||||
paused_event_handler = handler;
|
|
||||||
Debugger::SetEventHandler(DebuggerEventHandler);
|
|
||||||
}
|
|
||||||
|
|
||||||
DART_EXPORT Dart_Handle Dart_GetStackTrace(Dart_StackTrace* trace) {
|
DART_EXPORT Dart_Handle Dart_GetStackTrace(Dart_StackTrace* trace) {
|
||||||
DARTSCOPE(Thread::Current());
|
DARTSCOPE(Thread::Current());
|
||||||
Isolate* I = T->isolate();
|
Isolate* I = T->isolate();
|
||||||
|
@ -282,36 +206,6 @@ DART_EXPORT Dart_Handle Dart_EvaluateStaticExpr(Dart_Handle lib_handle,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DART_EXPORT Dart_Handle Dart_GetLibraryIds() {
|
|
||||||
DARTSCOPE(Thread::Current());
|
|
||||||
Isolate* I = T->isolate();
|
|
||||||
|
|
||||||
const GrowableObjectArray& libs =
|
|
||||||
GrowableObjectArray::Handle(Z, I->object_store()->libraries());
|
|
||||||
int num_libs = libs.Length();
|
|
||||||
|
|
||||||
// Create new list and populate with the url of loaded libraries.
|
|
||||||
Library& lib = Library::Handle();
|
|
||||||
const Array& library_id_list = Array::Handle(Z, Array::New(num_libs));
|
|
||||||
for (int i = 0; i < num_libs; i++) {
|
|
||||||
lib ^= libs.At(i);
|
|
||||||
ASSERT(!lib.IsNull());
|
|
||||||
ASSERT(Smi::IsValid(lib.index()));
|
|
||||||
library_id_list.SetAt(i, Smi::Handle(Smi::New(lib.index())));
|
|
||||||
}
|
|
||||||
return Api::NewHandle(T, library_id_list.raw());
|
|
||||||
}
|
|
||||||
|
|
||||||
DART_EXPORT Dart_Handle Dart_GetLibraryFromId(intptr_t library_id) {
|
|
||||||
DARTSCOPE(Thread::Current());
|
|
||||||
const Library& lib = Library::Handle(Z, Library::GetLibrary(library_id));
|
|
||||||
if (lib.IsNull()) {
|
|
||||||
return Api::NewError("%s: %" Pd " is not a valid library id", CURRENT_FUNC,
|
|
||||||
library_id);
|
|
||||||
}
|
|
||||||
return Api::NewHandle(T, lib.raw());
|
|
||||||
}
|
|
||||||
|
|
||||||
DART_EXPORT Dart_Handle Dart_LibraryId(Dart_Handle library,
|
DART_EXPORT Dart_Handle Dart_LibraryId(Dart_Handle library,
|
||||||
intptr_t* library_id) {
|
intptr_t* library_id) {
|
||||||
DARTSCOPE(Thread::Current());
|
DARTSCOPE(Thread::Current());
|
||||||
|
@ -351,12 +245,6 @@ DART_EXPORT Dart_Handle Dart_SetLibraryDebuggable(intptr_t library_id,
|
||||||
return Api::Success();
|
return Api::Success();
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
DART_EXPORT void Dart_SetPausedEventHandler(Dart_PausedEventHandler handler) {
|
|
||||||
// NOOP.
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // !PRODUCT
|
#endif // !PRODUCT
|
||||||
|
|
||||||
} // namespace dart
|
} // namespace dart
|
||||||
|
|
|
@ -62,16 +62,6 @@ typedef void Dart_BreakpointResolvedHandler(Dart_IsolateId isolate_id,
|
||||||
intptr_t bp_id,
|
intptr_t bp_id,
|
||||||
const Dart_CodeLocation& location);
|
const Dart_CodeLocation& location);
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a list of ids (integers) of all the libraries loaded in the
|
|
||||||
* current isolate.
|
|
||||||
*
|
|
||||||
* Requires there to be a current isolate.
|
|
||||||
*
|
|
||||||
* \return A handle to a list of library ids.
|
|
||||||
*/
|
|
||||||
DART_EXPORT Dart_Handle Dart_GetLibraryIds();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the debugger can step into code of the given library.
|
* Returns true if the debugger can step into code of the given library.
|
||||||
*
|
*
|
||||||
|
@ -104,14 +94,6 @@ DART_EXPORT Dart_Handle Dart_SetLibraryDebuggable(intptr_t library_id,
|
||||||
DART_EXPORT Dart_Handle Dart_SetBreakpoint(Dart_Handle script_url,
|
DART_EXPORT Dart_Handle Dart_SetBreakpoint(Dart_Handle script_url,
|
||||||
intptr_t line_number);
|
intptr_t line_number);
|
||||||
|
|
||||||
/**
|
|
||||||
* Installs a handler callback function that gets called by the VM
|
|
||||||
* when a breakpoint location has been reached or when stepping.
|
|
||||||
*
|
|
||||||
* Requires there to be a current isolate.
|
|
||||||
*/
|
|
||||||
DART_EXPORT void Dart_SetPausedEventHandler(Dart_PausedEventHandler handler);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns in \trace the current stack trace, or NULL if the
|
* Returns in \trace the current stack trace, or NULL if the
|
||||||
* VM is not paused.
|
* VM is not paused.
|
||||||
|
@ -191,15 +173,6 @@ Dart_ActivationFrameInfo(Dart_ActivationFrame activation_frame,
|
||||||
DART_EXPORT Dart_Handle Dart_EvaluateStaticExpr(Dart_Handle lib_handle,
|
DART_EXPORT Dart_Handle Dart_EvaluateStaticExpr(Dart_Handle lib_handle,
|
||||||
Dart_Handle expr);
|
Dart_Handle expr);
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a handle to the library \library_id.
|
|
||||||
*
|
|
||||||
* Requires there to be a current isolate.
|
|
||||||
*
|
|
||||||
* \return A library handle if the id is valid.
|
|
||||||
*/
|
|
||||||
DART_EXPORT Dart_Handle Dart_GetLibraryFromId(intptr_t library_id);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns in \library_id the library id of the given \library.
|
* Returns in \library_id the library id of the given \library.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1124,8 +1124,7 @@ Isolate* Isolate::InitIsolate(const char* name_prefix,
|
||||||
|
|
||||||
result->BuildName(name_prefix);
|
result->BuildName(name_prefix);
|
||||||
#if !defined(PRODUCT)
|
#if !defined(PRODUCT)
|
||||||
result->debugger_ = new Debugger();
|
result->debugger_ = new Debugger(result);
|
||||||
result->debugger_->Initialize(result);
|
|
||||||
#endif
|
#endif
|
||||||
if (FLAG_trace_isolates) {
|
if (FLAG_trace_isolates) {
|
||||||
if (name_prefix == NULL || strcmp(name_prefix, "vm-isolate") != 0) {
|
if (name_prefix == NULL || strcmp(name_prefix, "vm-isolate") != 0) {
|
||||||
|
|
Loading…
Reference in a new issue