1bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee// Copyright 2016 the V8 project authors. All rights reserved. 2bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee// Use of this source code is governed by a BSD-style license that can be 3bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee// found in the LICENSE file. 4bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 5bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#include "src/inspector/v8-stack-trace-impl.h" 6bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 7bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#include "src/inspector/string-util.h" 8bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#include "src/inspector/v8-debugger.h" 9bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#include "src/inspector/v8-inspector-impl.h" 10bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#include "src/inspector/v8-profiler-agent-impl.h" 11bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 12bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#include "include/v8-debug.h" 13bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#include "include/v8-profiler.h" 14bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#include "include/v8-version.h" 15bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 16bd8388b4555645b3d29abc6a94c303638064d69awonjong.leenamespace v8_inspector { 17bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 18bd8388b4555645b3d29abc6a94c303638064d69awonjong.leenamespace { 19bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 20bd8388b4555645b3d29abc6a94c303638064d69awonjong.leestatic const v8::StackTrace::StackTraceOptions stackTraceOptions = 21bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee static_cast<v8::StackTrace::StackTraceOptions>( 22bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee v8::StackTrace::kLineNumber | v8::StackTrace::kColumnOffset | 23bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee v8::StackTrace::kScriptId | v8::StackTrace::kScriptNameOrSourceURL | 24bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee v8::StackTrace::kFunctionName); 25bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 26bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeV8StackTraceImpl::Frame toFrame(v8::Local<v8::StackFrame> frame) { 27bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee String16 scriptId = String16::fromInteger(frame->GetScriptId()); 28bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee String16 sourceName; 29bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee v8::Local<v8::String> sourceNameValue(frame->GetScriptNameOrSourceURL()); 30bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if (!sourceNameValue.IsEmpty()) 31bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee sourceName = toProtocolString(sourceNameValue); 32bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 33bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee String16 functionName; 34bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee v8::Local<v8::String> functionNameValue(frame->GetFunctionName()); 35bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if (!functionNameValue.IsEmpty()) 36bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee functionName = toProtocolString(functionNameValue); 37bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 38bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee int sourceLineNumber = frame->GetLineNumber(); 39bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee int sourceColumn = frame->GetColumn(); 40bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee return V8StackTraceImpl::Frame(functionName, scriptId, sourceName, 41bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee sourceLineNumber, sourceColumn); 42bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee} 43bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 44bd8388b4555645b3d29abc6a94c303638064d69awonjong.leevoid toFramesVector(v8::Local<v8::StackTrace> stackTrace, 45bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee std::vector<V8StackTraceImpl::Frame>& frames, 46bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee size_t maxStackSize, v8::Isolate* isolate) { 47bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee DCHECK(isolate->InContext()); 48bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee int frameCount = stackTrace->GetFrameCount(); 49bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if (frameCount > static_cast<int>(maxStackSize)) 50bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee frameCount = static_cast<int>(maxStackSize); 51bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee for (int i = 0; i < frameCount; i++) { 52bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee v8::Local<v8::StackFrame> stackFrame = stackTrace->GetFrame(i); 53bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee frames.push_back(toFrame(stackFrame)); 54bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee } 55bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee} 56bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 57bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee} // namespace 58bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 59bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeV8StackTraceImpl::Frame::Frame() 60bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee : m_functionName("undefined"), 61bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee m_scriptId(""), 62bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee m_scriptName("undefined"), 63bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee m_lineNumber(0), 64bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee m_columnNumber(0) {} 65bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 66bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeV8StackTraceImpl::Frame::Frame(const String16& functionName, 67bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee const String16& scriptId, 68bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee const String16& scriptName, int lineNumber, 69bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee int column) 70bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee : m_functionName(functionName), 71bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee m_scriptId(scriptId), 72bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee m_scriptName(scriptName), 73bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee m_lineNumber(lineNumber), 74bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee m_columnNumber(column) { 75bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee DCHECK(m_lineNumber != v8::Message::kNoLineNumberInfo); 76bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee DCHECK(m_columnNumber != v8::Message::kNoColumnInfo); 77bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee} 78bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 79bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeV8StackTraceImpl::Frame::~Frame() {} 80bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 81bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee// buildInspectorObject() and SourceLocation's toTracedValue() should set the 82bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee// same fields. 83bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee// If either of them is modified, the other should be also modified. 84bd8388b4555645b3d29abc6a94c303638064d69awonjong.leestd::unique_ptr<protocol::Runtime::CallFrame> 85bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeV8StackTraceImpl::Frame::buildInspectorObject() const { 86bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee return protocol::Runtime::CallFrame::create() 87bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee .setFunctionName(m_functionName) 88bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee .setScriptId(m_scriptId) 89bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee .setUrl(m_scriptName) 90bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee .setLineNumber(m_lineNumber - 1) 91bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee .setColumnNumber(m_columnNumber - 1) 92bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee .build(); 93bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee} 94bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 95bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeV8StackTraceImpl::Frame V8StackTraceImpl::Frame::clone() const { 96bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee return Frame(m_functionName, m_scriptId, m_scriptName, m_lineNumber, 97bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee m_columnNumber); 98bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee} 99bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 100bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee// static 101bd8388b4555645b3d29abc6a94c303638064d69awonjong.leevoid V8StackTraceImpl::setCaptureStackTraceForUncaughtExceptions( 102bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee v8::Isolate* isolate, bool capture) { 103bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee isolate->SetCaptureStackTraceForUncaughtExceptions( 104bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee capture, V8StackTraceImpl::maxCallStackSizeToCapture, stackTraceOptions); 105bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee} 106bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 107bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee// static 108bd8388b4555645b3d29abc6a94c303638064d69awonjong.leestd::unique_ptr<V8StackTraceImpl> V8StackTraceImpl::create( 109bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee V8Debugger* debugger, int contextGroupId, 110bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee v8::Local<v8::StackTrace> stackTrace, size_t maxStackSize, 111bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee const String16& description) { 112bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee v8::Isolate* isolate = v8::Isolate::GetCurrent(); 113bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee v8::HandleScope scope(isolate); 114bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee std::vector<V8StackTraceImpl::Frame> frames; 115bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if (!stackTrace.IsEmpty()) 116bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee toFramesVector(stackTrace, frames, maxStackSize, isolate); 117bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 118bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee int maxAsyncCallChainDepth = 1; 119bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee V8StackTraceImpl* asyncCallChain = nullptr; 120bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if (debugger && maxStackSize > 1) { 121bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee asyncCallChain = debugger->currentAsyncCallChain(); 122bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee maxAsyncCallChainDepth = debugger->maxAsyncCallChainDepth(); 123bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee } 124bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee // Do not accidentally append async call chain from another group. This should 125bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee // not 126bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee // happen if we have proper instrumentation, but let's double-check to be 127bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee // safe. 128bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if (contextGroupId && asyncCallChain && asyncCallChain->m_contextGroupId && 129bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee asyncCallChain->m_contextGroupId != contextGroupId) { 130bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee asyncCallChain = nullptr; 131bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee maxAsyncCallChainDepth = 1; 132bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee } 133bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 134bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee // Only the top stack in the chain may be empty, so ensure that second stack 135bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee // is non-empty (it's the top of appended chain). 136bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if (asyncCallChain && asyncCallChain->isEmpty()) 137bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee asyncCallChain = asyncCallChain->m_parent.get(); 138bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 139bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if (stackTrace.IsEmpty() && !asyncCallChain) return nullptr; 140bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 141bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee std::unique_ptr<V8StackTraceImpl> result(new V8StackTraceImpl( 142bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee contextGroupId, description, frames, 143bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee asyncCallChain ? asyncCallChain->cloneImpl() : nullptr)); 144bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 145bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee // Crop to not exceed maxAsyncCallChainDepth. 146bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee V8StackTraceImpl* deepest = result.get(); 147bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee while (deepest && maxAsyncCallChainDepth) { 148bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee deepest = deepest->m_parent.get(); 149bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee maxAsyncCallChainDepth--; 150bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee } 151bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if (deepest) deepest->m_parent.reset(); 152bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 153bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee return result; 154bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee} 155bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 156bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee// static 157bd8388b4555645b3d29abc6a94c303638064d69awonjong.leestd::unique_ptr<V8StackTraceImpl> V8StackTraceImpl::capture( 158bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee V8Debugger* debugger, int contextGroupId, size_t maxStackSize, 159bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee const String16& description) { 160bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee v8::Isolate* isolate = v8::Isolate::GetCurrent(); 161bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee v8::HandleScope handleScope(isolate); 162bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee v8::Local<v8::StackTrace> stackTrace; 163bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if (isolate->InContext()) { 164bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if (debugger) { 165bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee V8InspectorImpl* inspector = debugger->inspector(); 166bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee V8ProfilerAgentImpl* profilerAgent = 167bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee inspector->enabledProfilerAgentForGroup(contextGroupId); 168bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if (profilerAgent) profilerAgent->collectSample(); 169bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee } 170bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee stackTrace = v8::StackTrace::CurrentStackTrace( 171bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee isolate, static_cast<int>(maxStackSize), stackTraceOptions); 172bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee } 173bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee return V8StackTraceImpl::create(debugger, contextGroupId, stackTrace, 174bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee maxStackSize, description); 175bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee} 176bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 177bd8388b4555645b3d29abc6a94c303638064d69awonjong.leestd::unique_ptr<V8StackTraceImpl> V8StackTraceImpl::cloneImpl() { 178bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee std::vector<Frame> framesCopy(m_frames); 179bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee return wrapUnique( 180bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee new V8StackTraceImpl(m_contextGroupId, m_description, framesCopy, 181bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee m_parent ? m_parent->cloneImpl() : nullptr)); 182bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee} 183bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 184bd8388b4555645b3d29abc6a94c303638064d69awonjong.leestd::unique_ptr<V8StackTrace> V8StackTraceImpl::clone() { 185bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee std::vector<Frame> frames; 186bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee for (size_t i = 0; i < m_frames.size(); i++) 187bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee frames.push_back(m_frames.at(i).clone()); 188bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee return wrapUnique( 189bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee new V8StackTraceImpl(m_contextGroupId, m_description, frames, nullptr)); 190bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee} 191bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 192bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeV8StackTraceImpl::V8StackTraceImpl(int contextGroupId, 193bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee const String16& description, 194bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee std::vector<Frame>& frames, 195bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee std::unique_ptr<V8StackTraceImpl> parent) 196bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee : m_contextGroupId(contextGroupId), 197bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee m_description(description), 198bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee m_parent(std::move(parent)) { 199bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee m_frames.swap(frames); 200bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee} 201bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 202bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeV8StackTraceImpl::~V8StackTraceImpl() {} 203bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 204bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeStringView V8StackTraceImpl::topSourceURL() const { 205bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee DCHECK(m_frames.size()); 206bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee return toStringView(m_frames[0].m_scriptName); 207bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee} 208bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 209bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeint V8StackTraceImpl::topLineNumber() const { 210bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee DCHECK(m_frames.size()); 211bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee return m_frames[0].m_lineNumber; 212bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee} 213bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 214bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeint V8StackTraceImpl::topColumnNumber() const { 215bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee DCHECK(m_frames.size()); 216bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee return m_frames[0].m_columnNumber; 217bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee} 218bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 219bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeStringView V8StackTraceImpl::topFunctionName() const { 220bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee DCHECK(m_frames.size()); 221bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee return toStringView(m_frames[0].m_functionName); 222bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee} 223bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 224bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeStringView V8StackTraceImpl::topScriptId() const { 225bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee DCHECK(m_frames.size()); 226bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee return toStringView(m_frames[0].m_scriptId); 227bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee} 228bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 229bd8388b4555645b3d29abc6a94c303638064d69awonjong.leestd::unique_ptr<protocol::Runtime::StackTrace> 230bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeV8StackTraceImpl::buildInspectorObjectImpl() const { 231bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee std::unique_ptr<protocol::Array<protocol::Runtime::CallFrame>> frames = 232bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee protocol::Array<protocol::Runtime::CallFrame>::create(); 233bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee for (size_t i = 0; i < m_frames.size(); i++) 234bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee frames->addItem(m_frames.at(i).buildInspectorObject()); 235bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 236bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee std::unique_ptr<protocol::Runtime::StackTrace> stackTrace = 237bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee protocol::Runtime::StackTrace::create() 238bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee .setCallFrames(std::move(frames)) 239bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee .build(); 240bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if (!m_description.isEmpty()) stackTrace->setDescription(m_description); 241bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if (m_parent) stackTrace->setParent(m_parent->buildInspectorObjectImpl()); 242bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee return stackTrace; 243bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee} 244bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 245bd8388b4555645b3d29abc6a94c303638064d69awonjong.leestd::unique_ptr<protocol::Runtime::StackTrace> 246bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeV8StackTraceImpl::buildInspectorObjectForTail(V8Debugger* debugger) const { 247bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee v8::HandleScope handleScope(v8::Isolate::GetCurrent()); 248bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee // Next call collapses possible empty stack and ensures 249bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee // maxAsyncCallChainDepth. 250bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee std::unique_ptr<V8StackTraceImpl> fullChain = V8StackTraceImpl::create( 251bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee debugger, m_contextGroupId, v8::Local<v8::StackTrace>(), 252bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee V8StackTraceImpl::maxCallStackSizeToCapture); 253bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee if (!fullChain || !fullChain->m_parent) return nullptr; 254bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee return fullChain->m_parent->buildInspectorObjectImpl(); 255bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee} 256bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 257bd8388b4555645b3d29abc6a94c303638064d69awonjong.leestd::unique_ptr<protocol::Runtime::API::StackTrace> 258bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeV8StackTraceImpl::buildInspectorObject() const { 259bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee return buildInspectorObjectImpl(); 260bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee} 261bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 262bd8388b4555645b3d29abc6a94c303638064d69awonjong.leestd::unique_ptr<StringBuffer> V8StackTraceImpl::toString() const { 263bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee String16Builder stackTrace; 264bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee for (size_t i = 0; i < m_frames.size(); ++i) { 265bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee const Frame& frame = m_frames[i]; 266bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee stackTrace.append("\n at " + (frame.functionName().length() 267bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee ? frame.functionName() 268bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee : "(anonymous function)")); 269bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee stackTrace.append(" ("); 270bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee stackTrace.append(frame.sourceURL()); 271bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee stackTrace.append(':'); 272bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee stackTrace.append(String16::fromInteger(frame.lineNumber())); 273bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee stackTrace.append(':'); 274bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee stackTrace.append(String16::fromInteger(frame.columnNumber())); 275bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee stackTrace.append(')'); 276bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee } 277bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee String16 string = stackTrace.toString(); 278bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee return StringBufferImpl::adopt(string); 279bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee} 280bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 281bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee} // namespace v8_inspector 282bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee