Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(261)

Side by Side Diff: pkg/stack_trace/lib/src/trace.dart

Issue 578993002: Unify parsing of Firefox and Safari stack traces. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « pkg/stack_trace/lib/src/frame.dart ('k') | pkg/stack_trace/pubspec.yaml » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 'chain.dart';
(...skipping 11 matching lines...) Expand all
22 /// lines, so we just look for any line other than the first that begins with 22 /// lines, so we just look for any line other than the first that begins with
23 /// three or four spaces and "at". 23 /// three or four spaces and "at".
24 final _v8Trace = new RegExp(r"\n ?at "); 24 final _v8Trace = new RegExp(r"\n ?at ");
25 25
26 /// A RegExp to match indidual lines of V8's stack traces. 26 /// A RegExp to match indidual lines of V8's stack traces.
27 /// 27 ///
28 /// This is intended to filter out the leading exception details of the trace 28 /// This is intended to filter out the leading exception details of the trace
29 /// though it is possible for the message to match this as well. 29 /// though it is possible for the message to match this as well.
30 final _v8TraceLine = new RegExp(r" ?at "); 30 final _v8TraceLine = new RegExp(r" ?at ");
31 31
32 /// A RegExp to match Safari's stack traces. 32 /// A RegExp to match Firefox and Safari's stack traces.
33 /// 33 ///
34 /// Prior to version 6, Safari's stack traces were uncapturable. In v6 they were 34 /// Firefox and Safari have very similar stack trace formats, so we use the same
35 /// almost identical to Firefox traces, and so are handled by the Firefox code. 35 /// logic for parsing them.
36 /// In v6.1+, they have their own format that's similar to Firefox but distinct
37 /// enough to warrant handling separately.
38 ///
39 /// Most notably, Safari traces occasionally don't include the initial method
40 /// name followed by "@", and they always have both the line and column number
41 /// (or just a trailing colon if no column number is available).
42 final _safariTrace = new RegExp(r"^([0-9A-Za-z_$]*@)?.*:\d*:\d*$",
43 multiLine: true);
44
45 /// A RegExp to match Firefox's stack traces.
46 /// 36 ///
47 /// Firefox's trace frames start with the name of the function in which the 37 /// Firefox's trace frames start with the name of the function in which the
48 /// error occurred, possibly including its parameters inside `()`. For example, 38 /// error occurred, possibly including its parameters inside `()`. For example,
49 /// `.VW.call$0("arg")@http://pub.dartlang.org/stuff.dart.js:560`. 39 /// `.VW.call$0("arg")@http://pub.dartlang.org/stuff.dart.js:560`.
50 final _firefoxTrace = new RegExp(r"^([.0-9A-Za-z_$/<]|\(.*\))*@"); 40 ///
41 /// Safari traces occasionally don't include the initial method name followed by
42 /// "@", and they always have both the line and column number (or just a
43 /// trailing colon if no column number is available). They can also contain
44 /// empty lines or lines consisting only of `[native code]`.
45 final _firefoxSafariTrace = new RegExp(
46 r"^"
47 r"(" // Member description. Not present in some Safari frames.
48 r"([.0-9A-Za-z_$/<]|\(.*\))*" // Member name and arguments.
49 r"@"
50 r")?"
51 r"[^\s]*" // Frame URL.
52 r":\d*" // Line or column number. Some older frames only have a line number.
53 r"$", multiLine: true);
51 54
52 /// A RegExp to match this package's stack traces. 55 /// A RegExp to match this package's stack traces.
53 final _friendlyTrace = new RegExp(r"^[^\s]+( \d+(:\d+)?)?[ \t]+[^\s]+$", 56 final _friendlyTrace = new RegExp(r"^[^\s]+( \d+(:\d+)?)?[ \t]+[^\s]+$",
54 multiLine: true); 57 multiLine: true);
55 58
56 /// A stack trace, comprised of a list of stack frames. 59 /// A stack trace, comprised of a list of stack frames.
57 class Trace implements StackTrace { 60 class Trace implements StackTrace {
58 /// The stack frames that comprise this stack trace. 61 /// The stack frames that comprise this stack trace.
59 final List<Frame> frames; 62 final List<Frame> frames;
60 63
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 if (trace is Trace) return trace; 105 if (trace is Trace) return trace;
103 if (trace is Chain) return trace.toTrace(); 106 if (trace is Chain) return trace.toTrace();
104 return new LazyTrace(() => new Trace.parse(trace.toString())); 107 return new LazyTrace(() => new Trace.parse(trace.toString()));
105 } 108 }
106 109
107 /// Parses a string representation of a stack trace. 110 /// Parses a string representation of a stack trace.
108 /// 111 ///
109 /// [trace] should be formatted in the same way as a Dart VM or browser stack 112 /// [trace] should be formatted in the same way as a Dart VM or browser stack
110 /// trace. 113 /// trace.
111 factory Trace.parse(String trace) { 114 factory Trace.parse(String trace) {
112 try { 115 // try {
Bob Nystrom 2014/09/18 19:12:03 ?
nweiz 2014/09/18 19:54:04 Oops, left over from debugging. Removed.
113 if (trace.isEmpty) return new Trace(<Frame>[]); 116 if (trace.isEmpty) return new Trace(<Frame>[]);
114 if (trace.contains(_v8Trace)) return new Trace.parseV8(trace); 117 if (trace.contains(_v8Trace)) return new Trace.parseV8(trace);
115 // Safari 6.1+ traces could be misinterpreted as Firefox traces, so we 118 if (trace.contains(_firefoxSafariTrace)) {
116 // check for them first. 119 return new Trace.parseFirefox(trace);
117 if (trace.contains(_safariTrace)) return new Trace.parseSafari6_1(trace); 120 }
118 // Safari 6.0 traces are a superset of Firefox traces, so we parse those
119 // two together.
120 if (trace.contains(_firefoxTrace)) return new Trace.parseSafari6_0(trace);
121 if (trace.contains(_friendlyTrace)) { 121 if (trace.contains(_friendlyTrace)) {
122 return new Trace.parseFriendly(trace); 122 return new Trace.parseFriendly(trace);
123 } 123 }
124 124
125 // Default to parsing the stack trace as a VM trace. This is also hit on 125 // Default to parsing the stack trace as a VM trace. This is also hit on
126 // IE and Safari, where the stack trace is just an empty string (issue 126 // IE and Safari, where the stack trace is just an empty string (issue
127 // 11257). 127 // 11257).
128 return new Trace.parseVM(trace); 128 return new Trace.parseVM(trace);
129 } on FormatException catch (error) { 129 // } on FormatException catch (error) {
130 throw new FormatException('${error.message}\nStack trace:\n$trace'); 130 // throw new FormatException('${error.message}\nStack trace:\n$trace');
131 } 131 // }
132 } 132 }
133 133
134 /// Parses a string representation of a Dart VM stack trace. 134 /// Parses a string representation of a Dart VM stack trace.
135 Trace.parseVM(String trace) 135 Trace.parseVM(String trace)
136 : this(trace.trim().split("\n"). 136 : this(trace.trim().split("\n").
137 // TODO(nweiz): remove this when issue 15920 is fixed. 137 // TODO(nweiz): remove this when issue 15920 is fixed.
138 where((line) => line.isNotEmpty). 138 where((line) => line.isNotEmpty).
139 map((line) => new Frame.parseVM(line))); 139 map((line) => new Frame.parseVM(line)));
140 140
141 /// Parses a string representation of a Chrome/V8 stack trace. 141 /// Parses a string representation of a Chrome/V8 stack trace.
142 Trace.parseV8(String trace) 142 Trace.parseV8(String trace)
143 : this(trace.split("\n").skip(1) 143 : this(trace.split("\n").skip(1)
144 // It's possible that an Exception's description contains a line that 144 // It's possible that an Exception's description contains a line that
145 // looks like a V8 trace line, which will screw this up. 145 // looks like a V8 trace line, which will screw this up.
146 // Unfortunately, that's impossible to detect. 146 // Unfortunately, that's impossible to detect.
147 .skipWhile((line) => !line.startsWith(_v8TraceLine)) 147 .skipWhile((line) => !line.startsWith(_v8TraceLine))
148 .map((line) => new Frame.parseV8(line))); 148 .map((line) => new Frame.parseV8(line)));
149 149
150 /// Parses a string representation of an Internet Explorer stack trace. 150 /// Parses a string representation of an Internet Explorer stack trace.
151 /// 151 ///
152 /// IE10+ traces look just like V8 traces. Prior to IE10, stack traces can't 152 /// IE10+ traces look just like V8 traces. Prior to IE10, stack traces can't
153 /// be retrieved. 153 /// be retrieved.
154 Trace.parseIE(String trace) 154 Trace.parseIE(String trace)
155 : this.parseV8(trace); 155 : this.parseV8(trace);
156 156
157 /// Parses a string representation of a Firefox stack trace. 157 /// Parses a string representation of a Firefox stack trace.
158 Trace.parseFirefox(String trace) 158 Trace.parseFirefox(String trace)
159 : this(trace.trim().split("\n") 159 : this(trace.trim().split("\n")
160 .where((line) => line.isNotEmpty && line != '[native code]')
160 .map((line) => new Frame.parseFirefox(line))); 161 .map((line) => new Frame.parseFirefox(line)));
161 162
162 /// Parses a string representation of a Safari stack trace. 163 /// Parses a string representation of a Safari stack trace.
163 /// 164 Trace.parseSafari(String trace)
164 /// This will automatically decide between [parseSafari6_0] and 165 : this.parseFirefox(trace);
165 /// [parseSafari6_1] based on the contents of [trace].
166 factory Trace.parseSafari(String trace) {
167 if (trace.contains(_safariTrace)) return new Trace.parseSafari6_1(trace);
168 return new Trace.parseSafari6_0(trace);
169 }
170 166
171 /// Parses a string representation of a Safari 6.1+ stack trace. 167 /// Parses a string representation of a Safari 6.1+ stack trace.
168 @Deprecated("Use Trace.parseSafari instead.")
172 Trace.parseSafari6_1(String trace) 169 Trace.parseSafari6_1(String trace)
173 : this(trace.trim().split("\n") 170 : this.parseSafari(trace);
174 .where((line) => line.isNotEmpty)
175 .map((line) => new Frame.parseSafari6_1(line)));
176 171
177 /// Parses a string representation of a Safari 6.0 stack trace. 172 /// Parses a string representation of a Safari 6.0 stack trace.
178 /// 173 @Deprecated("Use Trace.parseSafari instead.")
179 /// Safari 6.0 stack traces look just like Firefox traces, except that they
180 /// sometimes (e.g. in isolates) have a "[native code]" frame. We just ignore
181 /// this frame to make the stack format more consistent between browsers.
182 /// Prior to Safari 6.0, stack traces can't be retrieved.
183 Trace.parseSafari6_0(String trace) 174 Trace.parseSafari6_0(String trace)
184 : this(trace.trim().split("\n") 175 : this(trace.trim().split("\n")
185 .where((line) => line != '[native code]') 176 .where((line) => line != '[native code]')
186 .map((line) => new Frame.parseFirefox(line))); 177 .map((line) => new Frame.parseFirefox(line)));
187 178
188 /// Parses this package's string representation of a stack trace. 179 /// Parses this package's string representation of a stack trace.
189 /// 180 ///
190 /// This also parses string representations of [Chain]s. They parse to the 181 /// This also parses string representations of [Chain]s. They parse to the
191 /// same trace that [Chain.toTrace] would return. 182 /// same trace that [Chain.toTrace] would return.
192 Trace.parseFriendly(String trace) 183 Trace.parseFriendly(String trace)
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 // Figure out the longest path so we know how much to pad. 239 // Figure out the longest path so we know how much to pad.
249 var longest = frames.map((frame) => frame.location.length) 240 var longest = frames.map((frame) => frame.location.length)
250 .fold(0, math.max); 241 .fold(0, math.max);
251 242
252 // Print out the stack trace nicely formatted. 243 // Print out the stack trace nicely formatted.
253 return frames.map((frame) { 244 return frames.map((frame) {
254 return '${padRight(frame.location, longest)} ${frame.member}\n'; 245 return '${padRight(frame.location, longest)} ${frame.member}\n';
255 }).join(); 246 }).join();
256 } 247 }
257 } 248 }
OLDNEW
« no previous file with comments | « pkg/stack_trace/lib/src/frame.dart ('k') | pkg/stack_trace/pubspec.yaml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698