Skip to content
This repository has been archived by the owner on Oct 15, 2020. It is now read-only.

Commit

Permalink
inspector: enable TimeTravel support
Browse files Browse the repository at this point in the history
* Added the TimeTravel domain and wired it up
* Debuggers can now detect time travel mode by looking at the
  available domains.

PR-URL: #244
Reviewed-By: Kunal Pathak <Kunal.Pathak@microsoft.com>
Reviewed-By: Sandeep Agarwal <saagarwa@microsoft.com>
  • Loading branch information
kfarnung committed May 17, 2017
1 parent af912e8 commit f3d3097
Show file tree
Hide file tree
Showing 15 changed files with 199 additions and 23 deletions.
2 changes: 1 addition & 1 deletion deps/chakrashim/include/v8-debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ class V8_EXPORT Debug {
static Local<Context> GetDebugContext(Isolate* isolate);

static void EnableDebug();
static void EnableInspector();
static void EnableInspector(bool enableReplayDebug = false);

static void SetLiveEditEnabled(Isolate* isolate, bool enable);
};
Expand Down
5 changes: 5 additions & 0 deletions deps/chakrashim/src/inspector/inspector.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,12 @@
'<(SHARED_INTERMEDIATE_DIR)/src/inspector/protocol/Runtime.h',
'<(SHARED_INTERMEDIATE_DIR)/src/inspector/protocol/Schema.cpp',
'<(SHARED_INTERMEDIATE_DIR)/src/inspector/protocol/Schema.h',
'<(SHARED_INTERMEDIATE_DIR)/src/inspector/protocol/TimeTravel.cpp',
'<(SHARED_INTERMEDIATE_DIR)/src/inspector/protocol/TimeTravel.h',
'<(SHARED_INTERMEDIATE_DIR)/include/inspector/Debugger.h',
'<(SHARED_INTERMEDIATE_DIR)/include/inspector/Runtime.h',
'<(SHARED_INTERMEDIATE_DIR)/include/inspector/Schema.h',
'<(SHARED_INTERMEDIATE_DIR)/include/inspector/TimeTravel.h',
],

'inspector_all_sources': [
Expand Down Expand Up @@ -65,6 +68,8 @@
'src/inspector/v8-schema-agent-impl.h',
'src/inspector/v8-stack-trace-impl.cc',
'src/inspector/v8-stack-trace-impl.h',
'src/inspector/v8-timetravel-agent-impl.cc',
'src/inspector/v8-timetravel-agent-impl.h',
'src/inspector/v8-value-copier.cc',
'src/inspector/v8-value-copier.h',
]
Expand Down
14 changes: 14 additions & 0 deletions deps/chakrashim/src/inspector/js_protocol.json
Original file line number Diff line number Diff line change
Expand Up @@ -777,5 +777,19 @@
"description": "Issued when new console message is added."
}
]
},
{
"domain": "TimeTravel",
"description": "TimeTravel domain exposes JavaScript time travel capabilities. It allows stepping backwards through execution.",
"commands": [
{
"name": "stepBack",
"description": "Steps backwards to the previous statement."
},
{
"name": "reverse",
"description": "Resumes JavaScript execution in reverse."
}
]
}]
}
14 changes: 14 additions & 0 deletions deps/chakrashim/src/inspector/v8-debugger-agent-impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -654,6 +654,20 @@ void V8DebuggerAgentImpl::stepOut(ErrorString* errorString) {
m_debugger->stepOutOfFunction();
}

void V8DebuggerAgentImpl::reverse(ErrorString* errorString) {
if (!assertPaused(errorString)) return;
m_scheduledDebuggerStep = ReverseContinue;
m_steppingFromFramework = false;
m_debugger->reverse();
}

void V8DebuggerAgentImpl::stepBack(ErrorString* errorString) {
if (!assertPaused(errorString)) return;
m_scheduledDebuggerStep = StepBack;
m_steppingFromFramework = isTopPausedCallFrameBlackboxed();
m_debugger->stepBack();
}

void V8DebuggerAgentImpl::setPauseOnExceptions(
ErrorString* errorString, const String16& stringPauseState) {
if (!checkEnabled(errorString)) return;
Expand Down
13 changes: 12 additions & 1 deletion deps/chakrashim/src/inspector/v8-debugger-agent-impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@ class V8DebuggerAgentImpl : public protocol::Debugger::Backend {
std::unique_ptr<protocol::Array<protocol::Debugger::ScriptPosition>>
positions) override;

// Time travel implementations
void reverse(ErrorString*);
void stepBack(ErrorString*);

bool enabled();

void setBreakpointAt(const String16& scriptId, int lineNumber,
Expand Down Expand Up @@ -171,7 +175,14 @@ class V8DebuggerAgentImpl : public protocol::Debugger::Backend {
using DebugServerBreakpointToBreakpointIdAndSourceMap =
protocol::HashMap<String16, std::pair<String16, BreakpointSource>>;

enum DebuggerStep { NoStep = 0, StepInto, StepOver, StepOut };
enum DebuggerStep {
StepInto = 0,
StepOver,
StepOut,
StepBack,
ReverseContinue,
NoStep
};

V8InspectorImpl* m_inspector;
V8Debugger* m_debugger;
Expand Down
12 changes: 12 additions & 0 deletions deps/chakrashim/src/inspector/v8-debugger.cc
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,18 @@ void V8Debugger::clearStepping() {
JsDiagSetStepType(JsDiagStepTypeContinue);
}

void V8Debugger::reverse() {
DCHECK(isPaused());
JsDiagSetStepType(JsDiagStepTypeReverseContinue);
continueProgram();
}

void V8Debugger::stepBack() {
DCHECK(isPaused());
JsDiagSetStepType(JsDiagStepTypeStepBack);
continueProgram();
}

bool V8Debugger::setScriptSource(
const String16& sourceID, v8::Local<v8::String> newSource, bool dryRun,
ErrorString* error,
Expand Down
4 changes: 4 additions & 0 deletions deps/chakrashim/src/inspector/v8-debugger.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ class V8Debugger {
void stepOutOfFunction();
void clearStepping();

// Time travel
void reverse();
void stepBack();

bool setScriptSource(const String16& sourceID,
v8::Local<v8::String> newSource, bool dryRun,
ErrorString*,
Expand Down
20 changes: 19 additions & 1 deletion deps/chakrashim/src/inspector/v8-inspector-session-impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
#include "src/inspector/v8-inspector-impl.h"
#include "src/inspector/v8-runtime-agent-impl.h"
#include "src/inspector/v8-schema-agent-impl.h"
#include "src/inspector/v8-timetravel-agent-impl.h"

#include "src/jsrtinspector.h"

namespace v8_inspector {

Expand All @@ -28,7 +31,9 @@ bool V8InspectorSession::canDispatchMethod(const StringView& method) {
stringViewStartsWith(method,
protocol::Console::Metainfo::commandPrefix) ||
stringViewStartsWith(method,
protocol::Schema::Metainfo::commandPrefix);
protocol::Schema::Metainfo::commandPrefix) ||
stringViewStartsWith(method,
protocol::TimeTravel::Metainfo::commandPrefix);
}

std::unique_ptr<V8InspectorSessionImpl> V8InspectorSessionImpl::create(
Expand Down Expand Up @@ -77,6 +82,11 @@ V8InspectorSessionImpl::V8InspectorSessionImpl(V8InspectorImpl* inspector,
this, this, agentState(protocol::Schema::Metainfo::domainName)));
protocol::Schema::Dispatcher::wire(&m_dispatcher, m_schemaAgent.get());

m_timeTravelAgent = wrapUnique(new V8TimeTravelAgentImpl(
this, this, agentState(protocol::TimeTravel::Metainfo::domainName)));
protocol::TimeTravel::Dispatcher::wire(&m_dispatcher,
m_timeTravelAgent.get());

if (savedState.length()) {
m_runtimeAgent->restore();
m_debuggerAgent->restore();
Expand Down Expand Up @@ -173,6 +183,14 @@ V8InspectorSessionImpl::supportedDomainsImpl() {
.setName(protocol::Schema::Metainfo::domainName)
.setVersion(protocol::Schema::Metainfo::version)
.build());

if (m_timeTravelAgent->enabled()) {
result.push_back(protocol::Schema::Domain::create()
.setName(protocol::TimeTravel::Metainfo::domainName)
.setVersion(protocol::TimeTravel::Metainfo::version)
.build());
}

return result;
}

Expand Down
3 changes: 3 additions & 0 deletions deps/chakrashim/src/inspector/v8-inspector-session-impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class V8DebuggerAgentImpl;
class V8InspectorImpl;
class V8RuntimeAgentImpl;
class V8SchemaAgentImpl;
class V8TimeTravelAgentImpl;

using protocol::ErrorString;

Expand All @@ -38,6 +39,7 @@ class V8InspectorSessionImpl : public V8InspectorSession,
V8DebuggerAgentImpl* debuggerAgent() { return m_debuggerAgent.get(); }
V8SchemaAgentImpl* schemaAgent() { return m_schemaAgent.get(); }
V8RuntimeAgentImpl* runtimeAgent() { return m_runtimeAgent.get(); }
V8TimeTravelAgentImpl* timeTravelAgent() { return m_timeTravelAgent.get(); }
int contextGroupId() const { return m_contextGroupId; }

void reset();
Expand Down Expand Up @@ -85,6 +87,7 @@ class V8InspectorSessionImpl : public V8InspectorSession,
std::unique_ptr<V8DebuggerAgentImpl> m_debuggerAgent;
std::unique_ptr<V8ConsoleAgentImpl> m_consoleAgent;
std::unique_ptr<V8SchemaAgentImpl> m_schemaAgent;
std::unique_ptr<V8TimeTravelAgentImpl> m_timeTravelAgent;

DISALLOW_COPY_AND_ASSIGN(V8InspectorSessionImpl);
};
Expand Down
50 changes: 50 additions & 0 deletions deps/chakrashim/src/inspector/v8-timetravel-agent-impl.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright 2015 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.

#include "src/inspector/v8-timetravel-agent-impl.h"
#include "src/inspector/v8-inspector-session-impl.h"
#include "src/inspector/v8-debugger-agent-impl.h"
#include "src/jsrtinspector.h"

namespace v8_inspector {

V8TimeTravelAgentImpl::V8TimeTravelAgentImpl(
V8InspectorSessionImpl* session, protocol::FrontendChannel* frontendChannel,
protocol::DictionaryValue* state)
: m_session(session),
m_frontend(frontendChannel),
m_state(state) {}

V8TimeTravelAgentImpl::~V8TimeTravelAgentImpl() {}

bool V8TimeTravelAgentImpl::checkEnabled(ErrorString* errorString) {
if (enabled()) {
return true;
}

*errorString = "TimeTravel agent is not enabled";
return false;
}

bool V8TimeTravelAgentImpl::enabled() {
return jsrt::Inspector::IsReplayDebugEnabled();
}

void V8TimeTravelAgentImpl::reverse(ErrorString* errorString) {
if (!checkEnabled(errorString)) {
return;
}

m_session->debuggerAgent()->reverse(errorString);
}

void V8TimeTravelAgentImpl::stepBack(ErrorString* errorString) {
if (!checkEnabled(errorString)) {
return;
}

m_session->debuggerAgent()->stepBack(errorString);
}

} // namespace v8_inspector
46 changes: 46 additions & 0 deletions deps/chakrashim/src/inspector/v8-timetravel-agent-impl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright 2015 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.

#ifndef V8_INSPECTOR_V8TIMETRAVELAGENTIMPL_H_
#define V8_INSPECTOR_V8TIMETRAVELAGENTIMPL_H_

#include <vector>

#include "src/base/macros.h"
#include "src/inspector/protocol/TimeTravel.h"
#include "src/inspector/protocol/Forward.h"

namespace v8_inspector {

class V8Debugger;
class V8InspectorImpl;
class V8InspectorSessionImpl;

using protocol::ErrorString;

class V8TimeTravelAgentImpl : public protocol::TimeTravel::Backend {
public:
V8TimeTravelAgentImpl(V8InspectorSessionImpl*, protocol::FrontendChannel*,
protocol::DictionaryValue* state);
~V8TimeTravelAgentImpl() override;

// Part of the protocol.
void reverse(ErrorString*) override;
void stepBack(ErrorString*) override;

bool enabled();

private:
bool checkEnabled(ErrorString*);

V8InspectorSessionImpl* m_session;
protocol::TimeTravel::Frontend m_frontend;
protocol::DictionaryValue* m_state;

DISALLOW_COPY_AND_ASSIGN(V8TimeTravelAgentImpl);
};

} // namespace v8_inspector

#endif // V8_INSPECTOR_V8TIMETRAVELAGENTIMPL_H_
5 changes: 5 additions & 0 deletions deps/chakrashim/src/jsrtinspector.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

namespace v8 {
extern THREAD_LOCAL bool g_EnableInspector;
extern THREAD_LOCAL bool g_EnableReplayDebug;
}

namespace jsrt {
Expand Down Expand Up @@ -159,6 +160,10 @@ namespace jsrt {
return v8::g_EnableInspector;
}

bool Inspector::IsReplayDebugEnabled() {
return v8::g_EnableReplayDebug;
}

void Inspector::StartDebugging(JsRuntimeHandle runtime) {
JsErrorCode errorCode = JsDiagStartDebugging(
runtime, JsDiagDebugEventHandler, nullptr);
Expand Down
1 change: 1 addition & 0 deletions deps/chakrashim/src/jsrtinspector.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class InspectorBreakQueue;
class Inspector {
public:
static bool IsInspectorEnabled();
static bool IsReplayDebugEnabled();
static void StartDebugging(JsRuntimeHandle runtime);
static void RequestAsyncBreak(JsRuntimeHandle runtime,
v8::InterruptCallback callback,
Expand Down
4 changes: 3 additions & 1 deletion deps/chakrashim/src/v8debug.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,15 @@ namespace v8 {

THREAD_LOCAL bool g_EnableDebug = false;
THREAD_LOCAL bool g_EnableInspector = false;
THREAD_LOCAL bool g_EnableReplayDebug = false;

void Debug::EnableDebug() {
g_EnableDebug = true;
}

void Debug::EnableInspector() {
void Debug::EnableInspector(bool enableReplayDebug) {
g_EnableInspector = true;
g_EnableReplayDebug = enableReplayDebug;
}

Local<Context> Debug::GetDebugContext(Isolate* isolate) {
Expand Down
Loading

0 comments on commit f3d3097

Please sign in to comment.