OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome/renderer/extensions/chrome_extensions_render_frame_observer.h" | |
6 | |
7 #include "base/strings/string_split.h" | |
8 #include "base/strings/utf_string_conversions.h" | |
9 #include "chrome/common/render_messages.h" | |
10 #include "extensions/common/stack_frame.h" | |
11 | |
12 namespace { | |
Devlin
2014/06/06 20:57:23
please put all this in the extensions namespace.
Lei Zhang
2014/06/06 21:31:35
Done.
| |
13 | |
14 // The delimiter for a stack trace provided by WebKit. | |
15 const char kStackFrameDelimiter[] = "\n at "; | |
16 | |
17 // Get a stack trace from a WebKit console message. | |
18 // There are three possible scenarios: | |
19 // 1. WebKit gives us a stack trace in |stack_trace|. | |
20 // 2. The stack trace is embedded in the error |message| by an internal | |
21 // script. This will be more useful than |stack_trace|, since |stack_trace| | |
22 // will include the internal bindings trace, instead of a developer's code. | |
23 // 3. No stack trace is included. In this case, we should mock one up from | |
24 // the given line number and source. | |
25 // |message| will be populated with the error message only (i.e., will not | |
26 // include any stack trace). | |
27 extensions::StackTrace GetStackTraceFromMessage( | |
28 base::string16* message, | |
29 const base::string16& source, | |
30 const base::string16& stack_trace, | |
31 int32 line_number) { | |
32 extensions::StackTrace result; | |
33 std::vector<base::string16> pieces; | |
34 size_t index = 0; | |
35 | |
36 if (message->find(base::UTF8ToUTF16(kStackFrameDelimiter)) != | |
37 base::string16::npos) { | |
38 base::SplitStringUsingSubstr(*message, | |
39 base::UTF8ToUTF16(kStackFrameDelimiter), | |
40 &pieces); | |
41 *message = pieces[0]; | |
42 index = 1; | |
43 } else if (!stack_trace.empty()) { | |
44 base::SplitStringUsingSubstr(stack_trace, | |
45 base::UTF8ToUTF16(kStackFrameDelimiter), | |
46 &pieces); | |
47 } | |
48 | |
49 // If we got a stack trace, parse each frame from the text. | |
50 if (index < pieces.size()) { | |
51 for (; index < pieces.size(); ++index) { | |
52 scoped_ptr<extensions::StackFrame> frame = | |
53 extensions::StackFrame::CreateFromText(pieces[index]); | |
54 if (frame.get()) | |
55 result.push_back(*frame); | |
56 } | |
57 } | |
58 | |
59 if (result.empty()) { // If we don't have a stack trace, mock one up. | |
60 result.push_back( | |
61 extensions::StackFrame(line_number, | |
62 1u, // column number | |
63 source, | |
64 base::string16() /* no function name */ )); | |
65 } | |
66 | |
67 return result; | |
68 } | |
69 | |
70 } // namespace | |
71 | |
72 ChromeExtensionsRenderFrameObserver::ChromeExtensionsRenderFrameObserver( | |
73 content::RenderFrame* render_frame) | |
74 : content::RenderFrameObserver(render_frame) { | |
75 } | |
76 | |
77 ChromeExtensionsRenderFrameObserver::~ChromeExtensionsRenderFrameObserver() { | |
78 } | |
79 | |
80 void ChromeExtensionsRenderFrameObserver::DetailedConsoleMessageAdded( | |
81 const base::string16& message, | |
82 const base::string16& source, | |
83 const base::string16& stack_trace_string, | |
84 int32 line_number, | |
85 int32 severity_level) { | |
86 base::string16 trimmed_message = message; | |
87 extensions::StackTrace stack_trace = GetStackTraceFromMessage( | |
88 &trimmed_message, | |
89 source, | |
90 stack_trace_string, | |
91 line_number); | |
92 Send(new ChromeViewHostMsg_DetailedConsoleMessageAdded( | |
93 routing_id(), trimmed_message, source, stack_trace, severity_level)); | |
94 } | |
OLD | NEW |