[inspector] Fix Runtime.setMaxCallStackSizeToCapture
.
This change fixes the implementation of the previously introduced API `Runtime.setMaxCallStackSizeToCapture` to work correctly and also apply (consistently) to stack traces captured by V8 when exceptions are thrown. It does so in a fully backwards compatible manner. This change thus makes the previous fix for catapult (which landed in http://crrev.com/c/3347789) effective, and therefore ensures that real world performance benchmarks aren't affected by the use of the `Runtime` domain in the catapult test framework. Bug: chromium:1283162, chromium:1278650, chromium:1258599 Bug: chromium:1280803, chromium:1280832, chromium:1280818 Fixed: chromium:1280831 Doc: https://bit.ly/v8-cheaper-inspector-stack-traces Change-Id: I4ec951a858317fa49096cd4023deb0104d92c9c9 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3361839 Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Auto-Submit: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/main@{#78458}
This commit is contained in:
parent
d6681cd4a3
commit
34f73cc759
@ -100,12 +100,15 @@ class ConsoleHelper {
|
||||
void reportCall(ConsoleAPIType type,
|
||||
const std::vector<v8::Local<v8::Value>>& arguments) {
|
||||
if (!m_groupId) return;
|
||||
auto stackTrace = V8StackTraceImpl::capture(
|
||||
m_inspector->debugger(),
|
||||
m_inspector->debugger()->maxCallStackSizeToCapture());
|
||||
std::unique_ptr<V8ConsoleMessage> message =
|
||||
V8ConsoleMessage::createForConsoleAPI(
|
||||
m_context, m_contextId, m_groupId, m_inspector,
|
||||
m_inspector->client()->currentTimeMS(), type, arguments,
|
||||
consoleContextToString(m_isolate, m_consoleContext),
|
||||
m_inspector->debugger()->captureStackTrace(false));
|
||||
std::move(stackTrace));
|
||||
consoleMessageStorage()->addMessage(std::move(message));
|
||||
}
|
||||
|
||||
|
@ -77,6 +77,8 @@ V8Debugger::V8Debugger(v8::Isolate* isolate, V8InspectorImpl* inspector)
|
||||
m_continueToLocationBreakpointId(kNoBreakpointId),
|
||||
m_maxAsyncCallStacks(kMaxAsyncTaskStacks),
|
||||
m_maxAsyncCallStackDepth(0),
|
||||
m_maxCallStackSizeToCapture(
|
||||
V8StackTraceImpl::kDefaultMaxCallStackSizeToCapture),
|
||||
m_pauseOnExceptionsState(v8::debug::NoBreakOnException) {}
|
||||
|
||||
V8Debugger::~V8Debugger() {
|
||||
@ -817,8 +819,8 @@ v8::Local<v8::Array> V8Debugger::queryObjects(v8::Local<v8::Context> context,
|
||||
|
||||
std::unique_ptr<V8StackTraceImpl> V8Debugger::createStackTrace(
|
||||
v8::Local<v8::StackTrace> v8StackTrace) {
|
||||
return V8StackTraceImpl::create(this, v8StackTrace,
|
||||
V8StackTraceImpl::maxCallStackSizeToCapture);
|
||||
return V8StackTraceImpl::create(
|
||||
this, v8StackTrace, V8StackTraceImpl::kDefaultMaxCallStackSizeToCapture);
|
||||
}
|
||||
|
||||
void V8Debugger::setAsyncCallStackDepth(V8DebuggerAgentImpl* agent, int depth) {
|
||||
@ -843,6 +845,45 @@ void V8Debugger::setAsyncCallStackDepth(V8DebuggerAgentImpl* agent, int depth) {
|
||||
maxAsyncCallStackDepth ? this : nullptr);
|
||||
}
|
||||
|
||||
void V8Debugger::setMaxCallStackSizeToCapture(V8RuntimeAgentImpl* agent,
|
||||
int size) {
|
||||
if (size < 0) {
|
||||
m_maxCallStackSizeToCaptureMap.erase(agent);
|
||||
} else {
|
||||
m_maxCallStackSizeToCaptureMap[agent] = size;
|
||||
}
|
||||
|
||||
// The following logic is a bit complicated to decipher because we
|
||||
// want to retain backwards compatible semantics:
|
||||
//
|
||||
// (a) When no `Runtime` domain is enabled, we stick to the default
|
||||
// maximum call stack size, but don't let V8 collect stack traces
|
||||
// for uncaught exceptions.
|
||||
// (b) When `Runtime` is enabled for at least one front-end, we compute
|
||||
// the maximum of the requested maximum call stack sizes of all the
|
||||
// front-ends whose `Runtime` domains are enabled (which might be 0),
|
||||
// and ask V8 to collect stack traces for uncaught exceptions.
|
||||
//
|
||||
// The latter allows performance test automation infrastructure to drive
|
||||
// browser via `Runtime` domain while still minimizing the performance
|
||||
// overhead of having the inspector attached - see the relevant design
|
||||
// document https://bit.ly/v8-cheaper-inspector-stack-traces for more
|
||||
// information
|
||||
if (m_maxCallStackSizeToCaptureMap.empty()) {
|
||||
m_maxAsyncCallStackDepth =
|
||||
V8StackTraceImpl::kDefaultMaxCallStackSizeToCapture;
|
||||
m_isolate->SetCaptureStackTraceForUncaughtExceptions(false, 0);
|
||||
} else {
|
||||
m_maxCallStackSizeToCapture = 0;
|
||||
for (auto const& pair : m_maxCallStackSizeToCaptureMap) {
|
||||
if (m_maxCallStackSizeToCapture < pair.second)
|
||||
m_maxCallStackSizeToCapture = pair.second;
|
||||
}
|
||||
m_isolate->SetCaptureStackTraceForUncaughtExceptions(
|
||||
m_maxCallStackSizeToCapture > 0, m_maxCallStackSizeToCapture);
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<AsyncStackTrace> V8Debugger::stackTraceFor(
|
||||
int contextGroupId, const V8StackTraceId& id) {
|
||||
if (debuggerIdFor(contextGroupId).pair() != id.debugger_id) return nullptr;
|
||||
@ -860,8 +901,7 @@ V8StackTraceId V8Debugger::storeCurrentStackTrace(
|
||||
if (!contextGroupId) return V8StackTraceId();
|
||||
|
||||
std::shared_ptr<AsyncStackTrace> asyncStack =
|
||||
AsyncStackTrace::capture(this, toString16(description),
|
||||
V8StackTraceImpl::maxCallStackSizeToCapture);
|
||||
AsyncStackTrace::capture(this, toString16(description));
|
||||
if (!asyncStack) return V8StackTraceId();
|
||||
|
||||
uintptr_t id = AsyncStackTrace::store(this, asyncStack);
|
||||
@ -938,9 +978,8 @@ void V8Debugger::asyncTaskScheduledForStack(const StringView& taskName,
|
||||
bool skipTopFrame) {
|
||||
if (!m_maxAsyncCallStackDepth) return;
|
||||
v8::HandleScope scope(m_isolate);
|
||||
std::shared_ptr<AsyncStackTrace> asyncStack = AsyncStackTrace::capture(
|
||||
this, toString16(taskName), V8StackTraceImpl::maxCallStackSizeToCapture,
|
||||
skipTopFrame);
|
||||
std::shared_ptr<AsyncStackTrace> asyncStack =
|
||||
AsyncStackTrace::capture(this, toString16(taskName), skipTopFrame);
|
||||
if (asyncStack) {
|
||||
m_asyncTaskStacks[task] = asyncStack;
|
||||
if (recurring) m_recurringTasks.insert(task);
|
||||
@ -1044,20 +1083,17 @@ void V8Debugger::unmuteScriptParsedEvents() {
|
||||
|
||||
std::unique_ptr<V8StackTraceImpl> V8Debugger::captureStackTrace(
|
||||
bool fullStack) {
|
||||
if (!m_isolate->InContext()) return nullptr;
|
||||
|
||||
v8::HandleScope handles(m_isolate);
|
||||
int contextGroupId = currentContextGroupId();
|
||||
if (!contextGroupId) return nullptr;
|
||||
|
||||
int stackSize = 1;
|
||||
if (fullStack) {
|
||||
stackSize = V8StackTraceImpl::maxCallStackSizeToCapture;
|
||||
stackSize = V8StackTraceImpl::kDefaultMaxCallStackSizeToCapture;
|
||||
} else {
|
||||
m_inspector->forEachSession(
|
||||
contextGroupId, [&stackSize](V8InspectorSessionImpl* session) {
|
||||
if (session->runtimeAgent()->enabled())
|
||||
stackSize = V8StackTraceImpl::maxCallStackSizeToCapture;
|
||||
stackSize = V8StackTraceImpl::kDefaultMaxCallStackSizeToCapture;
|
||||
});
|
||||
}
|
||||
return V8StackTraceImpl::capture(this, stackSize);
|
||||
|
@ -27,6 +27,7 @@ class StackFrame;
|
||||
class V8Debugger;
|
||||
class V8DebuggerAgentImpl;
|
||||
class V8InspectorImpl;
|
||||
class V8RuntimeAgentImpl;
|
||||
class V8StackTraceImpl;
|
||||
struct V8StackTraceId;
|
||||
|
||||
@ -85,6 +86,9 @@ class V8Debugger : public v8::debug::DebugDelegate,
|
||||
int maxAsyncCallChainDepth() { return m_maxAsyncCallStackDepth; }
|
||||
void setAsyncCallStackDepth(V8DebuggerAgentImpl*, int);
|
||||
|
||||
int maxCallStackSizeToCapture() const { return m_maxCallStackSizeToCapture; }
|
||||
void setMaxCallStackSizeToCapture(V8RuntimeAgentImpl*, int);
|
||||
|
||||
std::shared_ptr<AsyncStackTrace> currentAsyncParent();
|
||||
V8StackTraceId currentExternalParent();
|
||||
|
||||
@ -248,6 +252,7 @@ class V8Debugger : public v8::debug::DebugDelegate,
|
||||
|
||||
size_t m_maxAsyncCallStacks;
|
||||
int m_maxAsyncCallStackDepth;
|
||||
int m_maxCallStackSizeToCapture;
|
||||
|
||||
std::vector<void*> m_currentTasks;
|
||||
std::vector<std::shared_ptr<AsyncStackTrace>> m_currentAsyncParent;
|
||||
@ -259,6 +264,7 @@ class V8Debugger : public v8::debug::DebugDelegate,
|
||||
std::list<std::shared_ptr<AsyncStackTrace>> m_allAsyncStacks;
|
||||
|
||||
std::unordered_map<V8DebuggerAgentImpl*, int> m_maxAsyncCallStackDepthMap;
|
||||
std::unordered_map<V8RuntimeAgentImpl*, int> m_maxCallStackSizeToCaptureMap;
|
||||
void* m_taskWithScheduledBreak = nullptr;
|
||||
|
||||
// If any of the following three is true, we schedule pause on next JS
|
||||
|
@ -62,7 +62,6 @@ V8InspectorImpl::V8InspectorImpl(v8::Isolate* isolate,
|
||||
: m_isolate(isolate),
|
||||
m_client(client),
|
||||
m_debugger(new V8Debugger(isolate, this)),
|
||||
m_capturingStackTracesCount(0),
|
||||
m_lastExceptionId(0),
|
||||
m_lastContextId(0),
|
||||
m_isolateId(generateUniqueId()) {
|
||||
@ -112,19 +111,6 @@ v8::MaybeLocal<v8::Script> V8InspectorImpl::compileScript(
|
||||
v8::ScriptCompiler::kNoCompileOptions);
|
||||
}
|
||||
|
||||
void V8InspectorImpl::enableStackCapturingIfNeeded() {
|
||||
if (!m_capturingStackTracesCount)
|
||||
V8StackTraceImpl::setCaptureStackTraceForUncaughtExceptions(m_isolate,
|
||||
true);
|
||||
++m_capturingStackTracesCount;
|
||||
}
|
||||
|
||||
void V8InspectorImpl::disableStackCapturingIfNeeded() {
|
||||
if (!(--m_capturingStackTracesCount))
|
||||
V8StackTraceImpl::setCaptureStackTraceForUncaughtExceptions(m_isolate,
|
||||
false);
|
||||
}
|
||||
|
||||
void V8InspectorImpl::muteExceptions(int contextGroupId) {
|
||||
m_muteExceptionsMap[contextGroupId]++;
|
||||
}
|
||||
|
@ -115,8 +115,6 @@ class V8InspectorImpl : public V8Inspector {
|
||||
v8::Local<v8::Name> key, v8::Local<v8::Value> value) override;
|
||||
|
||||
unsigned nextExceptionId() { return ++m_lastExceptionId; }
|
||||
void enableStackCapturingIfNeeded();
|
||||
void disableStackCapturingIfNeeded();
|
||||
void muteExceptions(int contextGroupId);
|
||||
void unmuteExceptions(int contextGroupId);
|
||||
V8ConsoleMessageStorage* ensureConsoleMessageStorage(int contextGroupId);
|
||||
@ -160,7 +158,6 @@ class V8InspectorImpl : public V8Inspector {
|
||||
v8::Global<v8::Context> m_regexContext;
|
||||
v8::Global<v8::Context> m_exceptionMetaDataContext;
|
||||
v8::Global<v8::debug::EphemeronTable> m_exceptionMetaData;
|
||||
int m_capturingStackTracesCount;
|
||||
unsigned m_lastExceptionId;
|
||||
int m_lastContextId;
|
||||
int m_lastSessionId = 0;
|
||||
|
@ -145,15 +145,14 @@ std::unique_ptr<protocol::Profiler::Profile> createCPUProfile(
|
||||
|
||||
std::unique_ptr<protocol::Debugger::Location> currentDebugLocation(
|
||||
V8InspectorImpl* inspector) {
|
||||
std::unique_ptr<V8StackTraceImpl> callStack =
|
||||
inspector->debugger()->captureStackTrace(false /* fullStack */);
|
||||
auto location =
|
||||
protocol::Debugger::Location::create()
|
||||
.setScriptId(String16::fromInteger(callStack->topScriptId()))
|
||||
.setLineNumber(callStack->topLineNumber())
|
||||
.build();
|
||||
location->setColumnNumber(callStack->topColumnNumber());
|
||||
return location;
|
||||
auto stackTrace = V8StackTraceImpl::capture(inspector->debugger(), 1);
|
||||
CHECK(stackTrace);
|
||||
CHECK(!stackTrace->isEmpty());
|
||||
return protocol::Debugger::Location::create()
|
||||
.setScriptId(String16::fromInteger(stackTrace->topScriptId()))
|
||||
.setLineNumber(stackTrace->topLineNumber())
|
||||
.setColumnNumber(stackTrace->topColumnNumber())
|
||||
.build();
|
||||
}
|
||||
|
||||
volatile int s_lastProfileId = 0;
|
||||
@ -213,10 +212,9 @@ void V8ProfilerAgentImpl::consoleProfileEnd(const String16& title) {
|
||||
std::unique_ptr<protocol::Profiler::Profile> profile =
|
||||
stopProfiling(id, true);
|
||||
if (!profile) return;
|
||||
std::unique_ptr<protocol::Debugger::Location> location =
|
||||
currentDebugLocation(m_session->inspector());
|
||||
m_frontend.consoleProfileFinished(id, std::move(location), std::move(profile),
|
||||
resolvedTitle);
|
||||
m_frontend.consoleProfileFinished(
|
||||
id, currentDebugLocation(m_session->inspector()), std::move(profile),
|
||||
resolvedTitle);
|
||||
}
|
||||
|
||||
Response V8ProfilerAgentImpl::enable() {
|
||||
|
@ -57,6 +57,7 @@ namespace v8_inspector {
|
||||
namespace V8RuntimeAgentImplState {
|
||||
static const char customObjectFormatterEnabled[] =
|
||||
"customObjectFormatterEnabled";
|
||||
static const char maxCallStackSizeToCapture[] = "maxCallStackSizeToCapture";
|
||||
static const char runtimeEnabled[] = "runtimeEnabled";
|
||||
static const char bindings[] = "bindings";
|
||||
static const char globalBindingsKey[] = "";
|
||||
@ -499,7 +500,9 @@ Response V8RuntimeAgentImpl::setMaxCallStackSizeToCapture(int size) {
|
||||
return Response::ServerError(
|
||||
"maxCallStackSizeToCapture should be non-negative");
|
||||
}
|
||||
V8StackTraceImpl::maxCallStackSizeToCapture = size;
|
||||
if (!m_enabled) return Response::ServerError("Runtime agent is not enabled");
|
||||
m_state->setInteger(V8RuntimeAgentImplState::maxCallStackSizeToCapture, size);
|
||||
m_inspector->debugger()->setMaxCallStackSizeToCapture(this, size);
|
||||
return Response::Success();
|
||||
}
|
||||
|
||||
@ -839,6 +842,11 @@ void V8RuntimeAgentImpl::restore() {
|
||||
V8RuntimeAgentImplState::customObjectFormatterEnabled, false))
|
||||
m_session->setCustomObjectFormatterEnabled(true);
|
||||
|
||||
int size;
|
||||
if (m_state->getInteger(V8RuntimeAgentImplState::maxCallStackSizeToCapture,
|
||||
&size))
|
||||
m_inspector->debugger()->setMaxCallStackSizeToCapture(this, size);
|
||||
|
||||
m_inspector->forEachContext(
|
||||
m_session->contextGroupId(),
|
||||
[this](InspectedContext* context) { addBindings(context); });
|
||||
@ -850,7 +858,8 @@ Response V8RuntimeAgentImpl::enable() {
|
||||
m_session->contextGroupId());
|
||||
m_enabled = true;
|
||||
m_state->setBoolean(V8RuntimeAgentImplState::runtimeEnabled, true);
|
||||
m_inspector->enableStackCapturingIfNeeded();
|
||||
m_inspector->debugger()->setMaxCallStackSizeToCapture(
|
||||
this, V8StackTraceImpl::kDefaultMaxCallStackSizeToCapture);
|
||||
m_session->reportAllContexts(this);
|
||||
V8ConsoleMessageStorage* storage =
|
||||
m_inspector->ensureConsoleMessageStorage(m_session->contextGroupId());
|
||||
@ -865,7 +874,7 @@ Response V8RuntimeAgentImpl::disable() {
|
||||
m_enabled = false;
|
||||
m_state->setBoolean(V8RuntimeAgentImplState::runtimeEnabled, false);
|
||||
m_state->remove(V8RuntimeAgentImplState::bindings);
|
||||
m_inspector->disableStackCapturingIfNeeded();
|
||||
m_inspector->debugger()->setMaxCallStackSizeToCapture(this, -1);
|
||||
m_session->setCustomObjectFormatterEnabled(false);
|
||||
reset();
|
||||
m_inspector->client()->endEnsureAllContextsInGroup(
|
||||
|
@ -22,9 +22,6 @@ using v8_crdtp::json::ConvertCBORToJSON;
|
||||
using v8_crdtp::json::ConvertJSONToCBOR;
|
||||
|
||||
namespace v8_inspector {
|
||||
|
||||
int V8StackTraceImpl::maxCallStackSizeToCapture = 200;
|
||||
|
||||
namespace {
|
||||
|
||||
static const char kId[] = "id";
|
||||
@ -221,13 +218,6 @@ bool StackFrame::isEqual(StackFrame* frame) const {
|
||||
m_columnNumber == frame->m_columnNumber;
|
||||
}
|
||||
|
||||
// static
|
||||
void V8StackTraceImpl::setCaptureStackTraceForUncaughtExceptions(
|
||||
v8::Isolate* isolate, bool capture) {
|
||||
isolate->SetCaptureStackTraceForUncaughtExceptions(
|
||||
capture, V8StackTraceImpl::maxCallStackSizeToCapture);
|
||||
}
|
||||
|
||||
// static
|
||||
std::unique_ptr<V8StackTraceImpl> V8StackTraceImpl::create(
|
||||
V8Debugger* debugger, v8::Local<v8::StackTrace> v8StackTrace,
|
||||
@ -398,10 +388,10 @@ StackFrame* V8StackTraceImpl::StackFrameIterator::frame() {
|
||||
|
||||
// static
|
||||
std::shared_ptr<AsyncStackTrace> AsyncStackTrace::capture(
|
||||
V8Debugger* debugger, const String16& description, int maxStackSize,
|
||||
bool skipTopFrame) {
|
||||
V8Debugger* debugger, const String16& description, bool skipTopFrame) {
|
||||
DCHECK(debugger);
|
||||
|
||||
int maxStackSize = debugger->maxCallStackSizeToCapture();
|
||||
TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("v8.stack_trace"),
|
||||
"AsyncStackTrace::capture", "maxFrameCount", maxStackSize);
|
||||
|
||||
|
@ -51,9 +51,8 @@ class StackFrame {
|
||||
|
||||
class V8StackTraceImpl : public V8StackTrace {
|
||||
public:
|
||||
static void setCaptureStackTraceForUncaughtExceptions(v8::Isolate*,
|
||||
bool capture);
|
||||
static int maxCallStackSizeToCapture;
|
||||
static constexpr int kDefaultMaxCallStackSizeToCapture = 200;
|
||||
|
||||
static std::unique_ptr<V8StackTraceImpl> create(V8Debugger*,
|
||||
v8::Local<v8::StackTrace>,
|
||||
int maxStackSize);
|
||||
@ -117,7 +116,6 @@ class AsyncStackTrace {
|
||||
AsyncStackTrace& operator=(const AsyncStackTrace&) = delete;
|
||||
static std::shared_ptr<AsyncStackTrace> capture(V8Debugger*,
|
||||
const String16& description,
|
||||
int maxStackSize,
|
||||
bool skipTopFrame = false);
|
||||
static uintptr_t store(V8Debugger* debugger,
|
||||
std::shared_ptr<AsyncStackTrace> stack);
|
||||
|
@ -1,4 +1,6 @@
|
||||
Checks Runtime.setMaxCallStackSizeToCapture.
|
||||
|
||||
Running test: testConsoleTrace
|
||||
Test with max size 0.
|
||||
{
|
||||
args : [
|
||||
@ -23,9 +25,9 @@ Test with max size 1.
|
||||
stackTrace : {
|
||||
callFrames : [
|
||||
[0] : {
|
||||
columnNumber : 10
|
||||
columnNumber : 12
|
||||
functionName : bar
|
||||
lineNumber : 2
|
||||
lineNumber : 3
|
||||
scriptId : <scriptId>
|
||||
url : test.js
|
||||
}
|
||||
@ -33,9 +35,9 @@ Test with max size 1.
|
||||
parent : {
|
||||
callFrames : [
|
||||
[0] : {
|
||||
columnNumber : 2
|
||||
functionName : test
|
||||
lineNumber : 10
|
||||
columnNumber : 4
|
||||
functionName : executor
|
||||
lineNumber : 12
|
||||
scriptId : <scriptId>
|
||||
url : test.js
|
||||
}
|
||||
@ -58,16 +60,16 @@ Test with max size 2.
|
||||
stackTrace : {
|
||||
callFrames : [
|
||||
[0] : {
|
||||
columnNumber : 10
|
||||
columnNumber : 12
|
||||
functionName : bar
|
||||
lineNumber : 2
|
||||
lineNumber : 3
|
||||
scriptId : <scriptId>
|
||||
url : test.js
|
||||
}
|
||||
[1] : {
|
||||
columnNumber : 2
|
||||
columnNumber : 4
|
||||
functionName : foo
|
||||
lineNumber : 6
|
||||
lineNumber : 8
|
||||
scriptId : <scriptId>
|
||||
url : test.js
|
||||
}
|
||||
@ -75,18 +77,18 @@ Test with max size 2.
|
||||
parent : {
|
||||
callFrames : [
|
||||
[0] : {
|
||||
columnNumber : 2
|
||||
functionName : test
|
||||
lineNumber : 10
|
||||
columnNumber : 4
|
||||
functionName : executor
|
||||
lineNumber : 12
|
||||
scriptId : <scriptId>
|
||||
url : test.js
|
||||
}
|
||||
[1] : {
|
||||
columnNumber : 0
|
||||
functionName :
|
||||
lineNumber : 0
|
||||
columnNumber : 9
|
||||
functionName : testConsoleTrace
|
||||
lineNumber : 11
|
||||
scriptId : <scriptId>
|
||||
url : expr.js
|
||||
url : test.js
|
||||
}
|
||||
]
|
||||
description : setTimeout
|
||||
@ -95,3 +97,172 @@ Test with max size 2.
|
||||
timestamp : <timestamp>
|
||||
type : trace
|
||||
}
|
||||
|
||||
Running test: testException
|
||||
{
|
||||
args : [
|
||||
[0] : {
|
||||
type : string
|
||||
value : Nested call.
|
||||
}
|
||||
]
|
||||
executionContextId : <executionContextId>
|
||||
timestamp : <timestamp>
|
||||
type : trace
|
||||
}
|
||||
{
|
||||
args : [
|
||||
[0] : {
|
||||
type : string
|
||||
value : Nested call.
|
||||
}
|
||||
]
|
||||
executionContextId : <executionContextId>
|
||||
stackTrace : {
|
||||
callFrames : [
|
||||
[0] : {
|
||||
columnNumber : 12
|
||||
functionName : bar
|
||||
lineNumber : 3
|
||||
scriptId : <scriptId>
|
||||
url : test.js
|
||||
}
|
||||
]
|
||||
parent : {
|
||||
callFrames : [
|
||||
[0] : {
|
||||
columnNumber : 4
|
||||
functionName : executor
|
||||
lineNumber : 12
|
||||
scriptId : <scriptId>
|
||||
url : test.js
|
||||
}
|
||||
]
|
||||
description : setTimeout
|
||||
}
|
||||
}
|
||||
timestamp : <timestamp>
|
||||
type : trace
|
||||
}
|
||||
{
|
||||
args : [
|
||||
[0] : {
|
||||
type : string
|
||||
value : Nested call.
|
||||
}
|
||||
]
|
||||
executionContextId : <executionContextId>
|
||||
stackTrace : {
|
||||
callFrames : [
|
||||
[0] : {
|
||||
columnNumber : 12
|
||||
functionName : bar
|
||||
lineNumber : 3
|
||||
scriptId : <scriptId>
|
||||
url : test.js
|
||||
}
|
||||
[1] : {
|
||||
columnNumber : 4
|
||||
functionName : foo
|
||||
lineNumber : 8
|
||||
scriptId : <scriptId>
|
||||
url : test.js
|
||||
}
|
||||
]
|
||||
parent : {
|
||||
callFrames : [
|
||||
[0] : {
|
||||
columnNumber : 4
|
||||
functionName : executor
|
||||
lineNumber : 12
|
||||
scriptId : <scriptId>
|
||||
url : test.js
|
||||
}
|
||||
[1] : {
|
||||
columnNumber : 9
|
||||
functionName : testConsoleTrace
|
||||
lineNumber : 11
|
||||
scriptId : <scriptId>
|
||||
url : test.js
|
||||
}
|
||||
]
|
||||
description : setTimeout
|
||||
}
|
||||
}
|
||||
timestamp : <timestamp>
|
||||
type : trace
|
||||
}
|
||||
Test with max size 0.
|
||||
{
|
||||
columnNumber : 4
|
||||
exception : {
|
||||
className : Error
|
||||
description : Error at bar (test.js:19:11) at foo (test.js:23:5) at testThrow (test.js:26:3) at <anonymous>:1:1
|
||||
objectId : <objectId>
|
||||
subtype : error
|
||||
type : object
|
||||
}
|
||||
exceptionId : <exceptionId>
|
||||
lineNumber : 18
|
||||
scriptId : <scriptId>
|
||||
text : Uncaught
|
||||
}
|
||||
Test with max size 1.
|
||||
{
|
||||
columnNumber : 4
|
||||
exception : {
|
||||
className : Error
|
||||
description : Error at bar (test.js:19:11) at foo (test.js:23:5) at testThrow (test.js:26:3) at <anonymous>:1:1
|
||||
objectId : <objectId>
|
||||
subtype : error
|
||||
type : object
|
||||
}
|
||||
exceptionId : <exceptionId>
|
||||
lineNumber : 18
|
||||
scriptId : <scriptId>
|
||||
stackTrace : {
|
||||
callFrames : [
|
||||
[0] : {
|
||||
columnNumber : 10
|
||||
functionName : bar
|
||||
lineNumber : 18
|
||||
scriptId : <scriptId>
|
||||
url : test.js
|
||||
}
|
||||
]
|
||||
}
|
||||
text : Uncaught
|
||||
}
|
||||
Test with max size 2.
|
||||
{
|
||||
columnNumber : 4
|
||||
exception : {
|
||||
className : Error
|
||||
description : Error at bar (test.js:19:11) at foo (test.js:23:5) at testThrow (test.js:26:3) at <anonymous>:1:1
|
||||
objectId : <objectId>
|
||||
subtype : error
|
||||
type : object
|
||||
}
|
||||
exceptionId : <exceptionId>
|
||||
lineNumber : 18
|
||||
scriptId : <scriptId>
|
||||
stackTrace : {
|
||||
callFrames : [
|
||||
[0] : {
|
||||
columnNumber : 10
|
||||
functionName : bar
|
||||
lineNumber : 18
|
||||
scriptId : <scriptId>
|
||||
url : test.js
|
||||
}
|
||||
[1] : {
|
||||
columnNumber : 4
|
||||
functionName : foo
|
||||
lineNumber : 22
|
||||
scriptId : <scriptId>
|
||||
url : test.js
|
||||
}
|
||||
]
|
||||
}
|
||||
text : Uncaught
|
||||
}
|
||||
|
@ -4,34 +4,62 @@
|
||||
|
||||
let {session, contextGroup, Protocol} = InspectorTest.start('Checks Runtime.setMaxCallStackSizeToCapture.');
|
||||
|
||||
Protocol.Runtime.enable();
|
||||
Protocol.Runtime.onConsoleAPICalled(
|
||||
message => InspectorTest.logMessage(message.params));
|
||||
({params}) => InspectorTest.logMessage(params));
|
||||
|
||||
contextGroup.addScript(`
|
||||
function bar() {
|
||||
console.trace("Nested call.");
|
||||
function testConsoleTrace() {
|
||||
function bar(callback) {
|
||||
console.trace("Nested call.");
|
||||
callback();
|
||||
}
|
||||
|
||||
function foo(callback) {
|
||||
bar(callback);
|
||||
}
|
||||
|
||||
return new Promise(function executor(resolve) {
|
||||
setTimeout(foo.bind(undefined, resolve), 0);
|
||||
});
|
||||
}
|
||||
|
||||
function foo() {
|
||||
bar();
|
||||
}
|
||||
function testThrow() {
|
||||
function bar() {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
async function test() {
|
||||
setTimeout(foo, 0);
|
||||
function foo() {
|
||||
bar();
|
||||
}
|
||||
|
||||
foo();
|
||||
}
|
||||
//# sourceURL=test.js`);
|
||||
|
||||
Protocol.Runtime.setAsyncCallStackDepth({maxDepth: 10});
|
||||
(async function test() {
|
||||
await Protocol.Runtime.setMaxCallStackSizeToCapture({size: 0});
|
||||
InspectorTest.log('Test with max size 0.');
|
||||
await Protocol.Runtime.evaluate({ expression: 'test()//# sourceURL=expr.js'});
|
||||
await Protocol.Runtime.setMaxCallStackSizeToCapture({size: 1});
|
||||
InspectorTest.log('Test with max size 1.');
|
||||
await Protocol.Runtime.evaluate({ expression: 'test()//# sourceURL=expr.js'});
|
||||
await Protocol.Runtime.setMaxCallStackSizeToCapture({size: 2});
|
||||
InspectorTest.log('Test with max size 2.');
|
||||
await Protocol.Runtime.evaluate({ expression: 'test()//# sourceURL=expr.js'});
|
||||
InspectorTest.completeTest();
|
||||
})();
|
||||
InspectorTest.runAsyncTestSuite([
|
||||
async function testConsoleTrace() {
|
||||
await Promise.all([
|
||||
Protocol.Runtime.enable(),
|
||||
Protocol.Runtime.setAsyncCallStackDepth({maxDepth: 10}),
|
||||
]);
|
||||
for (let size = 0; size <= 2; ++size) {
|
||||
await Protocol.Runtime.setMaxCallStackSizeToCapture({size});
|
||||
InspectorTest.log(`Test with max size ${size}.`);
|
||||
await Protocol.Runtime.evaluate(
|
||||
{expression: 'testConsoleTrace()', awaitPromise: true});
|
||||
}
|
||||
await Protocol.Runtime.disable();
|
||||
},
|
||||
|
||||
async function testException() {
|
||||
await Protocol.Runtime.enable();
|
||||
for (let size = 0; size <= 2; ++size) {
|
||||
await Protocol.Runtime.setMaxCallStackSizeToCapture({size});
|
||||
InspectorTest.log(`Test with max size ${size}.`);
|
||||
const {result: {exceptionDetails}} =
|
||||
await Protocol.Runtime.evaluate({expression: 'testThrow()'});
|
||||
InspectorTest.logMessage(exceptionDetails);
|
||||
}
|
||||
await Protocol.Runtime.disable();
|
||||
}
|
||||
])
|
||||
|
Loading…
Reference in New Issue
Block a user