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

Side by Side Diff: src/inspector/v8-stack-trace-impl.cc

Issue 2807273002: [inspector] store creation stack in current V8StackTraceImpl (Closed)
Patch Set: finally passed tests Created 3 years, 8 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
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 the V8 project 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 "src/inspector/v8-stack-trace-impl.h" 5 #include "src/inspector/v8-stack-trace-impl.h"
6 6
7 #include "src/inspector/string-util.h" 7 #include "src/inspector/string-util.h"
8 #include "src/inspector/v8-debugger-agent-impl.h" 8 #include "src/inspector/v8-debugger-agent-impl.h"
9 #include "src/inspector/v8-debugger.h" 9 #include "src/inspector/v8-debugger.h"
10 #include "src/inspector/v8-inspector-impl.h" 10 #include "src/inspector/v8-inspector-impl.h"
11 11
12 #include "include/v8-version.h" 12 #include "include/v8-version.h"
13 13
14 namespace v8_inspector { 14 namespace v8_inspector {
15 15
16 namespace { 16 namespace {
17 17
18 static const v8::StackTrace::StackTraceOptions stackTraceOptions = 18 static const v8::StackTrace::StackTraceOptions stackTraceOptions =
19 static_cast<v8::StackTrace::StackTraceOptions>( 19 static_cast<v8::StackTrace::StackTraceOptions>(
20 v8::StackTrace::kLineNumber | v8::StackTrace::kColumnOffset | 20 v8::StackTrace::kLineNumber | v8::StackTrace::kColumnOffset |
21 v8::StackTrace::kScriptId | v8::StackTrace::kScriptNameOrSourceURL | 21 v8::StackTrace::kScriptId | v8::StackTrace::kScriptNameOrSourceURL |
22 v8::StackTrace::kFunctionName | 22 v8::StackTrace::kFunctionName |
23 v8::StackTrace::kExposeFramesAcrossSecurityOrigins); 23 v8::StackTrace::kExposeFramesAcrossSecurityOrigins);
24 24
25 V8StackTraceImpl::Frame toFrame(v8::Local<v8::StackFrame> frame, 25 V8StackTraceImpl::Frame toFrame(v8::Local<v8::StackFrame> frame,
26 WasmTranslation* wasmTranslation, 26 WasmTranslation* wasmTranslation) {
27 int contextGroupId) {
28 String16 scriptId = String16::fromInteger(frame->GetScriptId()); 27 String16 scriptId = String16::fromInteger(frame->GetScriptId());
29 String16 sourceName; 28 String16 sourceName;
30 v8::Local<v8::String> sourceNameValue(frame->GetScriptNameOrSourceURL()); 29 v8::Local<v8::String> sourceNameValue(frame->GetScriptNameOrSourceURL());
31 if (!sourceNameValue.IsEmpty()) 30 if (!sourceNameValue.IsEmpty())
32 sourceName = toProtocolString(sourceNameValue); 31 sourceName = toProtocolString(sourceNameValue);
33 32
34 String16 functionName; 33 String16 functionName;
35 v8::Local<v8::String> functionNameValue(frame->GetFunctionName()); 34 v8::Local<v8::String> functionNameValue(frame->GetFunctionName());
36 if (!functionNameValue.IsEmpty()) 35 if (!functionNameValue.IsEmpty())
37 functionName = toProtocolString(functionNameValue); 36 functionName = toProtocolString(functionNameValue);
38 37
39 int sourceLineNumber = frame->GetLineNumber() - 1; 38 int sourceLineNumber = frame->GetLineNumber() - 1;
40 int sourceColumn = frame->GetColumn() - 1; 39 int sourceColumn = frame->GetColumn() - 1;
41 // TODO(clemensh): Figure out a way to do this translation only right before 40 // TODO(clemensh): Figure out a way to do this translation only right before
42 // sending the stack trace over wire. 41 // sending the stack trace over wire.
43 if (frame->IsWasm()) { 42 if (frame->IsWasm()) {
44 wasmTranslation->TranslateWasmScriptLocationToProtocolLocation( 43 wasmTranslation->TranslateWasmScriptLocationToProtocolLocation(
45 &scriptId, &sourceLineNumber, &sourceColumn); 44 &scriptId, &sourceLineNumber, &sourceColumn);
46 } 45 }
47 return V8StackTraceImpl::Frame(functionName, scriptId, sourceName, 46 return V8StackTraceImpl::Frame(functionName, scriptId, sourceName,
48 sourceLineNumber + 1, sourceColumn + 1); 47 sourceLineNumber + 1, sourceColumn + 1);
49 } 48 }
50 49
51 void toFramesVector(v8::Local<v8::StackTrace> stackTrace, 50 void toFramesVector(v8::Local<v8::StackTrace> stackTrace,
52 std::vector<V8StackTraceImpl::Frame>& frames, 51 std::vector<V8StackTraceImpl::Frame>& frames,
53 size_t maxStackSize, v8::Isolate* isolate, 52 size_t maxStackSize, v8::Isolate* isolate,
54 V8Debugger* debugger, int contextGroupId) { 53 V8Debugger* debugger) {
55 DCHECK(isolate->InContext()); 54 DCHECK(isolate->InContext());
56 int frameCount = stackTrace->GetFrameCount(); 55 int frameCount = stackTrace->GetFrameCount();
57 if (frameCount > static_cast<int>(maxStackSize)) 56 if (frameCount > static_cast<int>(maxStackSize))
58 frameCount = static_cast<int>(maxStackSize); 57 frameCount = static_cast<int>(maxStackSize);
59 WasmTranslation* wasmTranslation = debugger->wasmTranslation(); 58 WasmTranslation* wasmTranslation = debugger->wasmTranslation();
60 for (int i = 0; i < frameCount; i++) { 59 for (int i = 0; i < frameCount; i++) {
61 v8::Local<v8::StackFrame> stackFrame = stackTrace->GetFrame(i); 60 v8::Local<v8::StackFrame> stackFrame = stackTrace->GetFrame(i);
62 frames.push_back(toFrame(stackFrame, wasmTranslation, contextGroupId)); 61 frames.push_back(toFrame(stackFrame, wasmTranslation));
63 } 62 }
64 } 63 }
65 64
66 } // namespace 65 } // namespace
67 66
68 V8StackTraceImpl::Frame::Frame()
69 : m_functionName("undefined"),
70 m_scriptId(""),
71 m_scriptName("undefined"),
72 m_lineNumber(0),
73 m_columnNumber(0) {}
74
75 V8StackTraceImpl::Frame::Frame(const String16& functionName, 67 V8StackTraceImpl::Frame::Frame(const String16& functionName,
76 const String16& scriptId, 68 const String16& scriptId,
77 const String16& scriptName, int lineNumber, 69 const String16& scriptName, int lineNumber,
78 int column) 70 int column)
79 : m_functionName(functionName), 71 : m_functionName(functionName),
80 m_scriptId(scriptId), 72 m_scriptId(scriptId),
81 m_scriptName(scriptName), 73 m_scriptName(scriptName),
82 m_lineNumber(lineNumber), 74 m_lineNumber(lineNumber),
83 m_columnNumber(column) { 75 m_columnNumber(column) {
84 DCHECK(m_lineNumber != v8::Message::kNoLineNumberInfo); 76 DCHECK(m_lineNumber != v8::Message::kNoLineNumberInfo);
85 DCHECK(m_columnNumber != v8::Message::kNoColumnInfo); 77 DCHECK(m_columnNumber != v8::Message::kNoColumnInfo);
86 } 78 }
87 79
88 V8StackTraceImpl::Frame::~Frame() {}
89
90 // buildInspectorObject() and SourceLocation's toTracedValue() should set the 80 // buildInspectorObject() and SourceLocation's toTracedValue() should set the
91 // same fields. 81 // same fields.
92 // If either of them is modified, the other should be also modified. 82 // If either of them is modified, the other should be also modified.
93 std::unique_ptr<protocol::Runtime::CallFrame> 83 std::unique_ptr<protocol::Runtime::CallFrame>
94 V8StackTraceImpl::Frame::buildInspectorObject() const { 84 V8StackTraceImpl::Frame::buildInspectorObject() const {
95 return protocol::Runtime::CallFrame::create() 85 return protocol::Runtime::CallFrame::create()
96 .setFunctionName(m_functionName) 86 .setFunctionName(m_functionName)
97 .setScriptId(m_scriptId) 87 .setScriptId(m_scriptId)
98 .setUrl(m_scriptName) 88 .setUrl(m_scriptName)
99 .setLineNumber(m_lineNumber - 1) 89 .setLineNumber(m_lineNumber - 1)
100 .setColumnNumber(m_columnNumber - 1) 90 .setColumnNumber(m_columnNumber - 1)
101 .build(); 91 .build();
102 } 92 }
103 93
104 V8StackTraceImpl::Frame V8StackTraceImpl::Frame::clone() const {
105 return Frame(m_functionName, m_scriptId, m_scriptName, m_lineNumber,
106 m_columnNumber);
107 }
108
109 // static 94 // static
110 void V8StackTraceImpl::setCaptureStackTraceForUncaughtExceptions( 95 void V8StackTraceImpl::setCaptureStackTraceForUncaughtExceptions(
111 v8::Isolate* isolate, bool capture) { 96 v8::Isolate* isolate, bool capture) {
112 isolate->SetCaptureStackTraceForUncaughtExceptions( 97 isolate->SetCaptureStackTraceForUncaughtExceptions(
113 capture, V8StackTraceImpl::maxCallStackSizeToCapture, stackTraceOptions); 98 capture, V8StackTraceImpl::maxCallStackSizeToCapture, stackTraceOptions);
114 } 99 }
115 100
116 // static 101 // static
117 std::unique_ptr<V8StackTraceImpl> V8StackTraceImpl::create( 102 std::unique_ptr<V8StackTraceImpl> V8StackTraceImpl::create(
118 V8Debugger* debugger, int contextGroupId, 103 V8Debugger* debugger, int contextGroupId,
119 v8::Local<v8::StackTrace> stackTrace, size_t maxStackSize, 104 v8::Local<v8::StackTrace> stackTrace, size_t maxStackSize,
120 const String16& description) { 105 const String16& description) {
121 DCHECK(debugger); 106 DCHECK(debugger);
122 v8::Isolate* isolate = debugger->inspector()->isolate(); 107 v8::Isolate* isolate = debugger->inspector()->isolate();
123 v8::HandleScope scope(isolate); 108 v8::HandleScope scope(isolate);
124 std::vector<V8StackTraceImpl::Frame> frames; 109 std::vector<V8StackTraceImpl::Frame> frames;
125 if (!stackTrace.IsEmpty()) 110 if (!stackTrace.IsEmpty()) {
126 toFramesVector(stackTrace, frames, maxStackSize, isolate, debugger, 111 toFramesVector(stackTrace, frames, maxStackSize, isolate, debugger);
127 contextGroupId); 112 }
128 113
129 int maxAsyncCallChainDepth = 1; 114 int maxAsyncCallChainDepth = 1;
130 V8StackTraceImpl* asyncCallChain = nullptr; 115 V8StackTraceImpl* asyncCallChain = nullptr;
116 V8StackTraceImpl* creationStack = nullptr;
131 if (maxStackSize > 1) { 117 if (maxStackSize > 1) {
132 asyncCallChain = debugger->currentAsyncCallChain(); 118 asyncCallChain = debugger->currentAsyncCallChain();
119 creationStack = debugger->currentAsyncTaskCreationStack();
133 maxAsyncCallChainDepth = debugger->maxAsyncCallChainDepth(); 120 maxAsyncCallChainDepth = debugger->maxAsyncCallChainDepth();
134 } 121 }
122
135 // Do not accidentally append async call chain from another group. This should 123 // Do not accidentally append async call chain from another group. This should
136 // not 124 // not happen if we have proper instrumentation, but let's double-check to be
137 // happen if we have proper instrumentation, but let's double-check to be
138 // safe. 125 // safe.
139 if (contextGroupId && asyncCallChain && asyncCallChain->m_contextGroupId && 126 if (contextGroupId && asyncCallChain && asyncCallChain->m_contextGroupId &&
140 asyncCallChain->m_contextGroupId != contextGroupId) { 127 asyncCallChain->m_contextGroupId != contextGroupId) {
141 asyncCallChain = nullptr; 128 asyncCallChain = nullptr;
129 creationStack = nullptr;
142 maxAsyncCallChainDepth = 1; 130 maxAsyncCallChainDepth = 1;
143 } 131 }
144 132
145 // Only the top stack in the chain may be empty and doesn't contain creation 133 // Only the top stack in the chain may be empty and doesn't contain creation
146 // stack , so ensure that second stack is non-empty (it's the top of appended 134 // stack , so ensure that second stack is non-empty (it's the top of appended
147 // chain). 135 // chain).
148 if (asyncCallChain && asyncCallChain->isEmpty() && 136 if (asyncCallChain && !creationStack && !asyncCallChain->m_creation &&
149 !asyncCallChain->m_creation) { 137 asyncCallChain->isEmpty()) {
150 asyncCallChain = asyncCallChain->m_parent.get(); 138 asyncCallChain = asyncCallChain->m_parent.get();
151 } 139 }
152 140
153 if (stackTrace.IsEmpty() && !asyncCallChain) return nullptr; 141 if (frames.empty() && !creationStack && !asyncCallChain) return nullptr;
142
143 // When async call chain is empty but doesn't contain useful schedule stack
144 // and parent async call chain contains creationg stack but doesn't
145 // synchronous we can merge them together.
146 // e.g. Promise ThenableJob.
147 if (asyncCallChain && frames.empty() &&
148 asyncCallChain->m_description == description && !creationStack) {
149 return asyncCallChain->cloneImpl();
150 }
154 151
155 std::unique_ptr<V8StackTraceImpl> result(new V8StackTraceImpl( 152 std::unique_ptr<V8StackTraceImpl> result(new V8StackTraceImpl(
156 contextGroupId, description, frames, 153 contextGroupId, description, frames,
157 asyncCallChain ? asyncCallChain->cloneImpl() : nullptr)); 154 asyncCallChain ? asyncCallChain->cloneImpl() : nullptr,
155 creationStack ? creationStack->cloneImpl() : nullptr));
158 156
159 // Crop to not exceed maxAsyncCallChainDepth. 157 // Crop to not exceed maxAsyncCallChainDepth.
160 V8StackTraceImpl* deepest = result.get(); 158 V8StackTraceImpl* deepest = result.get();
161 while (deepest && maxAsyncCallChainDepth) { 159 while (deepest && maxAsyncCallChainDepth) {
162 deepest = deepest->m_parent.get(); 160 deepest = deepest->m_parent.get();
163 maxAsyncCallChainDepth--; 161 maxAsyncCallChainDepth--;
164 } 162 }
165 if (deepest) deepest->m_parent.reset(); 163 if (deepest) deepest->m_parent.reset();
166 164
167 return result; 165 return result;
(...skipping 12 matching lines...) Expand all
180 isolate, static_cast<int>(maxStackSize), stackTraceOptions); 178 isolate, static_cast<int>(maxStackSize), stackTraceOptions);
181 } 179 }
182 return V8StackTraceImpl::create(debugger, contextGroupId, stackTrace, 180 return V8StackTraceImpl::create(debugger, contextGroupId, stackTrace,
183 maxStackSize, description); 181 maxStackSize, description);
184 } 182 }
185 183
186 std::unique_ptr<V8StackTraceImpl> V8StackTraceImpl::cloneImpl() { 184 std::unique_ptr<V8StackTraceImpl> V8StackTraceImpl::cloneImpl() {
187 std::vector<Frame> framesCopy(m_frames); 185 std::vector<Frame> framesCopy(m_frames);
188 std::unique_ptr<V8StackTraceImpl> copy( 186 std::unique_ptr<V8StackTraceImpl> copy(
189 new V8StackTraceImpl(m_contextGroupId, m_description, framesCopy, 187 new V8StackTraceImpl(m_contextGroupId, m_description, framesCopy,
190 m_parent ? m_parent->cloneImpl() : nullptr)); 188 m_parent ? m_parent->cloneImpl() : nullptr,
191 if (m_creation) copy->setCreation(m_creation->cloneImpl()); 189 m_creation ? m_creation->cloneImpl() : nullptr));
192 return copy; 190 return copy;
193 } 191 }
194 192
195 std::unique_ptr<V8StackTrace> V8StackTraceImpl::clone() { 193 std::unique_ptr<V8StackTrace> V8StackTraceImpl::clone() {
196 std::vector<Frame> frames; 194 std::vector<Frame> frames;
197 for (size_t i = 0; i < m_frames.size(); i++) 195 for (size_t i = 0; i < m_frames.size(); i++) {
198 frames.push_back(m_frames.at(i).clone()); 196 frames.push_back(m_frames.at(i));
199 return std::unique_ptr<V8StackTraceImpl>( 197 }
200 new V8StackTraceImpl(m_contextGroupId, m_description, frames, nullptr)); 198 return std::unique_ptr<V8StackTraceImpl>(new V8StackTraceImpl(
199 m_contextGroupId, m_description, frames, nullptr, nullptr));
201 } 200 }
202 201
203 V8StackTraceImpl::V8StackTraceImpl(int contextGroupId, 202 V8StackTraceImpl::V8StackTraceImpl(int contextGroupId,
204 const String16& description, 203 const String16& description,
205 std::vector<Frame>& frames, 204 std::vector<Frame>& frames,
206 std::unique_ptr<V8StackTraceImpl> parent) 205 std::unique_ptr<V8StackTraceImpl> parent,
206 std::unique_ptr<V8StackTraceImpl> creation)
207 : m_contextGroupId(contextGroupId), 207 : m_contextGroupId(contextGroupId),
208 m_description(description), 208 m_description(description),
209 m_parent(std::move(parent)) { 209 m_parent(std::move(parent)),
210 m_creation(std::move(creation)) {
210 m_frames.swap(frames); 211 m_frames.swap(frames);
211 } 212 }
212 213
213 V8StackTraceImpl::~V8StackTraceImpl() {} 214 V8StackTraceImpl::~V8StackTraceImpl() {}
214 215
215 void V8StackTraceImpl::setCreation(std::unique_ptr<V8StackTraceImpl> creation) {
216 m_creation = std::move(creation);
217 // When async call chain is empty but doesn't contain useful schedule stack
218 // and parent async call chain contains creationg stack but doesn't
219 // synchronous we can merge them together.
220 // e.g. Promise ThenableJob.
221 if (m_parent && isEmpty() && m_description == m_parent->m_description &&
222 !m_parent->m_creation) {
223 m_frames.swap(m_parent->m_frames);
224 m_parent = std::move(m_parent->m_parent);
225 }
226 }
227
228 StringView V8StackTraceImpl::topSourceURL() const { 216 StringView V8StackTraceImpl::topSourceURL() const {
229 DCHECK(m_frames.size()); 217 DCHECK(m_frames.size());
230 return toStringView(m_frames[0].m_scriptName); 218 return toStringView(m_frames[0].m_scriptName);
231 } 219 }
232 220
233 int V8StackTraceImpl::topLineNumber() const { 221 int V8StackTraceImpl::topLineNumber() const {
234 DCHECK(m_frames.size()); 222 DCHECK(m_frames.size());
235 return m_frames[0].m_lineNumber; 223 return m_frames[0].m_lineNumber;
236 } 224 }
237 225
238 int V8StackTraceImpl::topColumnNumber() const { 226 int V8StackTraceImpl::topColumnNumber() const {
239 DCHECK(m_frames.size()); 227 DCHECK(m_frames.size());
240 return m_frames[0].m_columnNumber; 228 return m_frames[0].m_columnNumber;
241 } 229 }
242 230
243 StringView V8StackTraceImpl::topFunctionName() const { 231 StringView V8StackTraceImpl::topFunctionName() const {
244 DCHECK(m_frames.size()); 232 DCHECK(m_frames.size());
245 return toStringView(m_frames[0].m_functionName); 233 return toStringView(m_frames[0].m_functionName);
246 } 234 }
247 235
248 StringView V8StackTraceImpl::topScriptId() const { 236 StringView V8StackTraceImpl::topScriptId() const {
249 DCHECK(m_frames.size()); 237 DCHECK(m_frames.size());
250 return toStringView(m_frames[0].m_scriptId); 238 return toStringView(m_frames[0].m_scriptId);
251 } 239 }
252 240
253 std::unique_ptr<protocol::Runtime::StackTrace> 241 std::unique_ptr<protocol::Runtime::StackTrace>
254 V8StackTraceImpl::buildInspectorObjectImpl() const { 242 V8StackTraceImpl::buildInspectorObjectImpl() const {
243 return buildInspectorObjectImpl(nullptr);
244 }
245
246 std::unique_ptr<protocol::Runtime::StackTrace>
247 V8StackTraceImpl::buildInspectorObjectImpl(V8StackTraceImpl* creation) const {
255 std::unique_ptr<protocol::Array<protocol::Runtime::CallFrame>> frames = 248 std::unique_ptr<protocol::Array<protocol::Runtime::CallFrame>> frames =
256 protocol::Array<protocol::Runtime::CallFrame>::create(); 249 protocol::Array<protocol::Runtime::CallFrame>::create();
257 for (size_t i = 0; i < m_frames.size(); i++) 250 for (size_t i = 0; i < m_frames.size(); i++)
258 frames->addItem(m_frames.at(i).buildInspectorObject()); 251 frames->addItem(m_frames.at(i).buildInspectorObject());
259 252
260 std::unique_ptr<protocol::Runtime::StackTrace> stackTrace = 253 std::unique_ptr<protocol::Runtime::StackTrace> stackTrace =
261 protocol::Runtime::StackTrace::create() 254 protocol::Runtime::StackTrace::create()
262 .setCallFrames(std::move(frames)) 255 .setCallFrames(std::move(frames))
263 .build(); 256 .build();
264 if (!m_description.isEmpty()) stackTrace->setDescription(m_description); 257 if (!m_description.isEmpty()) stackTrace->setDescription(m_description);
265 if (m_parent) stackTrace->setParent(m_parent->buildInspectorObjectImpl()); 258 if (m_parent) {
266 if (m_creation && m_creation->m_frames.size()) { 259 stackTrace->setParent(m_parent->buildInspectorObjectImpl(m_creation.get()));
260 }
261 if (creation && creation->m_frames.size()) {
267 stackTrace->setPromiseCreationFrame( 262 stackTrace->setPromiseCreationFrame(
268 m_creation->m_frames[0].buildInspectorObject()); 263 creation->m_frames[0].buildInspectorObject());
269 } 264 }
270 return stackTrace; 265 return stackTrace;
271 } 266 }
272 267
268 // static
273 std::unique_ptr<protocol::Runtime::StackTrace> 269 std::unique_ptr<protocol::Runtime::StackTrace>
274 V8StackTraceImpl::buildInspectorObjectForTail(V8Debugger* debugger) const { 270 V8StackTraceImpl::buildInspectorObjectForTail(V8Debugger* debugger) {
275 DCHECK(debugger); 271 DCHECK(debugger);
276 v8::HandleScope handleScope(debugger->inspector()->isolate()); 272 v8::HandleScope handleScope(debugger->inspector()->isolate());
277 // Next call collapses possible empty stack and ensures 273 // Next call collapses possible empty stack and ensures
278 // maxAsyncCallChainDepth. 274 // maxAsyncCallChainDepth.
275 V8StackTraceImpl* asyncChain = debugger->currentAsyncCallChain();
276 if (!asyncChain) return nullptr;
279 std::unique_ptr<V8StackTraceImpl> fullChain = V8StackTraceImpl::create( 277 std::unique_ptr<V8StackTraceImpl> fullChain = V8StackTraceImpl::create(
280 debugger, m_contextGroupId, v8::Local<v8::StackTrace>(), 278 debugger, asyncChain->m_contextGroupId, v8::Local<v8::StackTrace>(),
281 V8StackTraceImpl::maxCallStackSizeToCapture); 279 V8StackTraceImpl::maxCallStackSizeToCapture);
282 if (!fullChain || !fullChain->m_parent) return nullptr; 280 if (!fullChain || !fullChain->m_parent) return nullptr;
283 return fullChain->m_parent->buildInspectorObjectImpl(); 281 return fullChain->m_parent->buildInspectorObjectImpl(
282 fullChain->m_creation.get());
284 } 283 }
285 284
286 std::unique_ptr<protocol::Runtime::API::StackTrace> 285 std::unique_ptr<protocol::Runtime::API::StackTrace>
287 V8StackTraceImpl::buildInspectorObject() const { 286 V8StackTraceImpl::buildInspectorObject() const {
288 return buildInspectorObjectImpl(); 287 return buildInspectorObjectImpl(nullptr);
289 } 288 }
290 289
291 std::unique_ptr<StringBuffer> V8StackTraceImpl::toString() const { 290 std::unique_ptr<StringBuffer> V8StackTraceImpl::toString() const {
292 String16Builder stackTrace; 291 String16Builder stackTrace;
293 for (size_t i = 0; i < m_frames.size(); ++i) { 292 for (size_t i = 0; i < m_frames.size(); ++i) {
294 const Frame& frame = m_frames[i]; 293 const Frame& frame = m_frames[i];
295 stackTrace.append("\n at " + (frame.functionName().length() 294 stackTrace.append("\n at " + (frame.functionName().length()
296 ? frame.functionName() 295 ? frame.functionName()
297 : "(anonymous function)")); 296 : "(anonymous function)"));
298 stackTrace.append(" ("); 297 stackTrace.append(" (");
299 stackTrace.append(frame.sourceURL()); 298 stackTrace.append(frame.sourceURL());
300 stackTrace.append(':'); 299 stackTrace.append(':');
301 stackTrace.append(String16::fromInteger(frame.lineNumber())); 300 stackTrace.append(String16::fromInteger(frame.lineNumber()));
302 stackTrace.append(':'); 301 stackTrace.append(':');
303 stackTrace.append(String16::fromInteger(frame.columnNumber())); 302 stackTrace.append(String16::fromInteger(frame.columnNumber()));
304 stackTrace.append(')'); 303 stackTrace.append(')');
305 } 304 }
306 String16 string = stackTrace.toString(); 305 String16 string = stackTrace.toString();
307 return StringBufferImpl::adopt(string); 306 return StringBufferImpl::adopt(string);
308 } 307 }
309 308
310 } // namespace v8_inspector 309 } // namespace v8_inspector
OLDNEW
« no previous file with comments | « src/inspector/v8-stack-trace-impl.h ('k') | test/inspector/debugger/max-async-call-chain-depth.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698