OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "platform/v8_inspector/V8StackTraceImpl.h" | 5 #include "platform/v8_inspector/V8StackTraceImpl.h" |
6 | 6 |
| 7 #include "platform/inspector_protocol/String16.h" |
7 #include "platform/v8_inspector/V8DebuggerAgentImpl.h" | 8 #include "platform/v8_inspector/V8DebuggerAgentImpl.h" |
8 #include "platform/v8_inspector/V8DebuggerImpl.h" | 9 #include "platform/v8_inspector/V8DebuggerImpl.h" |
9 #include "platform/v8_inspector/V8StringUtil.h" | 10 #include "platform/v8_inspector/V8StringUtil.h" |
10 #include "wtf/PassOwnPtr.h" | 11 #include "wtf/PassOwnPtr.h" |
11 #include "wtf/text/StringBuilder.h" | |
12 | 12 |
13 #include <v8-debug.h> | 13 #include <v8-debug.h> |
14 #include <v8-profiler.h> | 14 #include <v8-profiler.h> |
15 | 15 |
16 namespace blink { | 16 namespace blink { |
17 | 17 |
18 namespace { | 18 namespace { |
19 | 19 |
20 V8StackTraceImpl::Frame toCallFrame(v8::Local<v8::StackFrame> frame) | 20 V8StackTraceImpl::Frame toCallFrame(v8::Local<v8::StackFrame> frame) |
21 { | 21 { |
22 String scriptId = String::number(frame->GetScriptId()); | 22 String16 scriptId = String16::number(frame->GetScriptId()); |
23 String sourceName; | 23 String16 sourceName; |
24 v8::Local<v8::String> sourceNameValue(frame->GetScriptNameOrSourceURL()); | 24 v8::Local<v8::String> sourceNameValue(frame->GetScriptNameOrSourceURL()); |
25 if (!sourceNameValue.IsEmpty()) | 25 if (!sourceNameValue.IsEmpty()) |
26 sourceName = toWTFString(sourceNameValue); | 26 sourceName = toProtocolString(sourceNameValue); |
27 | 27 |
28 String functionName; | 28 String16 functionName; |
29 v8::Local<v8::String> functionNameValue(frame->GetFunctionName()); | 29 v8::Local<v8::String> functionNameValue(frame->GetFunctionName()); |
30 if (!functionNameValue.IsEmpty()) | 30 if (!functionNameValue.IsEmpty()) |
31 functionName = toWTFString(functionNameValue); | 31 functionName = toProtocolString(functionNameValue); |
32 | 32 |
33 int sourceLineNumber = frame->GetLineNumber(); | 33 int sourceLineNumber = frame->GetLineNumber(); |
34 int sourceColumn = frame->GetColumn(); | 34 int sourceColumn = frame->GetColumn(); |
35 return V8StackTraceImpl::Frame(functionName, scriptId, sourceName, sourceLin
eNumber, sourceColumn); | 35 return V8StackTraceImpl::Frame(functionName, scriptId, sourceName, sourceLin
eNumber, sourceColumn); |
36 } | 36 } |
37 | 37 |
38 void toCallFramesVector(v8::Local<v8::StackTrace> stackTrace, protocol::Vector<V
8StackTraceImpl::Frame>& scriptCallFrames, size_t maxStackSize, v8::Isolate* iso
late) | 38 void toCallFramesVector(v8::Local<v8::StackTrace> stackTrace, protocol::Vector<V
8StackTraceImpl::Frame>& scriptCallFrames, size_t maxStackSize, v8::Isolate* iso
late) |
39 { | 39 { |
40 ASSERT(isolate->InContext()); | 40 ASSERT(isolate->InContext()); |
41 int frameCount = stackTrace->GetFrameCount(); | 41 int frameCount = stackTrace->GetFrameCount(); |
42 if (frameCount > static_cast<int>(maxStackSize)) | 42 if (frameCount > static_cast<int>(maxStackSize)) |
43 frameCount = maxStackSize; | 43 frameCount = maxStackSize; |
44 for (int i = 0; i < frameCount; i++) { | 44 for (int i = 0; i < frameCount; i++) { |
45 v8::Local<v8::StackFrame> stackFrame = stackTrace->GetFrame(i); | 45 v8::Local<v8::StackFrame> stackFrame = stackTrace->GetFrame(i); |
46 scriptCallFrames.append(toCallFrame(stackFrame)); | 46 scriptCallFrames.append(toCallFrame(stackFrame)); |
47 } | 47 } |
48 } | 48 } |
49 | 49 |
50 } // namespace | 50 } // namespace |
51 | 51 |
52 V8StackTraceImpl::Frame::Frame() | 52 V8StackTraceImpl::Frame::Frame() |
53 : m_functionName("undefined") | 53 : m_functionName("undefined") |
54 , m_scriptId("") | 54 , m_scriptId("") |
55 , m_scriptName("undefined") | 55 , m_scriptName("undefined") |
56 , m_lineNumber(0) | 56 , m_lineNumber(0) |
57 , m_columnNumber(0) | 57 , m_columnNumber(0) |
58 { | 58 { |
59 } | 59 } |
60 | 60 |
61 V8StackTraceImpl::Frame::Frame(const String& functionName, const String& scriptI
d, const String& scriptName, int lineNumber, int column) | 61 V8StackTraceImpl::Frame::Frame(const String16& functionName, const String16& scr
iptId, const String16& scriptName, int lineNumber, int column) |
62 : m_functionName(functionName) | 62 : m_functionName(functionName) |
63 , m_scriptId(scriptId) | 63 , m_scriptId(scriptId) |
64 , m_scriptName(scriptName) | 64 , m_scriptName(scriptName) |
65 , m_lineNumber(lineNumber) | 65 , m_lineNumber(lineNumber) |
66 , m_columnNumber(column) | 66 , m_columnNumber(column) |
67 { | 67 { |
68 } | 68 } |
69 | 69 |
70 V8StackTraceImpl::Frame::~Frame() | 70 V8StackTraceImpl::Frame::~Frame() |
71 { | 71 { |
72 } | 72 } |
73 | 73 |
74 // buildInspectorObject() and ScriptCallStack's toTracedValue() should set the s
ame fields. | 74 // buildInspectorObject() and ScriptCallStack's toTracedValue() should set the s
ame fields. |
75 // If either of them is modified, the other should be also modified. | 75 // If either of them is modified, the other should be also modified. |
76 PassOwnPtr<protocol::Runtime::CallFrame> V8StackTraceImpl::Frame::buildInspector
Object() const | 76 PassOwnPtr<protocol::Runtime::CallFrame> V8StackTraceImpl::Frame::buildInspector
Object() const |
77 { | 77 { |
78 return protocol::Runtime::CallFrame::create() | 78 return protocol::Runtime::CallFrame::create() |
79 .setFunctionName(m_functionName) | 79 .setFunctionName(m_functionName) |
80 .setScriptId(m_scriptId) | 80 .setScriptId(m_scriptId) |
81 .setUrl(m_scriptName) | 81 .setUrl(m_scriptName) |
82 .setLineNumber(m_lineNumber) | 82 .setLineNumber(m_lineNumber) |
83 .setColumnNumber(m_columnNumber) | 83 .setColumnNumber(m_columnNumber) |
84 .build(); | 84 .build(); |
85 } | 85 } |
86 | 86 |
87 PassOwnPtr<V8StackTraceImpl> V8StackTraceImpl::create(V8DebuggerAgentImpl* agent
, v8::Local<v8::StackTrace> stackTrace, size_t maxStackSize, const String& descr
iption) | 87 PassOwnPtr<V8StackTraceImpl> V8StackTraceImpl::create(V8DebuggerAgentImpl* agent
, v8::Local<v8::StackTrace> stackTrace, size_t maxStackSize, const String16& des
cription) |
88 { | 88 { |
89 v8::Isolate* isolate = v8::Isolate::GetCurrent(); | 89 v8::Isolate* isolate = v8::Isolate::GetCurrent(); |
90 v8::HandleScope scope(isolate); | 90 v8::HandleScope scope(isolate); |
91 protocol::Vector<V8StackTraceImpl::Frame> scriptCallFrames; | 91 protocol::Vector<V8StackTraceImpl::Frame> scriptCallFrames; |
92 if (!stackTrace.IsEmpty()) | 92 if (!stackTrace.IsEmpty()) |
93 toCallFramesVector(stackTrace, scriptCallFrames, maxStackSize, isolate); | 93 toCallFramesVector(stackTrace, scriptCallFrames, maxStackSize, isolate); |
94 | 94 |
95 OwnPtr<V8StackTraceImpl> asyncCallStack; | 95 OwnPtr<V8StackTraceImpl> asyncCallStack; |
96 if (agent && agent->trackingAsyncCalls() && maxStackSize > 1) | 96 if (agent && agent->trackingAsyncCalls() && maxStackSize > 1) |
97 asyncCallStack = agent->currentAsyncStackTraceForRuntime(); | 97 asyncCallStack = agent->currentAsyncStackTraceForRuntime(); |
98 | 98 |
99 if (stackTrace.IsEmpty() && !asyncCallStack) | 99 if (stackTrace.IsEmpty() && !asyncCallStack) |
100 return nullptr; | 100 return nullptr; |
101 | 101 |
102 return V8StackTraceImpl::create(description, scriptCallFrames, asyncCallStac
k.release()); | 102 return V8StackTraceImpl::create(description, scriptCallFrames, asyncCallStac
k.release()); |
103 } | 103 } |
104 | 104 |
105 PassOwnPtr<V8StackTraceImpl> V8StackTraceImpl::capture(V8DebuggerAgentImpl* agen
t, size_t maxStackSize, const String& description) | 105 PassOwnPtr<V8StackTraceImpl> V8StackTraceImpl::capture(V8DebuggerAgentImpl* agen
t, size_t maxStackSize, const String16& description) |
106 { | 106 { |
107 v8::Isolate* isolate = v8::Isolate::GetCurrent(); | 107 v8::Isolate* isolate = v8::Isolate::GetCurrent(); |
108 v8::HandleScope handleScope(isolate); | 108 v8::HandleScope handleScope(isolate); |
109 v8::Local<v8::StackTrace> stackTrace; | 109 v8::Local<v8::StackTrace> stackTrace; |
110 if (isolate->InContext()) { | 110 if (isolate->InContext()) { |
111 isolate->GetCpuProfiler()->CollectSample(); | 111 isolate->GetCpuProfiler()->CollectSample(); |
112 stackTrace = v8::StackTrace::CurrentStackTrace(isolate, maxStackSize, st
ackTraceOptions); | 112 stackTrace = v8::StackTrace::CurrentStackTrace(isolate, maxStackSize, st
ackTraceOptions); |
113 } | 113 } |
114 return V8StackTraceImpl::create(agent, stackTrace, maxStackSize, description
); | 114 return V8StackTraceImpl::create(agent, stackTrace, maxStackSize, description
); |
115 } | 115 } |
116 | 116 |
117 PassOwnPtr<V8StackTraceImpl> V8StackTraceImpl::create(const String& description,
protocol::Vector<Frame>& frames, PassOwnPtr<V8StackTraceImpl> parent) | 117 PassOwnPtr<V8StackTraceImpl> V8StackTraceImpl::create(const String16& descriptio
n, protocol::Vector<Frame>& frames, PassOwnPtr<V8StackTraceImpl> parent) |
118 { | 118 { |
119 return adoptPtr(new V8StackTraceImpl(description, frames, parent)); | 119 return adoptPtr(new V8StackTraceImpl(description, frames, parent)); |
120 } | 120 } |
121 | 121 |
122 PassOwnPtr<V8StackTraceImpl> V8StackTraceImpl::clone(V8StackTraceImpl* origin, s
ize_t maxStackSize) | 122 PassOwnPtr<V8StackTraceImpl> V8StackTraceImpl::clone(V8StackTraceImpl* origin, s
ize_t maxStackSize) |
123 { | 123 { |
124 if (!origin) | 124 if (!origin) |
125 return nullptr; | 125 return nullptr; |
126 | 126 |
127 // TODO(dgozman): move this check to call-site. | 127 // TODO(dgozman): move this check to call-site. |
128 if (!origin->m_frames.size()) | 128 if (!origin->m_frames.size()) |
129 return V8StackTraceImpl::clone(origin->m_parent.get(), maxStackSize); | 129 return V8StackTraceImpl::clone(origin->m_parent.get(), maxStackSize); |
130 | 130 |
131 OwnPtr<V8StackTraceImpl> parent; | 131 OwnPtr<V8StackTraceImpl> parent; |
132 if (origin->m_parent && maxStackSize) | 132 if (origin->m_parent && maxStackSize) |
133 parent = V8StackTraceImpl::clone(origin->m_parent.get(), maxStackSize -
1); | 133 parent = V8StackTraceImpl::clone(origin->m_parent.get(), maxStackSize -
1); |
134 | 134 |
135 protocol::Vector<Frame> frames(origin->m_frames); | 135 protocol::Vector<Frame> frames(origin->m_frames); |
136 return adoptPtr(new V8StackTraceImpl(origin->m_description, frames, parent.r
elease())); | 136 return adoptPtr(new V8StackTraceImpl(origin->m_description, frames, parent.r
elease())); |
137 } | 137 } |
138 | 138 |
139 V8StackTraceImpl::V8StackTraceImpl(const String& description, protocol::Vector<F
rame>& frames, PassOwnPtr<V8StackTraceImpl> parent) | 139 V8StackTraceImpl::V8StackTraceImpl(const String16& description, protocol::Vector
<Frame>& frames, PassOwnPtr<V8StackTraceImpl> parent) |
140 : m_description(description) | 140 : m_description(description) |
141 , m_parent(parent) | 141 , m_parent(parent) |
142 { | 142 { |
143 m_frames.swap(frames); | 143 m_frames.swap(frames); |
144 } | 144 } |
145 | 145 |
146 V8StackTraceImpl::~V8StackTraceImpl() | 146 V8StackTraceImpl::~V8StackTraceImpl() |
147 { | 147 { |
148 } | 148 } |
149 | 149 |
150 String V8StackTraceImpl::topSourceURL() const | 150 String16 V8StackTraceImpl::topSourceURL() const |
151 { | 151 { |
152 ASSERT(m_frames.size()); | 152 ASSERT(m_frames.size()); |
153 return m_frames[0].m_scriptName; | 153 return m_frames[0].m_scriptName; |
154 } | 154 } |
155 | 155 |
156 int V8StackTraceImpl::topLineNumber() const | 156 int V8StackTraceImpl::topLineNumber() const |
157 { | 157 { |
158 ASSERT(m_frames.size()); | 158 ASSERT(m_frames.size()); |
159 return m_frames[0].m_lineNumber; | 159 return m_frames[0].m_lineNumber; |
160 } | 160 } |
161 | 161 |
162 int V8StackTraceImpl::topColumnNumber() const | 162 int V8StackTraceImpl::topColumnNumber() const |
163 { | 163 { |
164 ASSERT(m_frames.size()); | 164 ASSERT(m_frames.size()); |
165 return m_frames[0].m_columnNumber; | 165 return m_frames[0].m_columnNumber; |
166 } | 166 } |
167 | 167 |
168 String V8StackTraceImpl::topFunctionName() const | 168 String16 V8StackTraceImpl::topFunctionName() const |
169 { | 169 { |
170 ASSERT(m_frames.size()); | 170 ASSERT(m_frames.size()); |
171 return m_frames[0].m_functionName; | 171 return m_frames[0].m_functionName; |
172 } | 172 } |
173 | 173 |
174 String V8StackTraceImpl::topScriptId() const | 174 String16 V8StackTraceImpl::topScriptId() const |
175 { | 175 { |
176 ASSERT(m_frames.size()); | 176 ASSERT(m_frames.size()); |
177 return m_frames[0].m_scriptId; | 177 return m_frames[0].m_scriptId; |
178 } | 178 } |
179 | 179 |
180 PassOwnPtr<protocol::Runtime::StackTrace> V8StackTraceImpl::buildInspectorObject
() const | 180 PassOwnPtr<protocol::Runtime::StackTrace> V8StackTraceImpl::buildInspectorObject
() const |
181 { | 181 { |
182 OwnPtr<protocol::Array<protocol::Runtime::CallFrame>> frames = protocol::Arr
ay<protocol::Runtime::CallFrame>::create(); | 182 OwnPtr<protocol::Array<protocol::Runtime::CallFrame>> frames = protocol::Arr
ay<protocol::Runtime::CallFrame>::create(); |
183 for (size_t i = 0; i < m_frames.size(); i++) | 183 for (size_t i = 0; i < m_frames.size(); i++) |
184 frames->addItem(m_frames.at(i).buildInspectorObject()); | 184 frames->addItem(m_frames.at(i).buildInspectorObject()); |
185 | 185 |
186 OwnPtr<protocol::Runtime::StackTrace> stackTrace = protocol::Runtime::StackT
race::create() | 186 OwnPtr<protocol::Runtime::StackTrace> stackTrace = protocol::Runtime::StackT
race::create() |
187 .setCallFrames(frames.release()).build(); | 187 .setCallFrames(frames.release()).build(); |
188 if (!m_description.isEmpty()) | 188 if (!m_description.isEmpty()) |
189 stackTrace->setDescription(m_description); | 189 stackTrace->setDescription(m_description); |
190 if (m_parent) | 190 if (m_parent) |
191 stackTrace->setParent(m_parent->buildInspectorObject()); | 191 stackTrace->setParent(m_parent->buildInspectorObject()); |
192 return stackTrace.release(); | 192 return stackTrace.release(); |
193 } | 193 } |
194 | 194 |
195 String V8StackTraceImpl::toString() const | 195 String16 V8StackTraceImpl::toString() const |
196 { | 196 { |
197 StringBuilder stackTrace; | 197 String16Builder stackTrace; |
198 for (size_t i = 0; i < m_frames.size(); ++i) { | 198 for (size_t i = 0; i < m_frames.size(); ++i) { |
199 const Frame& frame = m_frames[i]; | 199 const Frame& frame = m_frames[i]; |
200 stackTrace.append("\n at " + (frame.functionName().length() ? frame.f
unctionName() : "(anonymous function)")); | 200 stackTrace.append("\n at " + (frame.functionName().length() ? frame.f
unctionName() : "(anonymous function)")); |
201 stackTrace.appendLiteral(" ("); | 201 stackTrace.append(" ("); |
202 stackTrace.append(frame.sourceURL()); | 202 stackTrace.append(frame.sourceURL()); |
203 stackTrace.append(':'); | 203 stackTrace.append(':'); |
204 stackTrace.appendNumber(frame.lineNumber()); | 204 stackTrace.appendNumber(frame.lineNumber()); |
205 stackTrace.append(':'); | 205 stackTrace.append(':'); |
206 stackTrace.appendNumber(frame.columnNumber()); | 206 stackTrace.appendNumber(frame.columnNumber()); |
207 stackTrace.append(')'); | 207 stackTrace.append(')'); |
208 } | 208 } |
209 return stackTrace.toString(); | 209 return stackTrace.toString(); |
210 } | 210 } |
211 | 211 |
212 } // namespace blink | 212 } // namespace blink |
OLD | NEW |