Index: runtime/observatory/lib/src/elements/debugger.dart |
diff --git a/runtime/observatory/lib/src/elements/debugger.dart b/runtime/observatory/lib/src/elements/debugger.dart |
index b3ca5693fd3b00e7b831eb127e6e7b95524bbda6..18594b42dd4210ae95990f6066f966648eacc112 100644 |
--- a/runtime/observatory/lib/src/elements/debugger.dart |
+++ b/runtime/observatory/lib/src/elements/debugger.dart |
@@ -604,6 +604,11 @@ class SetCommand extends DebuggerCommand { |
_setUpIsDown, |
(debugger, _) => debugger.upIsDown |
], |
+ 'sane-async-stacks': [ |
+ _boolValues, |
+ _setSaneAsyncStacks, |
+ (debugger, _) => debugger.saneAsyncStacks |
+ ] |
}; |
static Future _setBreakOnException(debugger, name, value) async { |
@@ -625,6 +630,16 @@ class SetCommand extends DebuggerCommand { |
debugger.console.print('${name} = ${value}'); |
} |
+ static Future _setSaneAsyncStacks(debugger, name, value) async { |
+ if (value == 'true') { |
+ debugger.saneAsyncStacks = true; |
+ } else { |
+ debugger.saneAsyncStacks = false; |
+ } |
+ debugger.refreshStack(); |
+ debugger.console.print('${name} = ${value}'); |
+ } |
+ |
Future run(List<String> args) async { |
if (args.length == 0) { |
for (var name in _options.keys) { |
@@ -1381,6 +1396,17 @@ class ObservatoryDebugger extends Debugger { |
bool _upIsDown; |
+ bool get saneAsyncStacks => _saneAsyncStacks; |
+ void set saneAsyncStacks(bool value) { |
+ settings.set('sane-async-stacks', value); |
+ _saneAsyncStacks = value; |
+ } |
+ |
+ bool _saneAsyncStacks; |
+ |
+ static const String kAsyncStackFrames = 'asyncFrames'; |
+ static const String kStackFrames = 'frames'; |
+ |
void upFrame(int count) { |
if (_upIsDown) { |
currentFrame += count; |
@@ -1397,7 +1423,21 @@ class ObservatoryDebugger extends Debugger { |
} |
} |
- int get stackDepth => stack['frames'].length; |
+ int get stackDepth { |
+ if (saneAsyncStacks) { |
+ return stack[kAsyncStackFrames].length; |
+ } else { |
+ return stack[kStackFrames].length; |
+ } |
+ } |
+ |
+ List get stackFrames { |
+ if (saneAsyncStacks) { |
+ return stack[kAsyncStackFrames] ?? []; |
+ } else { |
+ return stack[kStackFrames] ?? []; |
+ } |
+ } |
static final _history = ['']; |
@@ -1434,6 +1474,8 @@ class ObservatoryDebugger extends Debugger { |
void _loadSettings() { |
_upIsDown = settings.get('up-is-down'); |
+ _saneAsyncStacks = settings.get('sane-async-stacks') ?? true; |
+ print('saneAsyncStacks -> $_saneAsyncStacks'); |
} |
S.VM get vm => page.app.vm; |
@@ -1515,7 +1557,9 @@ class ObservatoryDebugger extends Debugger { |
} |
stack = result; |
stackElement.updateStack(stack, pauseEvent); |
- if (stack['frames'].length > 0) { |
+ List frames = |
+ saneAsyncStacks ? stack[kAsyncStackFrames] : stack[kStackFrames]; |
+ if (frames.length > 0) { |
currentFrame = 0; |
} else { |
currentFrame = null; |
@@ -1585,8 +1629,8 @@ class ObservatoryDebugger extends Debugger { |
console.print("Paused at an unhandled exception " |
"(type 'continue' or [F7] to exit the isolate')"); |
_reportIsolateError(isolate, event); |
- } else if (stack['frames'].length > 0) { |
- S.Frame frame = stack['frames'][0]; |
+ } else if (stackFrames.length > 0) { |
+ S.Frame frame = stackFrames[0]; |
var script = frame.location.script; |
script.load().then((_) { |
var line = script.tokenToLine(frame.location.tokenPos); |
@@ -2251,7 +2295,9 @@ class DebuggerStackElement extends HtmlElement implements Renderable { |
void updateStackFrames(S.ServiceMap newStack) { |
List frameElements = _frameList.children; |
- List newFrames = newStack['frames']; |
+ List newFrames = _debugger.saneAsyncStacks ? |
+ newStack[ObservatoryDebugger.kAsyncStackFrames] : |
+ newStack[ObservatoryDebugger.kStackFrames]; |
// Remove any frames whose functions don't match, starting from |
// bottom of stack. |
@@ -2379,7 +2425,11 @@ class DebuggerFrameElement extends HtmlElement implements Renderable { |
bool _expanded = false; |
void setCurrent(bool value) { |
- _frame.function.load().then((func) { |
+ Future load = |
+ (_frame.function != null) ? |
+ _frame.function.load() : |
+ new Future.value(null); |
+ load.then((func) { |
_current = value; |
if (_current) { |
_expand(); |
@@ -2432,6 +2482,13 @@ class DebuggerFrameElement extends HtmlElement implements Renderable { |
} else { |
classes.remove('current'); |
} |
+ if (_frame.kind == M.FrameKind.marker) { |
+ final content = <Element>[ |
+ new SpanElement()..children = _createMarkerHeader(_frame.marker) |
+ ]; |
+ children = content; |
+ return; |
+ } |
ButtonElement expandButton; |
final content = <Element>[ |
expandButton = new ButtonElement() |
@@ -2534,6 +2591,24 @@ class DebuggerFrameElement extends HtmlElement implements Renderable { |
children = content; |
} |
+ List<Element> _createMarkerHeader(String marker) { |
+ final content = [ |
+ new DivElement() |
+ ..classes = ['frameSummaryText'] |
+ ..children = [ |
+ new DivElement() |
+ ..classes = ['frameId'] |
+ ..text = 'Frame ${_frame.index}', |
+ new SpanElement()..text = '$marker', |
+ ] |
+ ]; |
+ return [ |
+ new DivElement() |
+ ..classes = ['frameSummary'] |
+ ..children = content |
+ ]; |
+ } |
+ |
List<Element> _createHeader() { |
final content = [ |
new DivElement() |
@@ -2578,6 +2653,9 @@ class DebuggerFrameElement extends HtmlElement implements Renderable { |
} |
bool matchFrame(S.Frame newFrame) { |
+ if (newFrame.function == null) { |
+ return frame.function == null; |
+ } |
return (newFrame.function.id == _frame.function.id && |
newFrame.location.script.id == |
frame.location.script.id); |