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/Platform.h" | 7 #include "platform/inspector_protocol/Platform.h" |
8 #include "platform/inspector_protocol/String16.h" | 8 #include "platform/inspector_protocol/String16.h" |
9 #include "platform/v8_inspector/V8DebuggerImpl.h" | 9 #include "platform/v8_inspector/V8InspectorImpl.h" |
10 #include "platform/v8_inspector/V8StringUtil.h" | 10 #include "platform/v8_inspector/V8StringUtil.h" |
11 | 11 |
12 #include <v8-debug.h> | 12 #include <v8-debug.h> |
13 #include <v8-profiler.h> | 13 #include <v8-profiler.h> |
14 #include <v8-version.h> | 14 #include <v8-version.h> |
15 | 15 |
16 namespace blink { | 16 namespace blink { |
17 | 17 |
18 namespace { | 18 namespace { |
19 | 19 |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 return Frame(m_functionName.isolatedCopy(), m_scriptId.isolatedCopy(), m_scr
iptName.isolatedCopy(), m_lineNumber, m_columnNumber); | 98 return Frame(m_functionName.isolatedCopy(), m_scriptId.isolatedCopy(), m_scr
iptName.isolatedCopy(), m_lineNumber, m_columnNumber); |
99 } | 99 } |
100 | 100 |
101 // static | 101 // static |
102 void V8StackTraceImpl::setCaptureStackTraceForUncaughtExceptions(v8::Isolate* is
olate, bool capture) | 102 void V8StackTraceImpl::setCaptureStackTraceForUncaughtExceptions(v8::Isolate* is
olate, bool capture) |
103 { | 103 { |
104 isolate->SetCaptureStackTraceForUncaughtExceptions(capture, V8StackTraceImpl
::maxCallStackSizeToCapture, stackTraceOptions); | 104 isolate->SetCaptureStackTraceForUncaughtExceptions(capture, V8StackTraceImpl
::maxCallStackSizeToCapture, stackTraceOptions); |
105 } | 105 } |
106 | 106 |
107 // static | 107 // static |
108 std::unique_ptr<V8StackTraceImpl> V8StackTraceImpl::create(V8DebuggerImpl* debug
ger, int contextGroupId, v8::Local<v8::StackTrace> stackTrace, size_t maxStackSi
ze, const String16& description) | 108 std::unique_ptr<V8StackTraceImpl> V8StackTraceImpl::create(V8InspectorImpl* insp
ector, int contextGroupId, v8::Local<v8::StackTrace> stackTrace, size_t maxStack
Size, const String16& description) |
109 { | 109 { |
110 v8::Isolate* isolate = v8::Isolate::GetCurrent(); | 110 v8::Isolate* isolate = v8::Isolate::GetCurrent(); |
111 v8::HandleScope scope(isolate); | 111 v8::HandleScope scope(isolate); |
112 std::vector<V8StackTraceImpl::Frame> frames; | 112 std::vector<V8StackTraceImpl::Frame> frames; |
113 if (!stackTrace.IsEmpty()) | 113 if (!stackTrace.IsEmpty()) |
114 toFramesVector(stackTrace, frames, maxStackSize, isolate); | 114 toFramesVector(stackTrace, frames, maxStackSize, isolate); |
115 | 115 |
116 int maxAsyncCallChainDepth = 1; | 116 int maxAsyncCallChainDepth = 1; |
117 V8StackTraceImpl* asyncCallChain = nullptr; | 117 V8StackTraceImpl* asyncCallChain = nullptr; |
118 if (debugger && maxStackSize > 1) { | 118 if (inspector && maxStackSize > 1) { |
119 asyncCallChain = debugger->currentAsyncCallChain(); | 119 asyncCallChain = inspector->currentAsyncCallChain(); |
120 maxAsyncCallChainDepth = debugger->maxAsyncCallChainDepth(); | 120 maxAsyncCallChainDepth = inspector->maxAsyncCallChainDepth(); |
121 } | 121 } |
122 // Do not accidentally append async call chain from another group. This shou
ld not | 122 // Do not accidentally append async call chain from another group. This shou
ld not |
123 // happen if we have proper instrumentation, but let's double-check to be sa
fe. | 123 // happen if we have proper instrumentation, but let's double-check to be sa
fe. |
124 if (contextGroupId && asyncCallChain && asyncCallChain->m_contextGroupId &&
asyncCallChain->m_contextGroupId != contextGroupId) { | 124 if (contextGroupId && asyncCallChain && asyncCallChain->m_contextGroupId &&
asyncCallChain->m_contextGroupId != contextGroupId) { |
125 asyncCallChain = nullptr; | 125 asyncCallChain = nullptr; |
126 maxAsyncCallChainDepth = 1; | 126 maxAsyncCallChainDepth = 1; |
127 } | 127 } |
128 | 128 |
129 // Only the top stack in the chain may be empty, so ensure that second stack
is non-empty (it's the top of appended chain). | 129 // Only the top stack in the chain may be empty, so ensure that second stack
is non-empty (it's the top of appended chain). |
130 if (asyncCallChain && asyncCallChain->isEmpty()) | 130 if (asyncCallChain && asyncCallChain->isEmpty()) |
131 asyncCallChain = asyncCallChain->m_parent.get(); | 131 asyncCallChain = asyncCallChain->m_parent.get(); |
132 | 132 |
133 if (stackTrace.IsEmpty() && !asyncCallChain) | 133 if (stackTrace.IsEmpty() && !asyncCallChain) |
134 return nullptr; | 134 return nullptr; |
135 | 135 |
136 std::unique_ptr<V8StackTraceImpl> result(new V8StackTraceImpl(contextGroupId
, description, frames, asyncCallChain ? asyncCallChain->cloneImpl() : nullptr)); | 136 std::unique_ptr<V8StackTraceImpl> result(new V8StackTraceImpl(contextGroupId
, description, frames, asyncCallChain ? asyncCallChain->cloneImpl() : nullptr)); |
137 | 137 |
138 // Crop to not exceed maxAsyncCallChainDepth. | 138 // Crop to not exceed maxAsyncCallChainDepth. |
139 V8StackTraceImpl* deepest = result.get(); | 139 V8StackTraceImpl* deepest = result.get(); |
140 while (deepest && maxAsyncCallChainDepth) { | 140 while (deepest && maxAsyncCallChainDepth) { |
141 deepest = deepest->m_parent.get(); | 141 deepest = deepest->m_parent.get(); |
142 maxAsyncCallChainDepth--; | 142 maxAsyncCallChainDepth--; |
143 } | 143 } |
144 if (deepest) | 144 if (deepest) |
145 deepest->m_parent.reset(); | 145 deepest->m_parent.reset(); |
146 | 146 |
147 return result; | 147 return result; |
148 } | 148 } |
149 | 149 |
150 std::unique_ptr<V8StackTraceImpl> V8StackTraceImpl::capture(V8DebuggerImpl* debu
gger, int contextGroupId, size_t maxStackSize, const String16& description) | 150 std::unique_ptr<V8StackTraceImpl> V8StackTraceImpl::capture(V8InspectorImpl* ins
pector, int contextGroupId, size_t maxStackSize, const String16& description) |
151 { | 151 { |
152 v8::Isolate* isolate = v8::Isolate::GetCurrent(); | 152 v8::Isolate* isolate = v8::Isolate::GetCurrent(); |
153 v8::HandleScope handleScope(isolate); | 153 v8::HandleScope handleScope(isolate); |
154 v8::Local<v8::StackTrace> stackTrace; | 154 v8::Local<v8::StackTrace> stackTrace; |
155 if (isolate->InContext()) { | 155 if (isolate->InContext()) { |
156 #if V8_MAJOR_VERSION >= 5 | 156 #if V8_MAJOR_VERSION >= 5 |
157 isolate->GetCpuProfiler()->CollectSample(); | 157 isolate->GetCpuProfiler()->CollectSample(); |
158 #endif | 158 #endif |
159 stackTrace = v8::StackTrace::CurrentStackTrace(isolate, maxStackSize, st
ackTraceOptions); | 159 stackTrace = v8::StackTrace::CurrentStackTrace(isolate, maxStackSize, st
ackTraceOptions); |
160 } | 160 } |
161 return V8StackTraceImpl::create(debugger, contextGroupId, stackTrace, maxSta
ckSize, description); | 161 return V8StackTraceImpl::create(inspector, contextGroupId, stackTrace, maxSt
ackSize, description); |
162 } | 162 } |
163 | 163 |
164 std::unique_ptr<V8StackTrace> V8StackTraceImpl::clone() | 164 std::unique_ptr<V8StackTrace> V8StackTraceImpl::clone() |
165 { | 165 { |
166 return cloneImpl(); | 166 return cloneImpl(); |
167 } | 167 } |
168 | 168 |
169 std::unique_ptr<V8StackTraceImpl> V8StackTraceImpl::cloneImpl() | 169 std::unique_ptr<V8StackTraceImpl> V8StackTraceImpl::cloneImpl() |
170 { | 170 { |
171 std::vector<Frame> framesCopy(m_frames); | 171 std::vector<Frame> framesCopy(m_frames); |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
235 | 235 |
236 std::unique_ptr<protocol::Runtime::StackTrace> stackTrace = protocol::Runtim
e::StackTrace::create() | 236 std::unique_ptr<protocol::Runtime::StackTrace> stackTrace = protocol::Runtim
e::StackTrace::create() |
237 .setCallFrames(std::move(frames)).build(); | 237 .setCallFrames(std::move(frames)).build(); |
238 if (!m_description.isEmpty()) | 238 if (!m_description.isEmpty()) |
239 stackTrace->setDescription(m_description); | 239 stackTrace->setDescription(m_description); |
240 if (m_parent) | 240 if (m_parent) |
241 stackTrace->setParent(m_parent->buildInspectorObjectImpl()); | 241 stackTrace->setParent(m_parent->buildInspectorObjectImpl()); |
242 return stackTrace; | 242 return stackTrace; |
243 } | 243 } |
244 | 244 |
245 std::unique_ptr<protocol::Runtime::StackTrace> V8StackTraceImpl::buildInspectorO
bjectForTail(V8DebuggerImpl* debugger) const | 245 std::unique_ptr<protocol::Runtime::StackTrace> V8StackTraceImpl::buildInspectorO
bjectForTail(V8InspectorImpl* inspector) const |
246 { | 246 { |
247 v8::HandleScope handleScope(v8::Isolate::GetCurrent()); | 247 v8::HandleScope handleScope(v8::Isolate::GetCurrent()); |
248 // Next call collapses possible empty stack and ensures maxAsyncCallChainDep
th. | 248 // Next call collapses possible empty stack and ensures maxAsyncCallChainDep
th. |
249 std::unique_ptr<V8StackTraceImpl> fullChain = V8StackTraceImpl::create(debug
ger, m_contextGroupId, v8::Local<v8::StackTrace>(), V8StackTraceImpl::maxCallSta
ckSizeToCapture); | 249 std::unique_ptr<V8StackTraceImpl> fullChain = V8StackTraceImpl::create(inspe
ctor, m_contextGroupId, v8::Local<v8::StackTrace>(), V8StackTraceImpl::maxCallSt
ackSizeToCapture); |
250 if (!fullChain || !fullChain->m_parent) | 250 if (!fullChain || !fullChain->m_parent) |
251 return nullptr; | 251 return nullptr; |
252 return fullChain->m_parent->buildInspectorObjectImpl(); | 252 return fullChain->m_parent->buildInspectorObjectImpl(); |
253 } | 253 } |
254 | 254 |
255 std::unique_ptr<protocol::Runtime::API::StackTrace> V8StackTraceImpl::buildInspe
ctorObject() const | 255 std::unique_ptr<protocol::Runtime::API::StackTrace> V8StackTraceImpl::buildInspe
ctorObject() const |
256 { | 256 { |
257 return buildInspectorObjectImpl(); | 257 return buildInspectorObjectImpl(); |
258 } | 258 } |
259 | 259 |
260 String16 V8StackTraceImpl::toString() const | 260 String16 V8StackTraceImpl::toString() const |
261 { | 261 { |
262 String16Builder stackTrace; | 262 String16Builder stackTrace; |
263 for (size_t i = 0; i < m_frames.size(); ++i) { | 263 for (size_t i = 0; i < m_frames.size(); ++i) { |
264 const Frame& frame = m_frames[i]; | 264 const Frame& frame = m_frames[i]; |
265 stackTrace.append("\n at " + (frame.functionName().length() ? frame.f
unctionName() : "(anonymous function)")); | 265 stackTrace.append("\n at " + (frame.functionName().length() ? frame.f
unctionName() : "(anonymous function)")); |
266 stackTrace.append(" ("); | 266 stackTrace.append(" ("); |
267 stackTrace.append(frame.sourceURL()); | 267 stackTrace.append(frame.sourceURL()); |
268 stackTrace.append(':'); | 268 stackTrace.append(':'); |
269 stackTrace.appendNumber(frame.lineNumber()); | 269 stackTrace.appendNumber(frame.lineNumber()); |
270 stackTrace.append(':'); | 270 stackTrace.append(':'); |
271 stackTrace.appendNumber(frame.columnNumber()); | 271 stackTrace.appendNumber(frame.columnNumber()); |
272 stackTrace.append(')'); | 272 stackTrace.append(')'); |
273 } | 273 } |
274 return stackTrace.toString(); | 274 return stackTrace.toString(); |
275 } | 275 } |
276 | 276 |
277 } // namespace blink | 277 } // namespace blink |
OLD | NEW |