| 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 |