2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010- 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 "hphp/runtime/eval/debugger/debugger_server.h"
18 #include "hphp/runtime/eval/debugger/debugger_client.h"
19 #include "hphp/runtime/eval/debugger/debugger.h"
20 #include "hphp/runtime/base/runtime_option.h"
21 #include "hphp/util/network.h"
22 #include "hphp/util/logger.h"
24 #define POLLING_SECONDS 1
26 namespace HPHP
{ namespace Eval
{
27 ///////////////////////////////////////////////////////////////////////////////
28 TRACE_SET_MOD(debugger
);
30 DebuggerServer
DebuggerServer::s_debugger_server
;
32 bool DebuggerServer::Start() {
33 TRACE(2, "DebuggerServer::Start\n");
34 if (RuntimeOption::EnableDebuggerServer
) {
35 Debugger::SetTextColors();
37 // Some server commands pre-formatted texts with color for clients. Loading
38 // a set of default colors for better display.
40 DebuggerClient::LoadColors(hdf
);
42 return s_debugger_server
.start();
47 void DebuggerServer::Stop() {
48 TRACE(2, "DebuggerServer::Stop\n");
49 if (RuntimeOption::EnableDebuggerServer
) {
50 s_debugger_server
.stop();
54 ///////////////////////////////////////////////////////////////////////////////
56 DebuggerServer::DebuggerServer()
57 : m_serverThread(this, &DebuggerServer::accept
), m_stopped(false) {
58 TRACE(2, "DebuggerServer::DebuggerServer\n");
61 DebuggerServer::~DebuggerServer() {
62 TRACE(2, "DebuggerServer::~DebuggerServer\n");
64 m_serverThread
.waitForEnd();
67 bool DebuggerServer::start() {
68 TRACE(2, "DebuggerServer::start\n");
69 int port
= RuntimeOption::DebuggerServerPort
;
73 if (!Util::safe_gethostbyname("0.0.0.0", result
)) {
76 struct sockaddr_in la
;
77 memcpy((char*)&la
.sin_addr
, result
.hostbuf
.h_addr
,
78 result
.hostbuf
.h_length
);
79 la
.sin_family
= result
.hostbuf
.h_addrtype
;
80 la
.sin_port
= htons((unsigned short)port
);
82 m_sock
= new Socket(socket(PF_INET
, SOCK_STREAM
, 0), PF_INET
, "0.0.0.0",
86 setsockopt(m_sock
->fd(), SOL_SOCKET
, SO_REUSEADDR
, &yes
, sizeof(yes
));
88 if (!m_sock
->valid()) {
89 Logger::Error("unable to create debugger server socket");
92 if (bind(m_sock
->fd(), (struct sockaddr
*)&la
, sizeof(la
)) < 0) {
93 Logger::Error("unable to bind to port %d for debugger server", port
);
96 if (listen(m_sock
->fd(), backlog
) < 0) {
97 Logger::Error("unable to listen on port %d for debugger server", port
);
101 m_serverThread
.start();
105 void DebuggerServer::stop() {
106 TRACE(2, "DebuggerServer::stop\n");
108 m_serverThread
.waitForEnd();
111 void DebuggerServer::accept() {
112 TRACE(2, "DebuggerServer::accept\n");
115 struct pollfd fds
[1];
116 fds
[0].fd
= m_sock
->fd();
117 fds
[0].events
= POLLIN
|POLLERR
|POLLHUP
;
118 int ret
= poll(fds
, 1, POLLING_SECONDS
* 1000);
120 bool in
= (fds
[0].revents
& POLLIN
);
123 socklen_t salen
= sizeof(sa
);
125 Socket
*new_sock
= new Socket(::accept(m_sock
->fd(), &sa
, &salen
),
127 SmartPtr
<Socket
> ret(new_sock
);
128 if (new_sock
->valid()) {
129 Debugger::CreateProxy(ret
, false);
131 Logger::Error("unable to accept incoming debugger request");
133 } catch (Exception
&e
) {
134 Logger::Error("%s", e
.getMessage().c_str());
135 } catch (std::exception
&e
) {
136 Logger::Error("%s", e
.what());
138 Logger::Error("(unknown exception was thrown)");
141 } // else timed out, then we have a chance to check m_stopped bit
142 // cleanup the dummy sandbox threads it created
143 Debugger::CleanupDummySandboxThreads();
149 ///////////////////////////////////////////////////////////////////////////////