[inspector] added V8InspectorClient::resourceNameToUrl
Some clients (see Node.js) use platform path as ScriptOrigin. Reporting platform path in protocol makes using protocol much harder. This CL introduced V8InspectorClient::resourceNameToUrl method that is called for any reported using protocol url. V8Inspector uses url internally as well so protocol client may generate pattern for blackboxing with file urls only and does not need to build complicated regexp that covers files urls and platform paths on different platforms. R=lushnikov@chromium.org TBR=yangguo@chromium.org Bug: none Cq-Include-Trybots: luci.chromium.try:linux_chromium_headless_rel;luci.chromium.try:linux_chromium_rel_ng;master.tryserver.blink:linux_trusty_blink_rel Change-Id: Iff302e7441df922fa5d689fe510f5a9bfd470b9b Reviewed-on: https://chromium-review.googlesource.com/1164624 Commit-Queue: Aleksey Kozyatinskiy <kozyatinskiy@chromium.org> Reviewed-by: Alexei Filippov <alph@chromium.org> Cr-Commit-Position: refs/heads/master@{#55029}
This commit is contained in:
parent
e7fad930a8
commit
dbfcc4878a
@ -215,6 +215,11 @@ class V8_EXPORT V8InspectorClient {
|
||||
virtual bool canExecuteScripts(int contextGroupId) { return true; }
|
||||
|
||||
virtual void maxAsyncCallStackDepthChanged(int depth) {}
|
||||
|
||||
virtual std::unique_ptr<StringBuffer> resourceNameToUrl(
|
||||
const StringView& resourceName) {
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
// These stack trace ids are intended to be passed between debuggers and be
|
||||
|
@ -1397,7 +1397,7 @@ void V8DebuggerAgentImpl::didParseSource(
|
||||
protocol::StringUtil::parseJSON(inspected->auxData()));
|
||||
}
|
||||
bool isLiveEdit = script->isLiveEdit();
|
||||
bool hasSourceURL = script->hasSourceURL();
|
||||
bool hasSourceURLComment = script->hasSourceURLComment();
|
||||
bool isModule = script->isModule();
|
||||
String16 scriptId = script->scriptId();
|
||||
String16 scriptURL = script->sourceURL();
|
||||
@ -1417,7 +1417,8 @@ void V8DebuggerAgentImpl::didParseSource(
|
||||
Maybe<protocol::DictionaryValue> executionContextAuxDataParam(
|
||||
std::move(executionContextAuxData));
|
||||
const bool* isLiveEditParam = isLiveEdit ? &isLiveEdit : nullptr;
|
||||
const bool* hasSourceURLParam = hasSourceURL ? &hasSourceURL : nullptr;
|
||||
const bool* hasSourceURLParam =
|
||||
hasSourceURLComment ? &hasSourceURLComment : nullptr;
|
||||
const bool* isModuleParam = isModule ? &isModule : nullptr;
|
||||
std::unique_ptr<V8StackTraceImpl> stack =
|
||||
V8StackTraceImpl::capture(m_inspector->debugger(), contextGroupId, 1);
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "src/inspector/inspected-context.h"
|
||||
#include "src/inspector/string-util.h"
|
||||
#include "src/inspector/v8-inspector-impl.h"
|
||||
#include "src/inspector/wasm-translation.h"
|
||||
#include "src/v8memory.h"
|
||||
|
||||
@ -110,9 +111,9 @@ class ActualScript : public V8DebuggerScript {
|
||||
|
||||
public:
|
||||
ActualScript(v8::Isolate* isolate, v8::Local<v8::debug::Script> script,
|
||||
bool isLiveEdit)
|
||||
bool isLiveEdit, V8InspectorClient* client)
|
||||
: V8DebuggerScript(isolate, String16::fromInteger(script->Id()),
|
||||
GetNameOrSourceUrl(isolate, script)),
|
||||
GetScriptURL(isolate, script, client)),
|
||||
m_isLiveEdit(isLiveEdit) {
|
||||
Initialize(script);
|
||||
}
|
||||
@ -218,11 +219,19 @@ class ActualScript : public V8DebuggerScript {
|
||||
}
|
||||
|
||||
private:
|
||||
String16 GetNameOrSourceUrl(v8::Isolate* isolate,
|
||||
v8::Local<v8::debug::Script> script) {
|
||||
v8::Local<v8::String> name;
|
||||
if (script->Name().ToLocal(&name) || script->SourceURL().ToLocal(&name))
|
||||
return toProtocolString(isolate, name);
|
||||
String16 GetScriptURL(v8::Isolate* isolate,
|
||||
v8::Local<v8::debug::Script> script,
|
||||
V8InspectorClient* client) {
|
||||
v8::Local<v8::String> sourceURL;
|
||||
if (script->SourceURL().ToLocal(&sourceURL) && sourceURL->Length() > 0)
|
||||
return toProtocolString(isolate, sourceURL);
|
||||
v8::Local<v8::String> v8Name;
|
||||
if (script->Name().ToLocal(&v8Name) && v8Name->Length() > 0) {
|
||||
String16 name = toProtocolString(isolate, v8Name);
|
||||
std::unique_ptr<StringBuffer> url =
|
||||
client->resourceNameToUrl(toStringView(name));
|
||||
return url ? toString16(url->string()) : name;
|
||||
}
|
||||
return String16();
|
||||
}
|
||||
|
||||
@ -232,8 +241,8 @@ class ActualScript : public V8DebuggerScript {
|
||||
|
||||
void Initialize(v8::Local<v8::debug::Script> script) {
|
||||
v8::Local<v8::String> tmp;
|
||||
if (script->SourceURL().ToLocal(&tmp))
|
||||
m_sourceURL = toProtocolString(m_isolate, tmp);
|
||||
m_hasSourceURLComment =
|
||||
script->SourceURL().ToLocal(&tmp) && tmp->Length() > 0;
|
||||
if (script->SourceMappingURL().ToLocal(&tmp))
|
||||
m_sourceMappingURL = toProtocolString(m_isolate, tmp);
|
||||
m_startLine = script->LineOffset();
|
||||
@ -400,9 +409,9 @@ class WasmVirtualScript : public V8DebuggerScript {
|
||||
|
||||
std::unique_ptr<V8DebuggerScript> V8DebuggerScript::Create(
|
||||
v8::Isolate* isolate, v8::Local<v8::debug::Script> scriptObj,
|
||||
bool isLiveEdit) {
|
||||
bool isLiveEdit, V8InspectorClient* client) {
|
||||
return std::unique_ptr<ActualScript>(
|
||||
new ActualScript(isolate, scriptObj, isLiveEdit));
|
||||
new ActualScript(isolate, scriptObj, isLiveEdit, client));
|
||||
}
|
||||
|
||||
std::unique_ptr<V8DebuggerScript> V8DebuggerScript::CreateWasm(
|
||||
@ -420,12 +429,11 @@ V8DebuggerScript::V8DebuggerScript(v8::Isolate* isolate, String16 id,
|
||||
|
||||
V8DebuggerScript::~V8DebuggerScript() {}
|
||||
|
||||
const String16& V8DebuggerScript::sourceURL() const {
|
||||
return m_sourceURL.isEmpty() ? m_url : m_sourceURL;
|
||||
}
|
||||
|
||||
void V8DebuggerScript::setSourceURL(const String16& sourceURL) {
|
||||
m_sourceURL = sourceURL;
|
||||
if (sourceURL.length() > 0) {
|
||||
m_hasSourceURLComment = true;
|
||||
m_url = sourceURL;
|
||||
}
|
||||
}
|
||||
|
||||
bool V8DebuggerScript::setBreakpoint(const String16& condition,
|
||||
@ -433,5 +441,4 @@ bool V8DebuggerScript::setBreakpoint(const String16& condition,
|
||||
v8::HandleScope scope(m_isolate);
|
||||
return script()->SetBreakpoint(toV8String(m_isolate, condition), loc, id);
|
||||
}
|
||||
|
||||
} // namespace v8_inspector
|
||||
|
@ -40,13 +40,14 @@
|
||||
namespace v8_inspector {
|
||||
|
||||
// Forward declaration.
|
||||
class V8InspectorClient;
|
||||
class WasmTranslation;
|
||||
|
||||
class V8DebuggerScript {
|
||||
public:
|
||||
static std::unique_ptr<V8DebuggerScript> Create(
|
||||
v8::Isolate* isolate, v8::Local<v8::debug::Script> script,
|
||||
bool isLiveEdit);
|
||||
bool isLiveEdit, V8InspectorClient* client);
|
||||
static std::unique_ptr<V8DebuggerScript> CreateWasm(
|
||||
v8::Isolate* isolate, WasmTranslation* wasmTranslation,
|
||||
v8::Local<v8::debug::WasmScript> underlyingScript, String16 id,
|
||||
@ -55,9 +56,9 @@ class V8DebuggerScript {
|
||||
virtual ~V8DebuggerScript();
|
||||
|
||||
const String16& scriptId() const { return m_id; }
|
||||
const String16& url() const { return m_url; }
|
||||
bool hasSourceURL() const { return !m_sourceURL.isEmpty(); }
|
||||
const String16& sourceURL() const;
|
||||
bool hasSourceURLComment() const { return m_hasSourceURLComment; }
|
||||
const String16& sourceURL() const { return m_url; }
|
||||
|
||||
virtual const String16& sourceMappingURL() const = 0;
|
||||
virtual const String16& source() const = 0;
|
||||
virtual const String16& hash() const = 0;
|
||||
@ -95,7 +96,7 @@ class V8DebuggerScript {
|
||||
|
||||
String16 m_id;
|
||||
String16 m_url;
|
||||
String16 m_sourceURL;
|
||||
bool m_hasSourceURLComment = false;
|
||||
int m_executionContextId = 0;
|
||||
|
||||
v8::Isolate* m_isolate;
|
||||
|
@ -226,13 +226,15 @@ void V8Debugger::getCompiledScripts(
|
||||
v8::Local<v8::debug::Script> script = scripts.Get(i);
|
||||
if (!script->WasCompiled()) continue;
|
||||
if (script->IsEmbedded()) {
|
||||
result.push_back(V8DebuggerScript::Create(m_isolate, script, false));
|
||||
result.push_back(V8DebuggerScript::Create(m_isolate, script, false,
|
||||
m_inspector->client()));
|
||||
continue;
|
||||
}
|
||||
int contextId;
|
||||
if (!script->ContextId().To(&contextId)) continue;
|
||||
if (m_inspector->contextGroupId(contextId) != contextGroupId) continue;
|
||||
result.push_back(V8DebuggerScript::Create(m_isolate, script, false));
|
||||
result.push_back(V8DebuggerScript::Create(m_isolate, script, false,
|
||||
m_inspector->client()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -585,13 +587,14 @@ void V8Debugger::ScriptCompiled(v8::Local<v8::debug::Script> script,
|
||||
});
|
||||
} else if (m_ignoreScriptParsedEventsCounter == 0) {
|
||||
v8::Isolate* isolate = m_isolate;
|
||||
V8InspectorClient* client = m_inspector->client();
|
||||
m_inspector->forEachSession(
|
||||
m_inspector->contextGroupId(contextId),
|
||||
[&isolate, &script, &has_compile_error,
|
||||
&is_live_edited](V8InspectorSessionImpl* session) {
|
||||
[&isolate, &script, &has_compile_error, &is_live_edited,
|
||||
&client](V8InspectorSessionImpl* session) {
|
||||
if (!session->debuggerAgent()->enabled()) return;
|
||||
session->debuggerAgent()->didParseSource(
|
||||
V8DebuggerScript::Create(isolate, script, is_live_edited),
|
||||
V8DebuggerScript::Create(isolate, script, is_live_edited, client),
|
||||
!has_compile_error);
|
||||
});
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "src/base/atomicops.h"
|
||||
#include "src/debug/debug-interface.h"
|
||||
#include "src/flags.h" // TODO(jgruber): Remove include and DEPS entry.
|
||||
#include "src/inspector/protocol/Protocol.h"
|
||||
#include "src/inspector/string-util.h"
|
||||
@ -31,6 +32,15 @@ static const char typeProfileStarted[] = "typeProfileStarted";
|
||||
|
||||
namespace {
|
||||
|
||||
String16 resourceNameToUrl(V8InspectorImpl* inspector,
|
||||
v8::Local<v8::String> v8Name) {
|
||||
String16 name = toProtocolString(inspector->isolate(), v8Name);
|
||||
if (!inspector) return name;
|
||||
std::unique_ptr<StringBuffer> url =
|
||||
inspector->client()->resourceNameToUrl(toStringView(name));
|
||||
return url ? toString16(url->string()) : name;
|
||||
}
|
||||
|
||||
std::unique_ptr<protocol::Array<protocol::Profiler::PositionTickInfo>>
|
||||
buildInspectorObjectForPositionTicks(const v8::CpuProfileNode* node) {
|
||||
unsigned lineCount = node->GetHitLineCount();
|
||||
@ -51,13 +61,14 @@ buildInspectorObjectForPositionTicks(const v8::CpuProfileNode* node) {
|
||||
}
|
||||
|
||||
std::unique_ptr<protocol::Profiler::ProfileNode> buildInspectorObjectFor(
|
||||
v8::Isolate* isolate, const v8::CpuProfileNode* node) {
|
||||
V8InspectorImpl* inspector, const v8::CpuProfileNode* node) {
|
||||
v8::Isolate* isolate = inspector->isolate();
|
||||
v8::HandleScope handleScope(isolate);
|
||||
auto callFrame =
|
||||
protocol::Runtime::CallFrame::create()
|
||||
.setFunctionName(toProtocolString(isolate, node->GetFunctionName()))
|
||||
.setScriptId(String16::fromInteger(node->GetScriptId()))
|
||||
.setUrl(toProtocolString(isolate, node->GetScriptResourceName()))
|
||||
.setUrl(resourceNameToUrl(inspector, node->GetScriptResourceName()))
|
||||
.setLineNumber(node->GetLineNumber() - 1)
|
||||
.setColumnNumber(node->GetColumnNumber() - 1)
|
||||
.build();
|
||||
@ -107,18 +118,19 @@ std::unique_ptr<protocol::Array<int>> buildInspectorObjectForTimestamps(
|
||||
return array;
|
||||
}
|
||||
|
||||
void flattenNodesTree(v8::Isolate* isolate, const v8::CpuProfileNode* node,
|
||||
void flattenNodesTree(V8InspectorImpl* inspector,
|
||||
const v8::CpuProfileNode* node,
|
||||
protocol::Array<protocol::Profiler::ProfileNode>* list) {
|
||||
list->addItem(buildInspectorObjectFor(isolate, node));
|
||||
list->addItem(buildInspectorObjectFor(inspector, node));
|
||||
const int childrenCount = node->GetChildrenCount();
|
||||
for (int i = 0; i < childrenCount; i++)
|
||||
flattenNodesTree(isolate, node->GetChild(i), list);
|
||||
flattenNodesTree(inspector, node->GetChild(i), list);
|
||||
}
|
||||
|
||||
std::unique_ptr<protocol::Profiler::Profile> createCPUProfile(
|
||||
v8::Isolate* isolate, v8::CpuProfile* v8profile) {
|
||||
V8InspectorImpl* inspector, v8::CpuProfile* v8profile) {
|
||||
auto nodes = protocol::Array<protocol::Profiler::ProfileNode>::create();
|
||||
flattenNodesTree(isolate, v8profile->GetTopDownRoot(), nodes.get());
|
||||
flattenNodesTree(inspector, v8profile->GetTopDownRoot(), nodes.get());
|
||||
return protocol::Profiler::Profile::create()
|
||||
.setNodes(std::move(nodes))
|
||||
.setStartTime(static_cast<double>(v8profile->GetStartTime()))
|
||||
@ -320,11 +332,12 @@ std::unique_ptr<protocol::Profiler::CoverageRange> createCoverageRange(
|
||||
}
|
||||
|
||||
Response coverageToProtocol(
|
||||
v8::Isolate* isolate, const v8::debug::Coverage& coverage,
|
||||
V8InspectorImpl* inspector, const v8::debug::Coverage& coverage,
|
||||
std::unique_ptr<protocol::Array<protocol::Profiler::ScriptCoverage>>*
|
||||
out_result) {
|
||||
std::unique_ptr<protocol::Array<protocol::Profiler::ScriptCoverage>> result =
|
||||
protocol::Array<protocol::Profiler::ScriptCoverage>::create();
|
||||
v8::Isolate* isolate = inspector->isolate();
|
||||
for (size_t i = 0; i < coverage.ScriptCount(); i++) {
|
||||
v8::debug::Coverage::ScriptData script_data = coverage.GetScriptData(i);
|
||||
v8::Local<v8::debug::Script> script = script_data.GetScript();
|
||||
@ -362,8 +375,10 @@ Response coverageToProtocol(
|
||||
}
|
||||
String16 url;
|
||||
v8::Local<v8::String> name;
|
||||
if (script->Name().ToLocal(&name) || script->SourceURL().ToLocal(&name)) {
|
||||
if (script->SourceURL().ToLocal(&name) && name->Length()) {
|
||||
url = toProtocolString(isolate, name);
|
||||
} else if (script->Name().ToLocal(&name) && name->Length()) {
|
||||
url = resourceNameToUrl(inspector, name);
|
||||
}
|
||||
result->addItem(protocol::Profiler::ScriptCoverage::create()
|
||||
.setScriptId(String16::fromInteger(script->Id()))
|
||||
@ -385,7 +400,7 @@ Response V8ProfilerAgentImpl::takePreciseCoverage(
|
||||
}
|
||||
v8::HandleScope handle_scope(m_isolate);
|
||||
v8::debug::Coverage coverage = v8::debug::Coverage::CollectPrecise(m_isolate);
|
||||
return coverageToProtocol(m_isolate, coverage, out_result);
|
||||
return coverageToProtocol(m_session->inspector(), coverage, out_result);
|
||||
}
|
||||
|
||||
Response V8ProfilerAgentImpl::getBestEffortCoverage(
|
||||
@ -394,15 +409,16 @@ Response V8ProfilerAgentImpl::getBestEffortCoverage(
|
||||
v8::HandleScope handle_scope(m_isolate);
|
||||
v8::debug::Coverage coverage =
|
||||
v8::debug::Coverage::CollectBestEffort(m_isolate);
|
||||
return coverageToProtocol(m_isolate, coverage, out_result);
|
||||
return coverageToProtocol(m_session->inspector(), coverage, out_result);
|
||||
}
|
||||
|
||||
namespace {
|
||||
std::unique_ptr<protocol::Array<protocol::Profiler::ScriptTypeProfile>>
|
||||
typeProfileToProtocol(v8::Isolate* isolate,
|
||||
typeProfileToProtocol(V8InspectorImpl* inspector,
|
||||
const v8::debug::TypeProfile& type_profile) {
|
||||
std::unique_ptr<protocol::Array<protocol::Profiler::ScriptTypeProfile>>
|
||||
result = protocol::Array<protocol::Profiler::ScriptTypeProfile>::create();
|
||||
v8::Isolate* isolate = inspector->isolate();
|
||||
for (size_t i = 0; i < type_profile.ScriptCount(); i++) {
|
||||
v8::debug::TypeProfile::ScriptData script_data =
|
||||
type_profile.GetScriptData(i);
|
||||
@ -428,8 +444,10 @@ typeProfileToProtocol(v8::Isolate* isolate,
|
||||
}
|
||||
String16 url;
|
||||
v8::Local<v8::String> name;
|
||||
if (script->Name().ToLocal(&name) || script->SourceURL().ToLocal(&name)) {
|
||||
if (script->SourceURL().ToLocal(&name) && name->Length()) {
|
||||
url = toProtocolString(isolate, name);
|
||||
} else if (script->Name().ToLocal(&name) && name->Length()) {
|
||||
url = resourceNameToUrl(inspector, name);
|
||||
}
|
||||
result->addItem(protocol::Profiler::ScriptTypeProfile::create()
|
||||
.setScriptId(String16::fromInteger(script->Id()))
|
||||
@ -464,7 +482,7 @@ Response V8ProfilerAgentImpl::takeTypeProfile(
|
||||
v8::HandleScope handle_scope(m_isolate);
|
||||
v8::debug::TypeProfile type_profile =
|
||||
v8::debug::TypeProfile::Collect(m_isolate);
|
||||
*out_result = typeProfileToProtocol(m_isolate, type_profile);
|
||||
*out_result = typeProfileToProtocol(m_session->inspector(), type_profile);
|
||||
return Response::OK();
|
||||
}
|
||||
|
||||
@ -493,7 +511,7 @@ std::unique_ptr<protocol::Profiler::Profile> V8ProfilerAgentImpl::stopProfiling(
|
||||
m_profiler->StopProfiling(toV8String(m_isolate, title));
|
||||
std::unique_ptr<protocol::Profiler::Profile> result;
|
||||
if (profile) {
|
||||
if (serialize) result = createCPUProfile(m_isolate, profile);
|
||||
if (serialize) result = createCPUProfile(m_session->inspector(), profile);
|
||||
profile->Delete();
|
||||
}
|
||||
--m_startedProfilesCount;
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <algorithm>
|
||||
|
||||
#include "src/inspector/v8-debugger.h"
|
||||
#include "src/inspector/v8-inspector-impl.h"
|
||||
#include "src/inspector/wasm-translation.h"
|
||||
|
||||
namespace v8_inspector {
|
||||
@ -74,7 +75,10 @@ std::unique_ptr<protocol::Runtime::StackTrace> buildInspectorObjectCommon(
|
||||
std::unique_ptr<protocol::Array<protocol::Runtime::CallFrame>>
|
||||
inspectorFrames = protocol::Array<protocol::Runtime::CallFrame>::create();
|
||||
for (size_t i = 0; i < frames.size(); i++) {
|
||||
inspectorFrames->addItem(frames[i]->buildInspectorObject());
|
||||
V8InspectorClient* client = nullptr;
|
||||
if (debugger && debugger->inspector())
|
||||
client = debugger->inspector()->client();
|
||||
inspectorFrames->addItem(frames[i]->buildInspectorObject(client));
|
||||
}
|
||||
std::unique_ptr<protocol::Runtime::StackTrace> stackTrace =
|
||||
protocol::Runtime::StackTrace::create()
|
||||
@ -119,7 +123,9 @@ StackFrame::StackFrame(v8::Isolate* isolate, v8::Local<v8::StackFrame> v8Frame)
|
||||
m_sourceURL(
|
||||
toProtocolString(isolate, v8Frame->GetScriptNameOrSourceURL())),
|
||||
m_lineNumber(v8Frame->GetLineNumber() - 1),
|
||||
m_columnNumber(v8Frame->GetColumn() - 1) {
|
||||
m_columnNumber(v8Frame->GetColumn() - 1),
|
||||
m_hasSourceURLComment(v8Frame->GetScriptName() !=
|
||||
v8Frame->GetScriptNameOrSourceURL()) {
|
||||
DCHECK_NE(v8::Message::kNoLineNumberInfo, m_lineNumber + 1);
|
||||
DCHECK_NE(v8::Message::kNoColumnInfo, m_columnNumber + 1);
|
||||
}
|
||||
@ -139,12 +145,20 @@ int StackFrame::lineNumber() const { return m_lineNumber; }
|
||||
|
||||
int StackFrame::columnNumber() const { return m_columnNumber; }
|
||||
|
||||
std::unique_ptr<protocol::Runtime::CallFrame> StackFrame::buildInspectorObject()
|
||||
const {
|
||||
std::unique_ptr<protocol::Runtime::CallFrame> StackFrame::buildInspectorObject(
|
||||
V8InspectorClient* client) const {
|
||||
String16 frameUrl = m_sourceURL;
|
||||
if (client && !m_hasSourceURLComment && frameUrl.length() > 0) {
|
||||
std::unique_ptr<StringBuffer> url =
|
||||
client->resourceNameToUrl(toStringView(m_sourceURL));
|
||||
if (url) {
|
||||
frameUrl = toString16(url->string());
|
||||
}
|
||||
}
|
||||
return protocol::Runtime::CallFrame::create()
|
||||
.setFunctionName(m_functionName)
|
||||
.setScriptId(m_scriptId)
|
||||
.setUrl(m_sourceURL)
|
||||
.setUrl(frameUrl)
|
||||
.setLineNumber(m_lineNumber)
|
||||
.setColumnNumber(m_columnNumber)
|
||||
.build();
|
||||
|
@ -33,7 +33,8 @@ class StackFrame {
|
||||
const String16& sourceURL() const;
|
||||
int lineNumber() const; // 0-based.
|
||||
int columnNumber() const; // 0-based.
|
||||
std::unique_ptr<protocol::Runtime::CallFrame> buildInspectorObject() const;
|
||||
std::unique_ptr<protocol::Runtime::CallFrame> buildInspectorObject(
|
||||
V8InspectorClient* client) const;
|
||||
bool isEqual(StackFrame* frame) const;
|
||||
|
||||
private:
|
||||
@ -42,6 +43,7 @@ class StackFrame {
|
||||
String16 m_sourceURL;
|
||||
int m_lineNumber; // 0-based.
|
||||
int m_columnNumber; // 0-based.
|
||||
bool m_hasSourceURLComment;
|
||||
};
|
||||
|
||||
class V8StackTraceImpl : public V8StackTrace {
|
||||
|
122
test/inspector/debugger/resource-name-to-url-expected.txt
Normal file
122
test/inspector/debugger/resource-name-to-url-expected.txt
Normal file
@ -0,0 +1,122 @@
|
||||
Tests V8InspectorClient::resourceNameToUrl.
|
||||
Check script with url:
|
||||
{
|
||||
method : Debugger.scriptParsed
|
||||
params : {
|
||||
endColumn : 16
|
||||
endLine : 0
|
||||
executionContextId : <executionContextId>
|
||||
hasSourceURL : false
|
||||
hash : 033b33d191ed51ed823355d865eb871d811403e2
|
||||
isLiveEdit : false
|
||||
isModule : false
|
||||
length : 16
|
||||
scriptId : <scriptId>
|
||||
sourceMapURL :
|
||||
startColumn : 0
|
||||
startLine : 0
|
||||
url : prefix://url
|
||||
}
|
||||
}
|
||||
Check script with sourceURL comment:
|
||||
{
|
||||
method : Debugger.scriptParsed
|
||||
params : {
|
||||
endColumn : 37
|
||||
endLine : 0
|
||||
executionContextId : <executionContextId>
|
||||
hasSourceURL : true
|
||||
hash : 06c136ce206c5f505f32af524e6ec71b5baa0bbb
|
||||
isLiveEdit : false
|
||||
isModule : false
|
||||
length : 37
|
||||
scriptId : <scriptId>
|
||||
sourceMapURL :
|
||||
startColumn : 0
|
||||
startLine : 0
|
||||
url : foo.js
|
||||
}
|
||||
}
|
||||
Check script failed to parse:
|
||||
{
|
||||
method : Debugger.scriptFailedToParse
|
||||
params : {
|
||||
endColumn : 15
|
||||
endLine : 0
|
||||
executionContextId : <executionContextId>
|
||||
hasSourceURL : false
|
||||
hash : 033b33d191ed51ed1f44cd0465eb871d811403e2
|
||||
isModule : false
|
||||
length : 15
|
||||
scriptId : <scriptId>
|
||||
sourceMapURL :
|
||||
startColumn : 0
|
||||
startLine : 0
|
||||
url : prefix://url
|
||||
}
|
||||
}
|
||||
Check script failed to parse with sourceURL comment:
|
||||
{
|
||||
method : Debugger.scriptFailedToParse
|
||||
params : {
|
||||
endColumn : 36
|
||||
endLine : 0
|
||||
executionContextId : <executionContextId>
|
||||
hasSourceURL : true
|
||||
hash : 23a2885951475580023e2a742563d78876d8f05e
|
||||
isModule : false
|
||||
length : 36
|
||||
scriptId : <scriptId>
|
||||
sourceMapURL :
|
||||
startColumn : 0
|
||||
startLine : 0
|
||||
url : foo.js
|
||||
}
|
||||
}
|
||||
Test runtime stack trace:
|
||||
{
|
||||
method : Runtime.consoleAPICalled
|
||||
params : {
|
||||
args : [
|
||||
[0] : {
|
||||
description : 42
|
||||
type : number
|
||||
value : 42
|
||||
}
|
||||
]
|
||||
executionContextId : <executionContextId>
|
||||
stackTrace : {
|
||||
callFrames : [
|
||||
[0] : {
|
||||
columnNumber : 14
|
||||
functionName : foo
|
||||
lineNumber : 2
|
||||
scriptId : <scriptId>
|
||||
url : prefix://url
|
||||
}
|
||||
[1] : {
|
||||
columnNumber : 0
|
||||
functionName :
|
||||
lineNumber : 0
|
||||
scriptId : <scriptId>
|
||||
url : boo.js
|
||||
}
|
||||
[2] : {
|
||||
columnNumber : 4
|
||||
functionName :
|
||||
lineNumber : 4
|
||||
scriptId : <scriptId>
|
||||
url : prefix://url
|
||||
}
|
||||
]
|
||||
}
|
||||
timestamp : <timestamp>
|
||||
type : log
|
||||
}
|
||||
}
|
||||
Test debugger stack trace:
|
||||
[
|
||||
[0] : prefix://url
|
||||
[1] : boo.js
|
||||
[2] : prefix://url
|
||||
]
|
49
test/inspector/debugger/resource-name-to-url.js
Normal file
49
test/inspector/debugger/resource-name-to-url.js
Normal file
@ -0,0 +1,49 @@
|
||||
// Copyright 2018 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
let {session, contextGroup, Protocol} = InspectorTest.start(
|
||||
'Tests V8InspectorClient::resourceNameToUrl.');
|
||||
|
||||
(async function test(){
|
||||
Protocol.Runtime.enable();
|
||||
await Protocol.Debugger.enable();
|
||||
contextGroup.addScript(`inspector.setResourceNamePrefix('prefix://')`);
|
||||
await Protocol.Debugger.onceScriptParsed();
|
||||
|
||||
InspectorTest.log('Check script with url:');
|
||||
contextGroup.addScript('function foo(){}', 0, 0, 'url');
|
||||
InspectorTest.logMessage(await Protocol.Debugger.onceScriptParsed());
|
||||
|
||||
InspectorTest.log('Check script with sourceURL comment:');
|
||||
contextGroup.addScript('function foo(){} //# sourceURL=foo.js', 0, 0, 'url');
|
||||
InspectorTest.logMessage(await Protocol.Debugger.onceScriptParsed());
|
||||
|
||||
InspectorTest.log('Check script failed to parse:');
|
||||
contextGroup.addScript('function foo(){', 0, 0, 'url');
|
||||
InspectorTest.logMessage(await Protocol.Debugger.onceScriptFailedToParse());
|
||||
|
||||
InspectorTest.log('Check script failed to parse with sourceURL comment:');
|
||||
contextGroup.addScript('function foo(){ //# sourceURL=foo.js', 0, 0, 'url');
|
||||
InspectorTest.logMessage(await Protocol.Debugger.onceScriptFailedToParse());
|
||||
|
||||
InspectorTest.log('Test runtime stack trace:');
|
||||
contextGroup.addScript(`
|
||||
function foo() {
|
||||
console.log(42);
|
||||
}
|
||||
eval('foo(); //# sourceURL=boo.js');
|
||||
`, 0, 0, 'url');
|
||||
InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
|
||||
|
||||
InspectorTest.log('Test debugger stack trace:');
|
||||
contextGroup.addScript(`
|
||||
function foo() {
|
||||
debugger;
|
||||
}
|
||||
eval('foo(); //# sourceURL=boo.js');
|
||||
`, 0, 0, 'url');
|
||||
const {params:{callFrames}} = await Protocol.Debugger.oncePaused();
|
||||
InspectorTest.logMessage(callFrames.map(frame => frame.url));
|
||||
InspectorTest.completeTest();
|
||||
})();
|
@ -726,6 +726,9 @@ class InspectorExtension : public IsolateData::SetupGlobalTask {
|
||||
ToV8String(isolate, "setAllowCodeGenerationFromStrings"),
|
||||
v8::FunctionTemplate::New(
|
||||
isolate, &InspectorExtension::SetAllowCodeGenerationFromStrings));
|
||||
inspector->Set(ToV8String(isolate, "setResourceNamePrefix"),
|
||||
v8::FunctionTemplate::New(
|
||||
isolate, &InspectorExtension::SetResourceNamePrefix));
|
||||
global->Set(ToV8String(isolate, "inspector"), inspector);
|
||||
}
|
||||
|
||||
@ -990,6 +993,18 @@ class InspectorExtension : public IsolateData::SetupGlobalTask {
|
||||
args.GetIsolate()->GetCurrentContext()->AllowCodeGenerationFromStrings(
|
||||
args[0].As<v8::Boolean>()->Value());
|
||||
}
|
||||
|
||||
static void SetResourceNamePrefix(
|
||||
const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
if (args.Length() != 1 || !args[0]->IsString()) {
|
||||
fprintf(stderr, "Internal error: setResourceNamePrefix('prefix').");
|
||||
Exit();
|
||||
}
|
||||
v8::Isolate* isolate = args.GetIsolate();
|
||||
v8::Local<v8::Context> context = isolate->GetCurrentContext();
|
||||
IsolateData* data = IsolateData::FromContext(context);
|
||||
data->SetResourceNamePrefix(v8::Local<v8::String>::Cast(args[0]));
|
||||
}
|
||||
};
|
||||
|
||||
bool RunExtraCode(v8::Isolate* isolate, v8::Local<v8::Context> context,
|
||||
|
@ -426,3 +426,32 @@ void IsolateData::maxAsyncCallStackDepthChanged(int depth) {
|
||||
if (!log_max_async_call_stack_depth_changed_) return;
|
||||
fprintf(stdout, "maxAsyncCallStackDepthChanged: %d\n", depth);
|
||||
}
|
||||
|
||||
void IsolateData::SetResourceNamePrefix(v8::Local<v8::String> prefix) {
|
||||
resource_name_prefix_.Reset(v8::Isolate::GetCurrent(), prefix);
|
||||
}
|
||||
|
||||
namespace {
|
||||
class StringBufferImpl : public v8_inspector::StringBuffer {
|
||||
public:
|
||||
StringBufferImpl(v8::Isolate* isolate, v8::Local<v8::String> string)
|
||||
: data_(ToVector(isolate, string)),
|
||||
view_(data_.start(), data_.length()) {}
|
||||
const v8_inspector::StringView& string() override { return view_; }
|
||||
|
||||
private:
|
||||
v8::internal::Vector<uint16_t> data_;
|
||||
v8_inspector::StringView view_;
|
||||
};
|
||||
} // anonymous namespace
|
||||
|
||||
std::unique_ptr<v8_inspector::StringBuffer> IsolateData::resourceNameToUrl(
|
||||
const v8_inspector::StringView& resourceName) {
|
||||
if (resource_name_prefix_.IsEmpty()) return nullptr;
|
||||
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
v8::Local<v8::String> name = ToString(isolate, resourceName);
|
||||
v8::Local<v8::String> prefix = resource_name_prefix_.Get(isolate);
|
||||
v8::Local<v8::String> url = v8::String::Concat(isolate, prefix, name);
|
||||
return std::unique_ptr<StringBufferImpl>(new StringBufferImpl(isolate, url));
|
||||
}
|
||||
|
@ -76,6 +76,7 @@ class IsolateData : public v8_inspector::V8InspectorClient {
|
||||
void FireContextCreated(v8::Local<v8::Context> context, int context_group_id);
|
||||
void FireContextDestroyed(v8::Local<v8::Context> context);
|
||||
void FreeContext(v8::Local<v8::Context> context);
|
||||
void SetResourceNamePrefix(v8::Local<v8::String> prefix);
|
||||
|
||||
private:
|
||||
struct VectorCompare {
|
||||
@ -114,6 +115,8 @@ class IsolateData : public v8_inspector::V8InspectorClient {
|
||||
v8_inspector::V8StackTrace*) override;
|
||||
bool isInspectableHeapObject(v8::Local<v8::Object>) override;
|
||||
void maxAsyncCallStackDepthChanged(int depth) override;
|
||||
std::unique_ptr<v8_inspector::StringBuffer> resourceNameToUrl(
|
||||
const v8_inspector::StringView& resourceName) override;
|
||||
|
||||
// The isolate gets deleted by its {Dispose} method, not by the default
|
||||
// deleter. Therefore we have to define a custom deleter for the unique_ptr to
|
||||
@ -141,6 +144,7 @@ class IsolateData : public v8_inspector::V8InspectorClient {
|
||||
bool log_console_api_message_calls_ = false;
|
||||
bool log_max_async_call_stack_depth_changed_ = false;
|
||||
v8::Global<v8::Private> not_inspectable_private_;
|
||||
v8::Global<v8::String> resource_name_prefix_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(IsolateData);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user