mirror of
https://github.com/dart-lang/sdk
synced 2024-09-20 03:51:33 +00:00
Reapply "Per-closure breakpoints; restructure breakpoint implementation to keep a list of conditions."
Fix copying breakpoints over to a new location when a latent location is resolved. Fix bad assumption that BreakpointLocationAtLine always returns non-null result. Review URL: https://codereview.chromium.org//1149983003
This commit is contained in:
parent
dfee2bf45d
commit
74dfae69e3
|
@ -1206,6 +1206,11 @@ class Isolate extends ServiceObjectOwner with Coverage {
|
||||||
{ 'functionId': function.id });
|
{ 'functionId': function.id });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<ServiceObject> addBreakOnActivation(Instance closure) {
|
||||||
|
return invokeRpc('_addBreakpointAtActivation',
|
||||||
|
{ 'objectId': closure.id });
|
||||||
|
}
|
||||||
|
|
||||||
Future removeBreakpoint(Breakpoint bpt) {
|
Future removeBreakpoint(Breakpoint bpt) {
|
||||||
return invokeRpc('removeBreakpoint',
|
return invokeRpc('removeBreakpoint',
|
||||||
{ 'breakpointId': bpt.id });
|
{ 'breakpointId': bpt.id });
|
||||||
|
|
191
runtime/observatory/tests/service/break_on_activation_test.dart
Normal file
191
runtime/observatory/tests/service/break_on_activation_test.dart
Normal file
|
@ -0,0 +1,191 @@
|
||||||
|
// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
|
||||||
|
// for details. All rights reserved. Use of this source code is governed by a
|
||||||
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
// VMOptions=--compile-all --error_on_bad_type --error_on_bad_override
|
||||||
|
|
||||||
|
import 'package:observatory/service_io.dart';
|
||||||
|
import 'package:unittest/unittest.dart';
|
||||||
|
import 'test_helper.dart';
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
genRepeater(value) {
|
||||||
|
return () => print(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
genRepeaterNamed(value) {
|
||||||
|
return ({x, y}) => print(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
var r1;
|
||||||
|
var r2;
|
||||||
|
var r3;
|
||||||
|
|
||||||
|
var r1_named;
|
||||||
|
var r2_named;
|
||||||
|
var r3_named;
|
||||||
|
|
||||||
|
void testeeSetup() {
|
||||||
|
// These closures have the same function.
|
||||||
|
r1 = genRepeater('r1');
|
||||||
|
r2 = genRepeater('r2');
|
||||||
|
r3 = genRepeater('r3');
|
||||||
|
|
||||||
|
// These closures have the same function.
|
||||||
|
r1_named = genRepeaterNamed('r1_named');
|
||||||
|
r2_named = genRepeaterNamed('r2_named');
|
||||||
|
r3_named = genRepeaterNamed('r3_named');
|
||||||
|
}
|
||||||
|
|
||||||
|
void testeeDo() {
|
||||||
|
r1();
|
||||||
|
r2();
|
||||||
|
r3();
|
||||||
|
}
|
||||||
|
|
||||||
|
void testeeDoNamed() {
|
||||||
|
r1_named(y: 'Not a closure', x: 'Not a closure');
|
||||||
|
r2_named(y: 'Not a closure', x: 'Not a closure');
|
||||||
|
r3_named(y: 'Not a closure', x: 'Not a closure');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var tests = [
|
||||||
|
(Isolate isolate) async {
|
||||||
|
var rootLib = await isolate.rootLibrary.load();
|
||||||
|
|
||||||
|
var breaksHit = 0;
|
||||||
|
|
||||||
|
var subscription;
|
||||||
|
subscription = isolate.vm.events.stream.listen((ServiceEvent event) {
|
||||||
|
if (event.eventType == ServiceEvent.kPauseBreakpoint) {
|
||||||
|
print("Hit breakpoint ${event.breakpoint}");
|
||||||
|
breaksHit++;
|
||||||
|
isolate.resume();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
valueOfField(String name) {
|
||||||
|
return rootLib.variables.singleWhere((v) => v.name == name).value;
|
||||||
|
}
|
||||||
|
var r1Ref = valueOfField('r1');
|
||||||
|
var r2Ref = valueOfField('r2');
|
||||||
|
var r3Ref = valueOfField('r3');
|
||||||
|
|
||||||
|
var bpt1 = await isolate.addBreakOnActivation(r1Ref);
|
||||||
|
print("Added breakpoint $bpt1");
|
||||||
|
expect(bpt1 is Breakpoint, isTrue);
|
||||||
|
expect(breaksHit, equals(0));
|
||||||
|
print("testeeDo()");
|
||||||
|
var res = await rootLib.evaluate("testeeDo()");
|
||||||
|
expect(res is Instance, isTrue); // Not error.
|
||||||
|
expect(breaksHit, equals(1));
|
||||||
|
|
||||||
|
await isolate.removeBreakpoint(bpt1);
|
||||||
|
print("Removed breakpoint $bpt1");
|
||||||
|
print("testeeDo()");
|
||||||
|
res = await rootLib.evaluate("testeeDo()");
|
||||||
|
expect(res is Instance, isTrue); // Not error.
|
||||||
|
expect(breaksHit, equals(1));
|
||||||
|
|
||||||
|
await subscription.cancel();
|
||||||
|
},
|
||||||
|
|
||||||
|
(Isolate isolate) async {
|
||||||
|
var rootLib = await isolate.rootLibrary.load();
|
||||||
|
|
||||||
|
var breaksHit = 0;
|
||||||
|
|
||||||
|
var subscription;
|
||||||
|
subscription = isolate.vm.events.stream.listen((ServiceEvent event) {
|
||||||
|
if (event.eventType == ServiceEvent.kPauseBreakpoint) {
|
||||||
|
print("Hit breakpoint ${event.breakpoint}");
|
||||||
|
breaksHit++;
|
||||||
|
isolate.resume();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
valueOfField(String name) {
|
||||||
|
return rootLib.variables.singleWhere((v) => v.name == name).value;
|
||||||
|
}
|
||||||
|
var r1Ref = valueOfField('r1_named');
|
||||||
|
var r2Ref = valueOfField('r2_named');
|
||||||
|
var r3Ref = valueOfField('r3_named');
|
||||||
|
|
||||||
|
var bpt1 = await isolate.addBreakOnActivation(r1Ref);
|
||||||
|
print("Added breakpoint $bpt1");
|
||||||
|
expect(bpt1 is Breakpoint, isTrue);
|
||||||
|
expect(breaksHit, equals(0));
|
||||||
|
print("testeeDoNamed()");
|
||||||
|
var res = await rootLib.evaluate("testeeDoNamed()");
|
||||||
|
expect(res is Instance, isTrue); // Not error.
|
||||||
|
expect(breaksHit, equals(1));
|
||||||
|
|
||||||
|
await isolate.removeBreakpoint(bpt1);
|
||||||
|
print("Removed breakpoint $bpt1");
|
||||||
|
print("testeeDoNamed()");
|
||||||
|
res = await rootLib.evaluate("testeeDoNamed()");
|
||||||
|
expect(res is Instance, isTrue); // Not error.
|
||||||
|
expect(breaksHit, equals(1));
|
||||||
|
|
||||||
|
await subscription.cancel();
|
||||||
|
},
|
||||||
|
|
||||||
|
(Isolate isolate) async {
|
||||||
|
var rootLib = await isolate.rootLibrary.load();
|
||||||
|
|
||||||
|
var breaksHit = 0;
|
||||||
|
|
||||||
|
var subscription;
|
||||||
|
subscription = isolate.vm.events.stream.listen((ServiceEvent event) {
|
||||||
|
if (event.eventType == ServiceEvent.kPauseBreakpoint) {
|
||||||
|
print("Hit breakpoint ${event.breakpoint}");
|
||||||
|
breaksHit++;
|
||||||
|
isolate.resume();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
valueOfField(String name) {
|
||||||
|
return rootLib.variables.singleWhere((v) => v.name == name).value;
|
||||||
|
}
|
||||||
|
var r1Ref = valueOfField('r1');
|
||||||
|
var r2Ref = valueOfField('r2');
|
||||||
|
var r3Ref = valueOfField('r3');
|
||||||
|
|
||||||
|
var bpt1 = await isolate.addBreakOnActivation(r1Ref);
|
||||||
|
print("Added breakpoint $bpt1");
|
||||||
|
expect(bpt1 is Breakpoint, isTrue);
|
||||||
|
expect(breaksHit, equals(0));
|
||||||
|
print("testeeDo()");
|
||||||
|
var res = await rootLib.evaluate("testeeDo()");
|
||||||
|
expect(res is Instance, isTrue); // Not error.
|
||||||
|
expect(breaksHit, equals(1));
|
||||||
|
|
||||||
|
var bpt2 = await isolate.addBreakOnActivation(r2Ref);
|
||||||
|
print("Added breakpoint $bpt2");
|
||||||
|
expect(bpt2 is Breakpoint, isTrue);
|
||||||
|
expect(breaksHit, equals(1));
|
||||||
|
print("testeeDo()");
|
||||||
|
res = await rootLib.evaluate("testeeDo()");
|
||||||
|
expect(res is Instance, isTrue); // Not error.
|
||||||
|
expect(breaksHit, equals(3));
|
||||||
|
|
||||||
|
await isolate.removeBreakpoint(bpt1);
|
||||||
|
print("Removed breakpoint $bpt1");
|
||||||
|
print("testeeDo()");
|
||||||
|
res = await rootLib.evaluate("testeeDo()");
|
||||||
|
expect(res is Instance, isTrue); // Not error.
|
||||||
|
expect(breaksHit, equals(4));
|
||||||
|
|
||||||
|
await isolate.removeBreakpoint(bpt2);
|
||||||
|
print("Removed breakpoint $bpt2");
|
||||||
|
print("testeeDo()");
|
||||||
|
res = await rootLib.evaluate("testeeDo()");
|
||||||
|
expect(res is Instance, isTrue); // Not error.
|
||||||
|
expect(breaksHit, equals(4));
|
||||||
|
|
||||||
|
await subscription.cancel();
|
||||||
|
},
|
||||||
|
|
||||||
|
];
|
||||||
|
|
||||||
|
main(args) => runIsolateTests(args, tests, testeeBefore: testeeSetup);
|
|
@ -108,6 +108,9 @@ void runIsolateTests(List<String> mainArgs,
|
||||||
} else {
|
} else {
|
||||||
var process = new _TestLauncher();
|
var process = new _TestLauncher();
|
||||||
process.launch(pause_on_exit).then((port) {
|
process.launch(pause_on_exit).then((port) {
|
||||||
|
if (mainArgs.contains("--gdb")) {
|
||||||
|
port = 8181;
|
||||||
|
}
|
||||||
String addr = 'ws://localhost:$port/ws';
|
String addr = 'ws://localhost:$port/ws';
|
||||||
var testIndex = 1;
|
var testIndex = 1;
|
||||||
var totalTests = tests.length;
|
var totalTests = tests.length;
|
||||||
|
@ -192,6 +195,9 @@ Future runVMTests(List<String> mainArgs,
|
||||||
} else {
|
} else {
|
||||||
var process = new _TestLauncher();
|
var process = new _TestLauncher();
|
||||||
process.launch(pause_on_exit).then((port) async {
|
process.launch(pause_on_exit).then((port) async {
|
||||||
|
if (mainArgs.contains("--gdb")) {
|
||||||
|
port = 8181;
|
||||||
|
}
|
||||||
String addr = 'ws://localhost:$port/ws';
|
String addr = 'ws://localhost:$port/ws';
|
||||||
var testIndex = 1;
|
var testIndex = 1;
|
||||||
var totalTests = tests.length;
|
var totalTests = tests.length;
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -18,12 +18,74 @@ class JSONArray;
|
||||||
class JSONStream;
|
class JSONStream;
|
||||||
class ObjectPointerVisitor;
|
class ObjectPointerVisitor;
|
||||||
class RemoteObjectCache;
|
class RemoteObjectCache;
|
||||||
class SourceBreakpoint;
|
class BreakpointLocation;
|
||||||
class StackFrame;
|
class StackFrame;
|
||||||
|
|
||||||
// SourceBreakpoint represents a user-specified breakpoint location in
|
// A user-defined breakpoint, which either fires once, for a particular closure,
|
||||||
// Dart source. There may be more than one CodeBreakpoint object per
|
// or always. The API's notion of a breakpoint corresponds to this object.
|
||||||
// SourceBreakpoint.
|
class Breakpoint {
|
||||||
|
public:
|
||||||
|
Breakpoint(intptr_t id, BreakpointLocation* bpt_location)
|
||||||
|
: id_(id),
|
||||||
|
kind_(Breakpoint::kNone),
|
||||||
|
next_(NULL),
|
||||||
|
closure_(Instance::null()),
|
||||||
|
bpt_location_(bpt_location) {}
|
||||||
|
|
||||||
|
intptr_t id() const { return id_; }
|
||||||
|
Breakpoint* next() const { return next_; }
|
||||||
|
void set_next(Breakpoint* n) { next_ = n; }
|
||||||
|
|
||||||
|
BreakpointLocation* bpt_location() const { return bpt_location_; }
|
||||||
|
void set_bpt_location(BreakpointLocation* new_bpt_location);
|
||||||
|
|
||||||
|
bool IsRepeated() const { return kind_ == kRepeated; }
|
||||||
|
bool IsSingleShot() const { return kind_ == kSingleShot; }
|
||||||
|
bool IsPerClosure() const { return kind_ == kPerClosure; }
|
||||||
|
RawInstance* closure() const { return closure_; }
|
||||||
|
|
||||||
|
void SetIsRepeated() {
|
||||||
|
ASSERT(kind_ == kNone);
|
||||||
|
kind_ = kRepeated;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetIsSingleShot() {
|
||||||
|
ASSERT(kind_ == kNone);
|
||||||
|
kind_ = kSingleShot;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetIsPerClosure(const Instance& closure) {
|
||||||
|
ASSERT(kind_ == kNone);
|
||||||
|
kind_ = kPerClosure;
|
||||||
|
closure_ = closure.raw();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintJSON(JSONStream* stream);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void VisitObjectPointers(ObjectPointerVisitor* visitor);
|
||||||
|
|
||||||
|
enum ConditionKind {
|
||||||
|
kNone,
|
||||||
|
kRepeated,
|
||||||
|
kSingleShot,
|
||||||
|
kPerClosure,
|
||||||
|
};
|
||||||
|
|
||||||
|
intptr_t id_;
|
||||||
|
ConditionKind kind_;
|
||||||
|
Breakpoint* next_;
|
||||||
|
RawInstance* closure_;
|
||||||
|
BreakpointLocation* bpt_location_;
|
||||||
|
|
||||||
|
friend class BreakpointLocation;
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(Breakpoint);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// BreakpointLocation represents a collection of breakpoint conditions at the
|
||||||
|
// same token position in Dart source. There may be more than one CodeBreakpoint
|
||||||
|
// object per BreakpointLocation.
|
||||||
// An unresolved breakpoint is one where the underlying code has not
|
// An unresolved breakpoint is one where the underlying code has not
|
||||||
// been compiled yet. Since the code has not been compiled, we don't know
|
// been compiled yet. Since the code has not been compiled, we don't know
|
||||||
// the definitive source location yet. The requested source location may
|
// the definitive source location yet. The requested source location may
|
||||||
|
@ -32,22 +94,21 @@ class StackFrame;
|
||||||
// that is not loaded in the VM when the breakpoint is requested.
|
// that is not loaded in the VM when the breakpoint is requested.
|
||||||
// When a script with matching url is loaded, a latent breakpoint
|
// When a script with matching url is loaded, a latent breakpoint
|
||||||
// becomes an unresolved breakpoint.
|
// becomes an unresolved breakpoint.
|
||||||
class SourceBreakpoint {
|
class BreakpointLocation {
|
||||||
public:
|
public:
|
||||||
// Create a new unresolved breakpoint.
|
// Create a new unresolved breakpoint.
|
||||||
SourceBreakpoint(intptr_t id,
|
BreakpointLocation(const Script& script,
|
||||||
const Script& script,
|
intptr_t token_pos,
|
||||||
intptr_t token_pos,
|
intptr_t end_token_pos);
|
||||||
intptr_t end_token_pos);
|
|
||||||
// Create a new latent breakpoint.
|
// Create a new latent breakpoint.
|
||||||
SourceBreakpoint(intptr_t id,
|
BreakpointLocation(const String& url,
|
||||||
const String& url,
|
intptr_t line_number);
|
||||||
intptr_t line_number);
|
|
||||||
|
~BreakpointLocation();
|
||||||
|
|
||||||
RawFunction* function() const { return function_; }
|
RawFunction* function() const { return function_; }
|
||||||
intptr_t token_pos() const { return token_pos_; }
|
intptr_t token_pos() const { return token_pos_; }
|
||||||
intptr_t end_token_pos() const { return end_token_pos_; }
|
intptr_t end_token_pos() const { return end_token_pos_; }
|
||||||
intptr_t id() const { return id_; }
|
|
||||||
|
|
||||||
RawScript* script() const { return script_; }
|
RawScript* script() const { return script_; }
|
||||||
RawString* url() const { return url_; }
|
RawString* url() const { return url_; }
|
||||||
|
@ -55,45 +116,46 @@ class SourceBreakpoint {
|
||||||
|
|
||||||
void GetCodeLocation(Library* lib, Script* script, intptr_t* token_pos);
|
void GetCodeLocation(Library* lib, Script* script, intptr_t* token_pos);
|
||||||
|
|
||||||
void Enable();
|
Breakpoint* AddRepeated(Debugger* dbg);
|
||||||
void Disable();
|
Breakpoint* AddSingleShot(Debugger* dbg);
|
||||||
bool IsEnabled() const { return is_enabled_; }
|
Breakpoint* AddPerClosure(Debugger* dbg, const Instance& closure);
|
||||||
|
|
||||||
|
bool AnyEnabled() const;
|
||||||
bool IsResolved() const { return is_resolved_; }
|
bool IsResolved() const { return is_resolved_; }
|
||||||
bool IsLatent() const { return token_pos_ < 0; }
|
bool IsLatent() const { return token_pos_ < 0; }
|
||||||
|
|
||||||
bool IsOneShot() const { return is_one_shot_; }
|
|
||||||
void SetIsOneShot() { is_one_shot_ = true; }
|
|
||||||
|
|
||||||
void PrintJSON(JSONStream* stream);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void VisitObjectPointers(ObjectPointerVisitor* visitor);
|
void VisitObjectPointers(ObjectPointerVisitor* visitor);
|
||||||
|
|
||||||
void SetResolved(const Function& func, intptr_t token_pos);
|
void SetResolved(const Function& func, intptr_t token_pos);
|
||||||
void set_next(SourceBreakpoint* value) { next_ = value; }
|
|
||||||
SourceBreakpoint* next() const { return this->next_; }
|
|
||||||
|
|
||||||
const intptr_t id_;
|
BreakpointLocation* next() const { return this->next_; }
|
||||||
|
void set_next(BreakpointLocation* value) { next_ = value; }
|
||||||
|
|
||||||
|
void AddBreakpoint(Breakpoint* bpt, Debugger* dbg);
|
||||||
|
|
||||||
|
Breakpoint* breakpoints() const { return this->conditions_; }
|
||||||
|
void set_breakpoints(Breakpoint* head) { this->conditions_ = head; }
|
||||||
|
|
||||||
RawScript* script_;
|
RawScript* script_;
|
||||||
RawString* url_;
|
RawString* url_;
|
||||||
intptr_t token_pos_;
|
intptr_t token_pos_;
|
||||||
intptr_t end_token_pos_;
|
intptr_t end_token_pos_;
|
||||||
bool is_resolved_;
|
bool is_resolved_;
|
||||||
bool is_enabled_;
|
BreakpointLocation* next_;
|
||||||
bool is_one_shot_;
|
Breakpoint* conditions_;
|
||||||
SourceBreakpoint* next_;
|
|
||||||
|
|
||||||
// Valid for resolved breakpoints:
|
// Valid for resolved breakpoints:
|
||||||
RawFunction* function_;
|
RawFunction* function_;
|
||||||
intptr_t line_number_;
|
intptr_t line_number_;
|
||||||
|
|
||||||
friend class Debugger;
|
friend class Debugger;
|
||||||
DISALLOW_COPY_AND_ASSIGN(SourceBreakpoint);
|
DISALLOW_COPY_AND_ASSIGN(BreakpointLocation);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// CodeBreakpoint represents a location in compiled code. There may be
|
// CodeBreakpoint represents a location in compiled code. There may be
|
||||||
// more than one CodeBreakpoint for one SourceBreakpoint, e.g. when a
|
// more than one CodeBreakpoint for one BreakpointLocation, e.g. when a
|
||||||
// function gets compiled as a regular function and as a closure.
|
// function gets compiled as a regular function and as a closure.
|
||||||
class CodeBreakpoint {
|
class CodeBreakpoint {
|
||||||
public:
|
public:
|
||||||
|
@ -106,7 +168,7 @@ class CodeBreakpoint {
|
||||||
RawFunction* function() const;
|
RawFunction* function() const;
|
||||||
uword pc() const { return pc_; }
|
uword pc() const { return pc_; }
|
||||||
intptr_t token_pos() const { return token_pos_; }
|
intptr_t token_pos() const { return token_pos_; }
|
||||||
bool IsInternal() const { return src_bpt_ == NULL; }
|
bool IsInternal() const { return bpt_location_ == NULL; }
|
||||||
|
|
||||||
RawScript* SourceCode();
|
RawScript* SourceCode();
|
||||||
RawString* SourceUrl();
|
RawString* SourceUrl();
|
||||||
|
@ -121,8 +183,8 @@ class CodeBreakpoint {
|
||||||
private:
|
private:
|
||||||
void VisitObjectPointers(ObjectPointerVisitor* visitor);
|
void VisitObjectPointers(ObjectPointerVisitor* visitor);
|
||||||
|
|
||||||
SourceBreakpoint* src_bpt() const { return src_bpt_; }
|
BreakpointLocation* bpt_location() const { return bpt_location_; }
|
||||||
void set_src_bpt(SourceBreakpoint* value) { src_bpt_ = value; }
|
void set_bpt_location(BreakpointLocation* value) { bpt_location_ = value; }
|
||||||
|
|
||||||
void set_next(CodeBreakpoint* value) { next_ = value; }
|
void set_next(CodeBreakpoint* value) { next_ = value; }
|
||||||
CodeBreakpoint* next() const { return this->next_; }
|
CodeBreakpoint* next() const { return this->next_; }
|
||||||
|
@ -136,7 +198,7 @@ class CodeBreakpoint {
|
||||||
intptr_t line_number_;
|
intptr_t line_number_;
|
||||||
bool is_enabled_;
|
bool is_enabled_;
|
||||||
|
|
||||||
SourceBreakpoint* src_bpt_;
|
BreakpointLocation* bpt_location_;
|
||||||
CodeBreakpoint* next_;
|
CodeBreakpoint* next_;
|
||||||
|
|
||||||
RawPcDescriptors::Kind breakpoint_kind_;
|
RawPcDescriptors::Kind breakpoint_kind_;
|
||||||
|
@ -194,6 +256,8 @@ class ActivationFrame : public ZoneAllocated {
|
||||||
Object* value);
|
Object* value);
|
||||||
|
|
||||||
RawArray* GetLocalVariables();
|
RawArray* GetLocalVariables();
|
||||||
|
RawObject* GetParameter(intptr_t index);
|
||||||
|
RawObject* GetClosure();
|
||||||
RawObject* GetReceiver();
|
RawObject* GetReceiver();
|
||||||
|
|
||||||
const Context& GetSavedCurrentContext();
|
const Context& GetSavedCurrentContext();
|
||||||
|
@ -273,11 +337,6 @@ class DebuggerStackTrace : public ZoneAllocated {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
typedef void BreakpointHandler(Dart_Port isolate_id,
|
|
||||||
SourceBreakpoint* bpt,
|
|
||||||
DebuggerStackTrace* stack);
|
|
||||||
|
|
||||||
|
|
||||||
class DebuggerEvent {
|
class DebuggerEvent {
|
||||||
public:
|
public:
|
||||||
enum EventType {
|
enum EventType {
|
||||||
|
@ -315,11 +374,11 @@ class DebuggerEvent {
|
||||||
top_frame_ = frame;
|
top_frame_ = frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
SourceBreakpoint* breakpoint() const {
|
Breakpoint* breakpoint() const {
|
||||||
ASSERT(type_ == kBreakpointReached || type_ == kBreakpointResolved);
|
ASSERT(type_ == kBreakpointReached || type_ == kBreakpointResolved);
|
||||||
return breakpoint_;
|
return breakpoint_;
|
||||||
}
|
}
|
||||||
void set_breakpoint(SourceBreakpoint* bpt) {
|
void set_breakpoint(Breakpoint* bpt) {
|
||||||
ASSERT(type_ == kBreakpointReached || type_ == kBreakpointResolved);
|
ASSERT(type_ == kBreakpointReached || type_ == kBreakpointResolved);
|
||||||
breakpoint_ = bpt;
|
breakpoint_ = bpt;
|
||||||
}
|
}
|
||||||
|
@ -341,7 +400,7 @@ class DebuggerEvent {
|
||||||
Isolate* isolate_;
|
Isolate* isolate_;
|
||||||
EventType type_;
|
EventType type_;
|
||||||
ActivationFrame* top_frame_;
|
ActivationFrame* top_frame_;
|
||||||
SourceBreakpoint* breakpoint_;
|
Breakpoint* breakpoint_;
|
||||||
const Object* exception_;
|
const Object* exception_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -365,15 +424,21 @@ class Debugger {
|
||||||
const String& function_name);
|
const String& function_name);
|
||||||
|
|
||||||
// Set breakpoint at closest location to function entry.
|
// Set breakpoint at closest location to function entry.
|
||||||
SourceBreakpoint* SetBreakpointAtEntry(const Function& target_function);
|
Breakpoint* SetBreakpointAtEntry(const Function& target_function,
|
||||||
|
bool single_shot);
|
||||||
|
Breakpoint* SetBreakpointAtActivation(const Instance& closure);
|
||||||
|
|
||||||
// TODO(turnidge): script_url may no longer be specific enough.
|
// TODO(turnidge): script_url may no longer be specific enough.
|
||||||
SourceBreakpoint* SetBreakpointAtLine(const String& script_url,
|
Breakpoint* SetBreakpointAtLine(const String& script_url,
|
||||||
intptr_t line_number);
|
intptr_t line_number);
|
||||||
RawError* OneTimeBreakAtEntry(const Function& target_function);
|
RawError* OneTimeBreakAtEntry(const Function& target_function);
|
||||||
|
|
||||||
|
BreakpointLocation* BreakpointLocationAtLine(const String& script_url,
|
||||||
|
intptr_t line_number);
|
||||||
|
|
||||||
|
|
||||||
void RemoveBreakpoint(intptr_t bp_id);
|
void RemoveBreakpoint(intptr_t bp_id);
|
||||||
SourceBreakpoint* GetBreakpointById(intptr_t id);
|
Breakpoint* GetBreakpointById(intptr_t id);
|
||||||
|
|
||||||
void SetStepOver();
|
void SetStepOver();
|
||||||
void SetSingleStep();
|
void SetSingleStep();
|
||||||
|
@ -476,22 +541,22 @@ class Debugger {
|
||||||
intptr_t requested_token_pos,
|
intptr_t requested_token_pos,
|
||||||
intptr_t last_token_pos);
|
intptr_t last_token_pos);
|
||||||
void DeoptimizeWorld();
|
void DeoptimizeWorld();
|
||||||
SourceBreakpoint* SetBreakpoint(const Script& script,
|
BreakpointLocation* SetBreakpoint(const Script& script,
|
||||||
intptr_t token_pos,
|
intptr_t token_pos,
|
||||||
intptr_t last_token_pos);
|
intptr_t last_token_pos);
|
||||||
void RemoveInternalBreakpoints();
|
void RemoveInternalBreakpoints();
|
||||||
void UnlinkCodeBreakpoints(SourceBreakpoint* src_bpt);
|
void UnlinkCodeBreakpoints(BreakpointLocation* bpt_location);
|
||||||
SourceBreakpoint* GetLatentBreakpoint(const String& url, intptr_t line);
|
BreakpointLocation* GetLatentBreakpoint(const String& url, intptr_t line);
|
||||||
void RegisterSourceBreakpoint(SourceBreakpoint* bpt);
|
void RegisterBreakpointLocation(BreakpointLocation* bpt);
|
||||||
void RegisterCodeBreakpoint(CodeBreakpoint* bpt);
|
void RegisterCodeBreakpoint(CodeBreakpoint* bpt);
|
||||||
SourceBreakpoint* GetSourceBreakpoint(const Script& script,
|
BreakpointLocation* GetBreakpointLocation(const Script& script,
|
||||||
intptr_t token_pos);
|
intptr_t token_pos);
|
||||||
void MakeCodeBreakpointAt(const Function& func,
|
void MakeCodeBreakpointAt(const Function& func,
|
||||||
SourceBreakpoint* bpt);
|
BreakpointLocation* bpt);
|
||||||
// Returns NULL if no breakpoint exists for the given address.
|
// Returns NULL if no breakpoint exists for the given address.
|
||||||
CodeBreakpoint* GetCodeBreakpoint(uword breakpoint_address);
|
CodeBreakpoint* GetCodeBreakpoint(uword breakpoint_address);
|
||||||
|
|
||||||
void SyncBreakpoint(SourceBreakpoint* bpt);
|
void SyncBreakpointLocation(BreakpointLocation* loc);
|
||||||
|
|
||||||
ActivationFrame* TopDartFrame() const;
|
ActivationFrame* TopDartFrame() const;
|
||||||
static ActivationFrame* CollectDartFrame(Isolate* isolate,
|
static ActivationFrame* CollectDartFrame(Isolate* isolate,
|
||||||
|
@ -504,9 +569,9 @@ class Debugger {
|
||||||
StackFrame* frame,
|
StackFrame* frame,
|
||||||
const Code& code);
|
const Code& code);
|
||||||
static DebuggerStackTrace* CollectStackTrace();
|
static DebuggerStackTrace* CollectStackTrace();
|
||||||
void SignalBpResolved(SourceBreakpoint *bpt);
|
void SignalBpResolved(Breakpoint *bpt);
|
||||||
void SignalPausedEvent(ActivationFrame* top_frame,
|
void SignalPausedEvent(ActivationFrame* top_frame,
|
||||||
SourceBreakpoint* bpt);
|
Breakpoint* bpt);
|
||||||
|
|
||||||
intptr_t nextId() { return next_id_++; }
|
intptr_t nextId() { return next_id_++; }
|
||||||
|
|
||||||
|
@ -531,8 +596,8 @@ class Debugger {
|
||||||
// ID number generator.
|
// ID number generator.
|
||||||
intptr_t next_id_;
|
intptr_t next_id_;
|
||||||
|
|
||||||
SourceBreakpoint* latent_breakpoints_;
|
BreakpointLocation* latent_locations_;
|
||||||
SourceBreakpoint* src_breakpoints_;
|
BreakpointLocation* breakpoint_locations_;
|
||||||
CodeBreakpoint* code_breakpoints_;
|
CodeBreakpoint* code_breakpoints_;
|
||||||
|
|
||||||
// Tells debugger what to do when resuming execution after a breakpoint.
|
// Tells debugger what to do when resuming execution after a breakpoint.
|
||||||
|
@ -565,7 +630,7 @@ class Debugger {
|
||||||
static EventHandler* event_handler_;
|
static EventHandler* event_handler_;
|
||||||
|
|
||||||
friend class Isolate;
|
friend class Isolate;
|
||||||
friend class SourceBreakpoint;
|
friend class BreakpointLocation;
|
||||||
DISALLOW_COPY_AND_ASSIGN(Debugger);
|
DISALLOW_COPY_AND_ASSIGN(Debugger);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -130,13 +130,13 @@ static void DebuggerEventHandler(DebuggerEvent* event) {
|
||||||
}
|
}
|
||||||
} else if (event->type() == DebuggerEvent::kBreakpointResolved) {
|
} else if (event->type() == DebuggerEvent::kBreakpointResolved) {
|
||||||
if (bp_resolved_handler != NULL) {
|
if (bp_resolved_handler != NULL) {
|
||||||
SourceBreakpoint* bpt = event->breakpoint();
|
Breakpoint* bpt = event->breakpoint();
|
||||||
ASSERT(bpt != NULL);
|
ASSERT(bpt != NULL);
|
||||||
Dart_CodeLocation location;
|
Dart_CodeLocation location;
|
||||||
Library& library = Library::Handle(isolate);
|
Library& library = Library::Handle(isolate);
|
||||||
Script& script = Script::Handle(isolate);
|
Script& script = Script::Handle(isolate);
|
||||||
intptr_t token_pos;
|
intptr_t token_pos;
|
||||||
bpt->GetCodeLocation(&library, &script, &token_pos);
|
bpt->bpt_location()->GetCodeLocation(&library, &script, &token_pos);
|
||||||
location.script_url = Api::NewHandle(isolate, script.url());
|
location.script_url = Api::NewHandle(isolate, script.url());
|
||||||
location.library_id = library.index();
|
location.library_id = library.index();
|
||||||
location.token_pos = token_pos;
|
location.token_pos = token_pos;
|
||||||
|
@ -341,7 +341,7 @@ DART_EXPORT Dart_Handle Dart_SetBreakpoint(
|
||||||
|
|
||||||
Debugger* debugger = isolate->debugger();
|
Debugger* debugger = isolate->debugger();
|
||||||
ASSERT(debugger != NULL);
|
ASSERT(debugger != NULL);
|
||||||
SourceBreakpoint* bpt =
|
Breakpoint* bpt =
|
||||||
debugger->SetBreakpointAtLine(script_url, line_number);
|
debugger->SetBreakpointAtLine(script_url, line_number);
|
||||||
if (bpt == NULL) {
|
if (bpt == NULL) {
|
||||||
return Api::NewError("%s: could not set breakpoint at line %" Pd " in '%s'",
|
return Api::NewError("%s: could not set breakpoint at line %" Pd " in '%s'",
|
||||||
|
@ -357,12 +357,12 @@ DART_EXPORT Dart_Handle Dart_GetBreakpointURL(intptr_t bp_id) {
|
||||||
Debugger* debugger = isolate->debugger();
|
Debugger* debugger = isolate->debugger();
|
||||||
ASSERT(debugger != NULL);
|
ASSERT(debugger != NULL);
|
||||||
|
|
||||||
SourceBreakpoint* bpt = debugger->GetBreakpointById(bp_id);
|
Breakpoint* bpt = debugger->GetBreakpointById(bp_id);
|
||||||
if (bpt == NULL) {
|
if (bpt == NULL) {
|
||||||
return Api::NewError("%s: breakpoint with id %" Pd " does not exist",
|
return Api::NewError("%s: breakpoint with id %" Pd " does not exist",
|
||||||
CURRENT_FUNC, bp_id);
|
CURRENT_FUNC, bp_id);
|
||||||
}
|
}
|
||||||
return Api::NewHandle(isolate, bpt->url());
|
return Api::NewHandle(isolate, bpt->bpt_location()->url());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -372,12 +372,12 @@ DART_EXPORT Dart_Handle Dart_GetBreakpointLine(intptr_t bp_id) {
|
||||||
Debugger* debugger = isolate->debugger();
|
Debugger* debugger = isolate->debugger();
|
||||||
ASSERT(debugger != NULL);
|
ASSERT(debugger != NULL);
|
||||||
|
|
||||||
SourceBreakpoint* bpt = debugger->GetBreakpointById(bp_id);
|
Breakpoint* bpt = debugger->GetBreakpointById(bp_id);
|
||||||
if (bpt == NULL) {
|
if (bpt == NULL) {
|
||||||
return Api::NewError("%s: breakpoint with id %" Pd " does not exist",
|
return Api::NewError("%s: breakpoint with id %" Pd " does not exist",
|
||||||
CURRENT_FUNC, bp_id);
|
CURRENT_FUNC, bp_id);
|
||||||
}
|
}
|
||||||
return Dart_NewInteger(bpt->LineNumber());
|
return Dart_NewInteger(bpt->bpt_location()->LineNumber());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -411,7 +411,7 @@ DART_EXPORT Dart_Handle Dart_SetBreakpointAtEntry(
|
||||||
function_name.ToCString());
|
function_name.ToCString());
|
||||||
}
|
}
|
||||||
|
|
||||||
SourceBreakpoint* bpt = debugger->SetBreakpointAtEntry(bp_target);
|
Breakpoint* bpt = debugger->SetBreakpointAtEntry(bp_target, false);
|
||||||
if (bpt == NULL) {
|
if (bpt == NULL) {
|
||||||
const char* target_name = Debugger::QualifiedFunctionName(bp_target);
|
const char* target_name = Debugger::QualifiedFunctionName(bp_target);
|
||||||
return Api::NewError("%s: no breakpoint location found in '%s'",
|
return Api::NewError("%s: no breakpoint location found in '%s'",
|
||||||
|
|
|
@ -327,7 +327,7 @@ void JSONStream::PrintValue(const Object& o, bool ref) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void JSONStream::PrintValue(SourceBreakpoint* bpt) {
|
void JSONStream::PrintValue(Breakpoint* bpt) {
|
||||||
PrintCommaIfNeeded();
|
PrintCommaIfNeeded();
|
||||||
bpt->PrintJSON(this);
|
bpt->PrintJSON(this);
|
||||||
}
|
}
|
||||||
|
@ -415,7 +415,7 @@ void JSONStream::PrintProperty(const char* name, const ServiceEvent* event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void JSONStream::PrintProperty(const char* name, SourceBreakpoint* bpt) {
|
void JSONStream::PrintProperty(const char* name, Breakpoint* bpt) {
|
||||||
PrintPropertyName(name);
|
PrintPropertyName(name);
|
||||||
PrintValue(bpt);
|
PrintValue(bpt);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ class MessageQueue;
|
||||||
class Metric;
|
class Metric;
|
||||||
class Object;
|
class Object;
|
||||||
class ServiceEvent;
|
class ServiceEvent;
|
||||||
class SourceBreakpoint;
|
class Breakpoint;
|
||||||
class String;
|
class String;
|
||||||
class Zone;
|
class Zone;
|
||||||
|
|
||||||
|
@ -115,7 +115,7 @@ class JSONStream : ValueObject {
|
||||||
void PrintValueNoEscape(const char* s);
|
void PrintValueNoEscape(const char* s);
|
||||||
void PrintfValue(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
|
void PrintfValue(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
|
||||||
void PrintValue(const Object& o, bool ref = true);
|
void PrintValue(const Object& o, bool ref = true);
|
||||||
void PrintValue(SourceBreakpoint* bpt);
|
void PrintValue(Breakpoint* bpt);
|
||||||
void PrintValue(const ServiceEvent* event);
|
void PrintValue(const ServiceEvent* event);
|
||||||
void PrintValue(Metric* metric);
|
void PrintValue(Metric* metric);
|
||||||
void PrintValue(MessageQueue* queue);
|
void PrintValue(MessageQueue* queue);
|
||||||
|
@ -135,7 +135,7 @@ class JSONStream : ValueObject {
|
||||||
void PrintProperty(const char* name, const Object& o, bool ref = true);
|
void PrintProperty(const char* name, const Object& o, bool ref = true);
|
||||||
|
|
||||||
void PrintProperty(const char* name, const ServiceEvent* event);
|
void PrintProperty(const char* name, const ServiceEvent* event);
|
||||||
void PrintProperty(const char* name, SourceBreakpoint* bpt);
|
void PrintProperty(const char* name, Breakpoint* bpt);
|
||||||
void PrintProperty(const char* name, Metric* metric);
|
void PrintProperty(const char* name, Metric* metric);
|
||||||
void PrintProperty(const char* name, MessageQueue* queue);
|
void PrintProperty(const char* name, MessageQueue* queue);
|
||||||
void PrintProperty(const char* name, Isolate* isolate);
|
void PrintProperty(const char* name, Isolate* isolate);
|
||||||
|
@ -216,7 +216,7 @@ class JSONObject : public ValueObject {
|
||||||
void AddProperty(const char* name, const ServiceEvent* event) const {
|
void AddProperty(const char* name, const ServiceEvent* event) const {
|
||||||
stream_->PrintProperty(name, event);
|
stream_->PrintProperty(name, event);
|
||||||
}
|
}
|
||||||
void AddProperty(const char* name, SourceBreakpoint* bpt) const {
|
void AddProperty(const char* name, Breakpoint* bpt) const {
|
||||||
stream_->PrintProperty(name, bpt);
|
stream_->PrintProperty(name, bpt);
|
||||||
}
|
}
|
||||||
void AddProperty(const char* name, Metric* metric) const {
|
void AddProperty(const char* name, Metric* metric) const {
|
||||||
|
@ -267,7 +267,7 @@ class JSONArray : public ValueObject {
|
||||||
void AddValue(Isolate* isolate, bool ref = true) const {
|
void AddValue(Isolate* isolate, bool ref = true) const {
|
||||||
stream_->PrintValue(isolate, ref);
|
stream_->PrintValue(isolate, ref);
|
||||||
}
|
}
|
||||||
void AddValue(SourceBreakpoint* bpt) const {
|
void AddValue(Breakpoint* bpt) const {
|
||||||
stream_->PrintValue(bpt);
|
stream_->PrintValue(bpt);
|
||||||
}
|
}
|
||||||
void AddValue(const ServiceEvent* event) const {
|
void AddValue(const ServiceEvent* event) const {
|
||||||
|
|
|
@ -4182,7 +4182,7 @@ TEST_CASE(FunctionWithBreakpointNotInlined) {
|
||||||
EXPECT(func_b.CanBeInlined());
|
EXPECT(func_b.CanBeInlined());
|
||||||
|
|
||||||
// After setting a breakpoint in a function A.b, it is no longer inlineable.
|
// After setting a breakpoint in a function A.b, it is no longer inlineable.
|
||||||
SourceBreakpoint* bpt =
|
Breakpoint* bpt =
|
||||||
Isolate::Current()->debugger()->SetBreakpointAtLine(name,
|
Isolate::Current()->debugger()->SetBreakpointAtLine(name,
|
||||||
kBreakpointLine);
|
kBreakpointLine);
|
||||||
ASSERT(bpt != NULL);
|
ASSERT(bpt != NULL);
|
||||||
|
|
|
@ -1196,7 +1196,7 @@ static void PrintSentinel(JSONStream* js, SentinelType sentinel_type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static SourceBreakpoint* LookupBreakpoint(Isolate* isolate, const char* id) {
|
static Breakpoint* LookupBreakpoint(Isolate* isolate, const char* id) {
|
||||||
size_t end_pos = strcspn(id, "/");
|
size_t end_pos = strcspn(id, "/");
|
||||||
if (end_pos == strlen(id)) {
|
if (end_pos == strlen(id)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1204,7 +1204,7 @@ static SourceBreakpoint* LookupBreakpoint(Isolate* isolate, const char* id) {
|
||||||
const char* rest = id + end_pos + 1; // +1 for '/'.
|
const char* rest = id + end_pos + 1; // +1 for '/'.
|
||||||
if (strncmp("breakpoints", id, end_pos) == 0) {
|
if (strncmp("breakpoints", id, end_pos) == 0) {
|
||||||
intptr_t bpt_id = 0;
|
intptr_t bpt_id = 0;
|
||||||
SourceBreakpoint* bpt = NULL;
|
Breakpoint* bpt = NULL;
|
||||||
if (GetIntegerId(rest, &bpt_id)) {
|
if (GetIntegerId(rest, &bpt_id)) {
|
||||||
bpt = isolate->debugger()->GetBreakpointById(bpt_id);
|
bpt = isolate->debugger()->GetBreakpointById(bpt_id);
|
||||||
}
|
}
|
||||||
|
@ -1808,7 +1808,7 @@ static bool AddBreakpoint(Isolate* isolate, JSONStream* js) {
|
||||||
}
|
}
|
||||||
const Script& script = Script::Cast(obj);
|
const Script& script = Script::Cast(obj);
|
||||||
const String& script_url = String::Handle(script.url());
|
const String& script_url = String::Handle(script.url());
|
||||||
SourceBreakpoint* bpt =
|
Breakpoint* bpt =
|
||||||
isolate->debugger()->SetBreakpointAtLine(script_url, line);
|
isolate->debugger()->SetBreakpointAtLine(script_url, line);
|
||||||
if (bpt == NULL) {
|
if (bpt == NULL) {
|
||||||
js->PrintError(kNoBreakAtLine, NULL);
|
js->PrintError(kNoBreakAtLine, NULL);
|
||||||
|
@ -1834,8 +1834,34 @@ static bool AddBreakpointAtEntry(Isolate* isolate, JSONStream* js) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
const Function& function = Function::Cast(obj);
|
const Function& function = Function::Cast(obj);
|
||||||
SourceBreakpoint* bpt =
|
Breakpoint* bpt =
|
||||||
isolate->debugger()->SetBreakpointAtEntry(function);
|
isolate->debugger()->SetBreakpointAtEntry(function, false);
|
||||||
|
if (bpt == NULL) {
|
||||||
|
js->PrintError(kNoBreakAtFunction, NULL);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bpt->PrintJSON(js);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const MethodParameter* add_breakpoint_at_activation_params[] = {
|
||||||
|
ISOLATE_PARAMETER,
|
||||||
|
new IdParameter("objectId", true),
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static bool AddBreakpointAtActivation(Isolate* isolate, JSONStream* js) {
|
||||||
|
const char* object_id = js->LookupParam("objectId");
|
||||||
|
Object& obj = Object::Handle(LookupHeapObject(isolate, object_id, NULL));
|
||||||
|
if (obj.raw() == Object::sentinel().raw() || !obj.IsInstance()) {
|
||||||
|
PrintInvalidParamError(js, "objectId");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const Instance& closure = Instance::Cast(obj);
|
||||||
|
Breakpoint* bpt =
|
||||||
|
isolate->debugger()->SetBreakpointAtActivation(closure);
|
||||||
if (bpt == NULL) {
|
if (bpt == NULL) {
|
||||||
js->PrintError(kNoBreakAtFunction, NULL);
|
js->PrintError(kNoBreakAtFunction, NULL);
|
||||||
return true;
|
return true;
|
||||||
|
@ -1857,7 +1883,7 @@ static bool RemoveBreakpoint(Isolate* isolate, JSONStream* js) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
const char* bpt_id = js->LookupParam("breakpointId");
|
const char* bpt_id = js->LookupParam("breakpointId");
|
||||||
SourceBreakpoint* bpt = LookupBreakpoint(isolate, bpt_id);
|
Breakpoint* bpt = LookupBreakpoint(isolate, bpt_id);
|
||||||
if (bpt == NULL) {
|
if (bpt == NULL) {
|
||||||
fprintf(stderr, "ERROR1");
|
fprintf(stderr, "ERROR1");
|
||||||
PrintInvalidParamError(js, "breakpointId");
|
PrintInvalidParamError(js, "breakpointId");
|
||||||
|
@ -2402,7 +2428,7 @@ static bool GetObject(Isolate* isolate, JSONStream* js) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle non-heap objects.
|
// Handle non-heap objects.
|
||||||
SourceBreakpoint* bpt = LookupBreakpoint(isolate, id);
|
Breakpoint* bpt = LookupBreakpoint(isolate, id);
|
||||||
if (bpt != NULL) {
|
if (bpt != NULL) {
|
||||||
bpt->PrintJSON(js);
|
bpt->PrintJSON(js);
|
||||||
return true;
|
return true;
|
||||||
|
@ -2592,6 +2618,8 @@ static ServiceMethodDescriptor service_methods_[] = {
|
||||||
add_breakpoint_params },
|
add_breakpoint_params },
|
||||||
{ "addBreakpointAtEntry", AddBreakpointAtEntry,
|
{ "addBreakpointAtEntry", AddBreakpointAtEntry,
|
||||||
add_breakpoint_at_entry_params },
|
add_breakpoint_at_entry_params },
|
||||||
|
{ "_addBreakpointAtActivation", AddBreakpointAtActivation,
|
||||||
|
add_breakpoint_at_activation_params },
|
||||||
{ "clearCpuProfile", ClearCpuProfile,
|
{ "clearCpuProfile", ClearCpuProfile,
|
||||||
clear_cpu_profile_params },
|
clear_cpu_profile_params },
|
||||||
{ "evaluate", Evaluate,
|
{ "evaluate", Evaluate,
|
||||||
|
|
|
@ -50,10 +50,10 @@ class ServiceEvent {
|
||||||
|
|
||||||
EventType type() const { return type_; }
|
EventType type() const { return type_; }
|
||||||
|
|
||||||
SourceBreakpoint* breakpoint() const {
|
Breakpoint* breakpoint() const {
|
||||||
return breakpoint_;
|
return breakpoint_;
|
||||||
}
|
}
|
||||||
void set_breakpoint(SourceBreakpoint* bpt) {
|
void set_breakpoint(Breakpoint* bpt) {
|
||||||
ASSERT(type() == kPauseBreakpoint ||
|
ASSERT(type() == kPauseBreakpoint ||
|
||||||
type() == kBreakpointAdded ||
|
type() == kBreakpointAdded ||
|
||||||
type() == kBreakpointResolved ||
|
type() == kBreakpointResolved ||
|
||||||
|
@ -103,7 +103,7 @@ class ServiceEvent {
|
||||||
private:
|
private:
|
||||||
Isolate* isolate_;
|
Isolate* isolate_;
|
||||||
EventType type_;
|
EventType type_;
|
||||||
SourceBreakpoint* breakpoint_;
|
Breakpoint* breakpoint_;
|
||||||
ActivationFrame* top_frame_;
|
ActivationFrame* top_frame_;
|
||||||
const Object* exception_;
|
const Object* exception_;
|
||||||
const Object* inspectee_;
|
const Object* inspectee_;
|
||||||
|
|
Loading…
Reference in a new issue