OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library trace; | 5 library trace; |
6 | 6 |
7 import 'dart:collection'; | 7 import 'dart:collection'; |
8 import 'dart:math' as math; | 8 import 'dart:math' as math; |
9 | 9 |
| 10 import 'chain.dart'; |
10 import 'frame.dart'; | 11 import 'frame.dart'; |
11 import 'lazy_trace.dart'; | 12 import 'lazy_trace.dart'; |
12 import 'utils.dart'; | 13 import 'utils.dart'; |
13 import 'vm_trace.dart'; | 14 import 'vm_trace.dart'; |
14 | 15 |
15 final _terseRegExp = new RegExp(r"(-patch)?(/.*)?$"); | 16 final _terseRegExp = new RegExp(r"(-patch)?(/.*)?$"); |
16 | 17 |
17 /// A RegExp to match V8's stack traces. | 18 /// A RegExp to match V8's stack traces. |
18 /// | 19 /// |
19 /// V8's traces start with a line that's either just "Error" or else is a | 20 /// V8's traces start with a line that's either just "Error" or else is a |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 return new LazyTrace(() => new Trace(trace.frames.skip(level + 1))); | 86 return new LazyTrace(() => new Trace(trace.frames.skip(level + 1))); |
86 } | 87 } |
87 } | 88 } |
88 | 89 |
89 /// Returns a new stack trace containing the same data as [trace]. | 90 /// Returns a new stack trace containing the same data as [trace]. |
90 /// | 91 /// |
91 /// If [trace] is a native [StackTrace], its data will be parsed out; if it's | 92 /// If [trace] is a native [StackTrace], its data will be parsed out; if it's |
92 /// a [Trace], it will be returned as-is. | 93 /// a [Trace], it will be returned as-is. |
93 factory Trace.from(StackTrace trace) { | 94 factory Trace.from(StackTrace trace) { |
94 if (trace is Trace) return trace; | 95 if (trace is Trace) return trace; |
| 96 if (trace is Chain) return trace.toTrace(); |
95 return new LazyTrace(() => new Trace.parse(trace.toString())); | 97 return new LazyTrace(() => new Trace.parse(trace.toString())); |
96 } | 98 } |
97 | 99 |
98 /// Parses a string representation of a stack trace. | 100 /// Parses a string representation of a stack trace. |
99 /// | 101 /// |
100 /// [trace] should be formatted in the same way as a Dart VM or browser stack | 102 /// [trace] should be formatted in the same way as a Dart VM or browser stack |
101 /// trace. | 103 /// trace. |
102 factory Trace.parse(String trace) { | 104 factory Trace.parse(String trace) { |
103 try { | 105 try { |
104 if (trace.isEmpty) return new Trace(<Frame>[]); | 106 if (trace.isEmpty) return new Trace(<Frame>[]); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
165 /// | 167 /// |
166 /// Safari 6.0 stack traces look just like Firefox traces, except that they | 168 /// Safari 6.0 stack traces look just like Firefox traces, except that they |
167 /// sometimes (e.g. in isolates) have a "[native code]" frame. We just ignore | 169 /// sometimes (e.g. in isolates) have a "[native code]" frame. We just ignore |
168 /// this frame to make the stack format more consistent between browsers. | 170 /// this frame to make the stack format more consistent between browsers. |
169 /// Prior to Safari 6.0, stack traces can't be retrieved. | 171 /// Prior to Safari 6.0, stack traces can't be retrieved. |
170 Trace.parseSafari6_0(String trace) | 172 Trace.parseSafari6_0(String trace) |
171 : this(trace.trim().split("\n") | 173 : this(trace.trim().split("\n") |
172 .where((line) => line != '[native code]') | 174 .where((line) => line != '[native code]') |
173 .map((line) => new Frame.parseFirefox(line))); | 175 .map((line) => new Frame.parseFirefox(line))); |
174 | 176 |
175 /// Parses this package's a string representation of a stack trace. | 177 /// Parses this package's string representation of a stack trace. |
| 178 /// |
| 179 /// This also parses string representations of [Chain]s. They parse to the |
| 180 /// same trace that [Chain.toTrace] would return. |
176 Trace.parseFriendly(String trace) | 181 Trace.parseFriendly(String trace) |
177 : this(trace.trim().split("\n") | 182 : this(trace.trim().split("\n") |
| 183 // Filter out asynchronous gaps from [Chain]s. |
| 184 .where((line) => !line.startsWith('=====')) |
178 .map((line) => new Frame.parseFriendly(line))); | 185 .map((line) => new Frame.parseFriendly(line))); |
179 | 186 |
180 /// Returns a new [Trace] comprised of [frames]. | 187 /// Returns a new [Trace] comprised of [frames]. |
181 Trace(Iterable<Frame> frames) | 188 Trace(Iterable<Frame> frames) |
182 : frames = new UnmodifiableListView<Frame>(frames.toList()); | 189 : frames = new UnmodifiableListView<Frame>(frames.toList()); |
183 | 190 |
184 /// Returns a VM-style [StackTrace] object. | 191 /// Returns a VM-style [StackTrace] object. |
185 /// | 192 /// |
186 /// The return value's [toString] method will always return a string | 193 /// The return value's [toString] method will always return a string |
187 /// representation in the Dart VM's stack trace format, regardless of what | 194 /// representation in the Dart VM's stack trace format, regardless of what |
188 /// platform is being used. | 195 /// platform is being used. |
189 StackTrace get vmTrace => new VMTrace(frames); | 196 StackTrace get vmTrace => new VMTrace(frames); |
190 | 197 |
191 /// Returns a terser version of [this]. | 198 /// Returns a terser version of [this]. |
192 /// | 199 /// |
193 /// This is accomplished by folding together multiple stack frames from the | 200 /// This is accomplished by folding together multiple stack frames from the |
194 /// core library, as in [foldFrames]. Remaining core library frames have their | 201 /// core library or from this package, as in [foldFrames]. Remaining core |
195 /// libraries, "-patch" suffixes, and line numbers removed. | 202 /// library frames have their libraries, "-patch" suffixes, and line numbers |
| 203 /// removed. |
196 Trace get terse { | 204 Trace get terse { |
197 return new Trace(foldFrames((frame) => frame.isCore).frames.map((frame) { | 205 return new Trace(foldFrames((frame) { |
| 206 return frame.isCore || frame.package == 'stack_trace'; |
| 207 }).frames.map((frame) { |
198 if (!frame.isCore) return frame; | 208 if (!frame.isCore) return frame; |
199 var library = frame.library.replaceAll(_terseRegExp, ''); | 209 var library = frame.library.replaceAll(_terseRegExp, ''); |
200 return new Frame(Uri.parse(library), null, null, frame.member); | 210 return new Frame(Uri.parse(library), null, null, frame.member); |
201 })); | 211 })); |
202 } | 212 } |
203 | 213 |
204 /// Returns a new [Trace] based on [this] where multiple stack frames matching | 214 /// Returns a new [Trace] based on [this] where multiple stack frames matching |
205 /// [predicate] are folded together. This means that whenever there are | 215 /// [predicate] are folded together. This means that whenever there are |
206 /// multiple frames in a row that match [predicate], only the last one is | 216 /// multiple frames in a row that match [predicate], only the last one is |
207 /// kept. | 217 /// kept. |
(...skipping 19 matching lines...) Expand all Loading... |
227 // Figure out the longest path so we know how much to pad. | 237 // Figure out the longest path so we know how much to pad. |
228 var longest = frames.map((frame) => frame.location.length) | 238 var longest = frames.map((frame) => frame.location.length) |
229 .fold(0, math.max); | 239 .fold(0, math.max); |
230 | 240 |
231 // Print out the stack trace nicely formatted. | 241 // Print out the stack trace nicely formatted. |
232 return frames.map((frame) { | 242 return frames.map((frame) { |
233 return '${padRight(frame.location, longest)} ${frame.member}\n'; | 243 return '${padRight(frame.location, longest)} ${frame.member}\n'; |
234 }).join(); | 244 }).join(); |
235 } | 245 } |
236 } | 246 } |
OLD | NEW |