2 +----------------------------------------------------------------------+
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 +----------------------------------------------------------------------+
18 #include "hphp/runtime/ext/vsdebug/ext_vsdebug.h"
19 #include "hphp/runtime/ext/vsdebug/logging.h"
24 VSDebugExtension::~VSDebugExtension() {
25 if (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", "");
45 "Eval.Debugger.VSDebugListenPort",
48 bool commandLineEnabled
= RuntimeOption::EnableVSDebugger
;
49 if (!s_configEnabled
&& !commandLineEnabled
) {
56 VSDebugLogger::InitializeLogging(s_logFilePath
);
58 VSDebugLogger::LogLevelInfo
,
59 "VSDebugExtension module loaded. Extension enabled in config."
63 void VSDebugExtension::moduleInit() {
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();
75 s_debugger
= new Debugger();
76 if (s_debugger
== nullptr) {
77 // Failed to allocate debugger, disable the extension.
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
);
91 // Otherwise, HHVM is running in script or interactive mode. Communicate
92 // with the debugger client locally via known file descriptors.
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) {
103 VSDebugLogger::LogLevelInfo
,
104 "Blocking script startup. Waiting for debugger to attach on port: %d",
105 RuntimeOption::VSDebuggerListenPort
108 transport
= new SocketTransport(
110 RuntimeOption::VSDebuggerListenPort
114 transport
= new FdTransport(s_debugger
);
117 assertx(transport
== nullptr);
122 if (transport
== nullptr) {
123 // Failed to allocate transport, disable the extension.
128 assertx(s_debugger
!= nullptr);
129 s_debugger
->setTransport(transport
);
132 void VSDebugExtension::moduleShutdown() {
133 if (s_debugger
!= nullptr) {
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
);
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
154 if (!RuntimeOption::ServerExecutionMode() &&
155 RuntimeOption::VSDebuggerListenPort
> 0) {
157 if (!RuntimeOption::VSDebuggerNoWait
) {
159 VSDebugLogger::LogLevelInfo
,
160 "Blocking script startup until debugger client connects..."
162 s_debugger
->waitForClientConnection();
164 VSDebugLogger::LogLevelInfo
,
165 "Debugger client connected."
170 s_debugger
->requestInit();
173 void VSDebugExtension::requestShutdown() {
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};