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_command.h"
18 #include "hphp/runtime/eval/debugger/debugger.h"
19 #include "hphp/runtime/eval/debugger/cmd/all.h"
20 #include "hphp/util/logger.h"
22 #define POLLING_SECONDS 1
24 namespace HPHP
{ namespace Eval
{
25 ///////////////////////////////////////////////////////////////////////////////
26 TRACE_SET_MOD(debugger
);
29 bool DebuggerCommand::send(DebuggerThriftBuffer
&thrift
) {
30 TRACE(5, "DebuggerCommand::send\n");
36 Logger::Error("DebuggerCommand::send(): a socket error has happened");
42 bool DebuggerCommand::recv(DebuggerThriftBuffer
&thrift
) {
43 TRACE(5, "DebuggerCommand::recv\n");
47 Logger::Error("DebuggerCommand::recv(): a socket error has happened");
53 void DebuggerCommand::sendImpl(DebuggerThriftBuffer
&thrift
) {
54 TRACE(5, "DebuggerCommand::sendImpl\n");
55 thrift
.write((int32_t)m_type
);
56 thrift
.write(m_class
);
58 thrift
.write(m_version
);
61 void DebuggerCommand::recvImpl(DebuggerThriftBuffer
&thrift
) {
62 TRACE(5, "DebuggerCommand::recvImpl\n");
64 thrift
.read(m_version
);
67 bool DebuggerCommand::Receive(DebuggerThriftBuffer
&thrift
,
68 DebuggerCommandPtr
&cmd
, const char *caller
) {
69 TRACE(5, "DebuggerCommand::Receive\n");
73 fds
[0].fd
= thrift
.getSocket()->fd();
74 fds
[0].events
= POLLIN
|POLLERR
|POLLHUP
;
75 int ret
= poll(fds
, 1, POLLING_SECONDS
* 1000);
79 if (ret
== -1 || !(fds
[0].revents
& POLLIN
)) {
80 return errno
!= EINTR
; // treat signals as timeouts
90 Logger::Error("%s => DebuggerCommand::Receive(): socket error", caller
);
94 TRACE(1, "DebuggerCommand::Receive: got cmd of type %d\n", type
);
96 // not all commands are here, as not all commands need to be sent over wire
98 case KindOfBreak
: cmd
= DebuggerCommandPtr(new CmdBreak ()); break;
99 case KindOfContinue
: cmd
= DebuggerCommandPtr(new CmdContinue ()); break;
100 case KindOfDown
: cmd
= DebuggerCommandPtr(new CmdDown ()); break;
101 case KindOfException
: cmd
= DebuggerCommandPtr(new CmdException()); break;
102 case KindOfFrame
: cmd
= DebuggerCommandPtr(new CmdFrame ()); break;
103 case KindOfGlobal
: cmd
= DebuggerCommandPtr(new CmdGlobal ()); break;
104 case KindOfInfo
: cmd
= DebuggerCommandPtr(new CmdInfo ()); break;
105 case KindOfConstant
: cmd
= DebuggerCommandPtr(new CmdConstant ()); break;
106 case KindOfList
: cmd
= DebuggerCommandPtr(new CmdList ()); break;
107 case KindOfMachine
: cmd
= DebuggerCommandPtr(new CmdMachine ()); break;
108 case KindOfNext
: cmd
= DebuggerCommandPtr(new CmdNext ()); break;
109 case KindOfOut
: cmd
= DebuggerCommandPtr(new CmdOut ()); break;
110 case KindOfPrint
: cmd
= DebuggerCommandPtr(new CmdPrint ()); break;
111 case KindOfQuit
: cmd
= DebuggerCommandPtr(new CmdQuit ()); break;
112 case KindOfRun
: cmd
= DebuggerCommandPtr(new CmdRun ()); break;
113 case KindOfStep
: cmd
= DebuggerCommandPtr(new CmdStep ()); break;
114 case KindOfThread
: cmd
= DebuggerCommandPtr(new CmdThread ()); break;
115 case KindOfUp
: cmd
= DebuggerCommandPtr(new CmdUp ()); break;
116 case KindOfVariable
: cmd
= DebuggerCommandPtr(new CmdVariable ()); break;
117 case KindOfWhere
: cmd
= DebuggerCommandPtr(new CmdWhere ()); break;
118 case KindOfUser
: cmd
= DebuggerCommandPtr(new CmdUser ()); break;
119 case KindOfEval
: cmd
= DebuggerCommandPtr(new CmdEval ()); break;
120 case KindOfInterrupt
: cmd
= DebuggerCommandPtr(new CmdInterrupt()); break;
121 case KindOfSignal
: cmd
= DebuggerCommandPtr(new CmdSignal ()); break;
122 case KindOfShell
: cmd
= DebuggerCommandPtr(new CmdShell ()); break;
124 case KindOfExtended
: {
125 assert(!clsname
.empty());
126 cmd
= CmdExtended::CreateExtendedCommand(clsname
);
133 Logger::Error("%s => DebuggerCommand::Receive(): bad cmd type: %d",
137 if (!cmd
->recv(thrift
)) {
138 Logger::Error("%s => DebuggerCommand::Receive(): socket error", caller
);
144 ///////////////////////////////////////////////////////////////////////////////
147 void DebuggerCommand::list(DebuggerClient
*client
) {
148 TRACE(2, "DebuggerCommand::list\n");
151 bool DebuggerCommand::help(DebuggerClient
*client
) {
152 TRACE(2, "DebuggerCommand::help\n");
157 // If the first argument of the command is "help" or "?"
158 // this displays help text for the command and returns true.
159 // Otherwise it returns false.
160 bool DebuggerCommand::onClient(DebuggerClient
*client
) {
161 TRACE(2, "DebuggerCommand::onClient\n");
162 if (client
->arg(1, "help") || client
->arg(1, "?")) {
168 bool DebuggerCommand::onClientD(DebuggerClient
*client
) {
169 TRACE(2, "DebuggerCommand::onClientD\n");
170 bool ret
= onClient(client
);
171 if (client
->isApiMode() && !m_incomplete
) {
172 setClientOutput(client
);
177 void DebuggerCommand::setClientOutput(DebuggerClient
*client
) {
178 TRACE(2, "DebuggerCommand::setClientOutput\n");
179 // Just default to text
180 client
->setOutputType(DebuggerClient::OTText
);
183 bool DebuggerCommand::onServer(DebuggerProxy
*proxy
) {
184 TRACE(2, "DebuggerCommand::onServer\n");
186 Logger::Error("DebuggerCommand::onServer(): bad cmd type: %d", m_type
);
190 ///////////////////////////////////////////////////////////////////////////////