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