Add support for HHBC ops with 5 immediates
[hiphop-php.git] / hphp / runtime / ext / vsdebug / ext_vsdebug.cpp
blob8ea67822b7152531bf124859be711ff562bf9034
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2017-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #include <string>
18 #include "hphp/runtime/ext/vsdebug/ext_vsdebug.h"
19 #include "hphp/runtime/ext/vsdebug/logging.h"
21 namespace HPHP {
22 namespace VSDEBUG {
24 VSDebugExtension::~VSDebugExtension() {
25 if (s_debugger != nullptr) {
26 delete s_debugger;
27 s_debugger = nullptr;
31 void VSDebugExtension::moduleLoad(const IniSetting::Map& ini, const Hdf hdf) {
32 // This extension is ** disabled ** by default, unless the configuration
33 // says otherwise. When !m_enabled, the other hooks in this module no-op.
34 Config::Bind(s_configEnabled, ini, hdf, "Eval.Debugger.VSDebugEnable", false);
36 // Set up logging for the extension.
37 // Note: Logging for the extension is disabled by default, unless
38 // VSDebugLogFile is explicitly defined in the configuration settings.
39 Config::Bind(s_logFilePath, ini, hdf, "Eval.Debugger.VSDebugLogFile", "");
41 Config::Bind(
42 s_attachListenPort,
43 ini,
44 hdf,
45 "Eval.Debugger.VSDebugListenPort",
46 DefaultListenPort);
48 bool commandLineEnabled = RuntimeOption::EnableVSDebugger;
49 if (!s_configEnabled && !commandLineEnabled) {
50 m_enabled = false;
51 return;
54 m_enabled = true;
56 VSDebugLogger::InitializeLogging(s_logFilePath);
57 VSDebugLogger::Log(
58 VSDebugLogger::LogLevelInfo,
59 "VSDebugExtension module loaded. Extension enabled in config."
63 void VSDebugExtension::moduleInit() {
64 SCOPE_EXIT {
65 // Memory barrier to ensure release semantics for our write of s_debugger
66 // and m_enabled in moduleLoad and this routine.
67 std::atomic_thread_fence(std::memory_order_release);
68 VSDebugLogger::LogFlush();
71 if (!m_enabled) {
72 return;
75 s_debugger = new Debugger();
76 if (s_debugger == nullptr) {
77 // Failed to allocate debugger, disable the extension.
78 m_enabled = false;
79 return;
82 DebugTransport* transport = nullptr;
83 if (RuntimeOption::ServerExecutionMode()) {
84 // If HHVM is running in server mode, start up the debugger socket server
85 // and listen for debugger clients to connect.
86 VSDebugLogger::Log(VSDebugLogger::LogLevelInfo,
87 "Extension started in SERVER mode");
89 transport = new SocketTransport(s_debugger, s_attachListenPort);
90 } else {
91 // Otherwise, HHVM is running in script or interactive mode. Communicate
92 // with the debugger client locally via known file descriptors.
93 VSDebugLogger::Log(
94 VSDebugLogger::LogLevelInfo,
95 "Extension started in SCRIPT mode."
98 // If a listen port was specified on the command line, use the TCP socket
99 // transport even in script mode. Otherwise, fall back to using a pipe with
100 // our parent process.
101 if (RuntimeOption::VSDebuggerListenPort > 0) {
102 VSDebugLogger::Log(
103 VSDebugLogger::LogLevelInfo,
104 "Blocking script startup. Waiting for debugger to attach on port: %d",
105 RuntimeOption::VSDebuggerListenPort
108 transport = new SocketTransport(
109 s_debugger,
110 RuntimeOption::VSDebuggerListenPort
112 } else {
113 try {
114 transport = new FdTransport(s_debugger);
115 s_launchMode = true;
116 } catch (...) {
117 assertx(transport == nullptr);
122 if (transport == nullptr) {
123 // Failed to allocate transport, disable the extension.
124 m_enabled = false;
125 return;
128 assertx(s_debugger != nullptr);
129 s_debugger->setTransport(transport);
132 void VSDebugExtension::moduleShutdown() {
133 if (s_debugger != nullptr) {
134 delete s_debugger;
135 s_debugger = nullptr;
138 VSDebugLogger::FinalizeLogging();
141 void VSDebugExtension::requestInit() {
142 // Memory barrier to ensure acquire semantics for the read of m_enabled below.
143 std::atomic_thread_fence(std::memory_order_acquire);
145 if (!m_enabled) {
146 return;
149 assertx(s_debugger != nullptr);
151 // If we're in SCRIPT mode and a TCP listen port was specified on the command
152 // line, we need to block starting the script until the debugger client
153 // connects.
154 if (!RuntimeOption::ServerExecutionMode() &&
155 RuntimeOption::VSDebuggerListenPort > 0) {
157 if (!RuntimeOption::VSDebuggerNoWait) {
158 VSDebugLogger::Log(
159 VSDebugLogger::LogLevelInfo,
160 "Blocking script startup until debugger client connects..."
162 s_debugger->waitForClientConnection();
163 VSDebugLogger::Log(
164 VSDebugLogger::LogLevelInfo,
165 "Debugger client connected."
170 s_debugger->requestInit();
173 void VSDebugExtension::requestShutdown() {
174 if (!m_enabled) {
175 return;
178 assertx(s_debugger != nullptr);
179 s_debugger->requestShutdown();
182 // Linkage for the debugger extension.
183 static VSDebugExtension s_vsdebug_extension;
185 // Linkage for configuration options.
186 bool VSDebugExtension::s_configEnabled {false};
187 std::string VSDebugExtension::s_logFilePath {""};
188 int VSDebugExtension::s_attachListenPort {-1};
189 bool VSDebugExtension::s_launchMode {false};
190 Debugger* VSDebugExtension::s_debugger {nullptr};