Arquivos
hhvm/hphp/runtime/debugger/cmd/cmd_internal_testing.cpp
T
Mike Magruder 22f8788e2f Cleanup client and server communication, events loops, and error handling.
Cleanup a lot of hangs with either the debugger client or server in a variety of error conditions, mostly related to communication errors or the client or server exiting unexpectedly. One of the biggest fixes is that all cases where the client was left in a state where Ctrl-C wouldn't work have been fixed.

Remove lots of little snippets of dead code. If you see a function (or small set of functions/fields) deleted then it was actually dead.

I debated whether to keep throwing DebuggerClientExitException on the server, and I decided to keep it. I think it's reasonable that if you've got the server stopped and you quit the debugger that the request gets terminated rather than continuing to run.

I also considered a big change to the way Ctrl-C works, but ended up staying with what was there with just a bit of cleanup. We need to guard against people banging on Ctrl-C, which is a reasonable behavior, and I think it feels pretty reasonable with the updated message.

Finally, added many comments about how this stuff works.
2013-06-18 16:23:17 -07:00

111 linhas
4.0 KiB
C++

/*
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
*/
#include "hphp/runtime/debugger/cmd/cmd_internal_testing.h"
namespace HPHP { namespace Eval {
///////////////////////////////////////////////////////////////////////////////
TRACE_SET_MOD(debugger);
void CmdInternalTesting::sendImpl(DebuggerThriftBuffer &thrift) {
DebuggerCommand::sendImpl(thrift);
thrift.write(m_arg);
// Write less data on purpose, to get the server to choke on deserialization
if ((m_arg != "shortcmd")) {
thrift.write(m_unused);
}
}
void CmdInternalTesting::recvImpl(DebuggerThriftBuffer &thrift) {
DebuggerCommand::recvImpl(thrift);
thrift.read(m_arg);
thrift.read(m_unused);
}
void CmdInternalTesting::help(DebuggerClient &client) {
TRACE(2, "CmdInternalTesting::help\n");
client.helpTitle("Internal Testing Command");
client.helpCmds(
"badcmdtypesend", "Send a bad command type to the proxy",
"badcmdtypereceive", "Receive a bad command type from the proxy",
"shortcmdsend", "Send less data that the proxy expects",
"shortcmdreceive", "Receive less data than the client expects",
"segfaultClient", "Segfault on the client",
"segfaultServer", "Segfault on the server",
nullptr
);
client.helpBody(
"This command is only for internal testing of the debugger, both client "
"and server. If you're using this command and you're not trying to test "
"the debugger, then you're making a really big mistake."
);
}
void CmdInternalTesting::onClientImpl(DebuggerClient &client) {
TRACE(2, "CmdInternalTesting::onClientImpl\n");
if (DebuggerCommand::displayedHelp(client)) return;
if (client.argCount() == 0) {
help(client);
return;
}
client.info("Executing internal test...");
m_arg = client.argValue(1);
if (client.arg(1, "badcmdtypesend")) {
// Give the cmd a bad type and send it over. This should cause the proxy to
// disconnect from us.
m_type = KindOfInternalTestingBad;
client.sendToServer(this);
throw DebuggerConsoleExitException(); // Expect no response
} else if (client.arg(1, "badcmdtypereceive")) {
client.xend<CmdInternalTesting>(this);
return;
} else if (client.arg(1, "shortcmdsend")) {
m_arg = "shortcmd"; // Force send to drop a field.
client.sendToServer(this);
throw DebuggerConsoleExitException(); // Expect no response
} else if (client.arg(1, "shortcmdreceive")) {
client.xend<CmdInternalTesting>(this);
return;
} else if (client.arg(1, "segfaultClient")) {
int *px = nullptr;
*px = 42;
} else if (client.arg(1, "segfaultServer")) {
client.xend<CmdInternalTesting>(this);
return;
}
help(client);
}
bool CmdInternalTesting::onServer(DebuggerProxy &proxy) {
TRACE(2, "CmdInternalTesting::onServer\n");
if (m_arg == "badcmdtypereceive") {
m_type = KindOfInternalTestingBad; // Send back a bad cmd.
} else if (m_arg == "shortcmdreceive") {
m_arg = "shortcmd"; // Force send to drop a field
} else if (m_arg == "segfaultServer") {
int *px = nullptr;
*px = 42;
}
return proxy.sendToClient(this);
}
///////////////////////////////////////////////////////////////////////////////
}}