Arquivos
hhvm/hphp/runtime/debugger/debugger_base.h
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

240 linhas
7.6 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. |
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_EVAL_DEBUGGER_BASE_H_
#define incl_HPHP_EVAL_DEBUGGER_BASE_H_
#include "hphp/runtime/debugger/break_point.h"
#include "hphp/runtime/base/util/string_buffer.h"
#include "hphp/runtime/base/util/exceptions.h"
#include "hphp/util/hdf.h"
namespace HPHP { namespace Eval {
///////////////////////////////////////////////////////////////////////////////
// startup options for debugger client
struct DebuggerClientOptions {
std::string host;
int port;
std::string extension;
StringVec cmds;
std::string sandbox;
std::string user;
bool apiMode;
std::string configFName;
DebuggerClientOptions() : port(-1), apiMode(false) {}
};
///////////////////////////////////////////////////////////////////////////////
// exceptions
// Client-side exceptions
class DebuggerClientException : public Exception {};
// Exception used to force the debugger client to exit the command prompt loop
// implemented in DebuggerClient::console(). Commands throw this when they do
// something that causes the server to start running code again, so we pop out
// of the command prompt loop and go back to waiting for interrupt messages from
// the server.
class DebuggerConsoleExitException : public DebuggerClientException {};
// Exception thrown when the client detects an error in the communication
// protocol with the server, but believes the connection is still alive.
// I.e., bad command type back, missing fields, etc.
class DebuggerProtocolException : public DebuggerClientException {};
// Exception thrown when the client loses its connection to the server.
class DebuggerServerLostException : public DebuggerClientException {};
// Both client- and server-side exceptions
class DebuggerException : public Exception {
EXCEPTION_COMMON_IMPL(DebuggerException);
};
// Exception thrown in two cases:
//
// Client-side: thrown in cases where the client should completely exit. This
// will pop us out of both the command prompt loop and the message loop for the
// server, and cause the client to quit.
//
// Server-side: thrown when the server detects that the client is exiting. This
// causes a thread which is currently interrupted to terminate it's request with
// this exception. The message attempts to reflect that a request which was
// being debugged has been terminated.
class DebuggerClientExitException : public DebuggerException {
virtual const char *what() const throw() {
return "Debugger client has just quit, request (if any) terminated.";
}
EXCEPTION_COMMON_IMPL(DebuggerClientExitException);
};
class DebuggerRestartException : public DebuggerException {
public:
explicit DebuggerRestartException(StringVecPtr args) : m_args(args) {}
~DebuggerRestartException() throw() {}
virtual const char *what() const throw() {
return "Debugger restarting program or aborting web request.";
}
EXCEPTION_COMMON_IMPL(DebuggerRestartException);
StringVecPtr m_args;
};
///////////////////////////////////////////////////////////////////////////////
// utility functions
enum CodeColor {
CodeColorNone,
CodeColorKeyword,
CodeColorComment,
CodeColorString,
CodeColorVariable,
CodeColorHtml,
CodeColorTag,
CodeColorDeclaration,
CodeColorConstant,
CodeColorLineNo
};
/**
* "line", starting line number, or 0 for no line number display.
* "lineFocus", the line to highlight, with gray background.
* highlight_code() doesn't need <?php and will treat source entirely PHP.
*/
String highlight_php(CStrRef source, int line = 0, int lineFocus0 = 0,
int charFocus0 = 0, int lineFocus1 = 0,
int charFocus1 = 0);
String highlight_code(CStrRef source, int line = 0, int lineFocus0 = 0,
int charFocus0 = 0, int lineFocus1 = 0,
int charFocus1 = 0);
extern const char *PHP_KEYWORDS[];
///////////////////////////////////////////////////////////////////////////////
DECLARE_BOOST_TYPES(DMachineInfo);
class DMachineInfo {
public:
DMachineInfo()
: m_port(0), m_interrupting(false), m_sandboxAttached(false),
m_initialized(false), m_rpcPort(0) {}
std::string m_name;
int m_port;
DebuggerThriftBuffer m_thrift;
bool m_interrupting; // True if the machine is paused at an interrupt
bool m_sandboxAttached;
bool m_initialized; // True if the initial connection protocol is complete
std::string m_rpcHost;
int m_rpcPort;
};
///////////////////////////////////////////////////////////////////////////////
DECLARE_BOOST_TYPES(DSandboxInfo);
class DSandboxInfo {
public:
DSandboxInfo() {}
explicit DSandboxInfo(const std::string &id) { set(id);}
std::string m_user;
std::string m_name;
std::string m_path;
const std::string &id() const;
const std::string desc() const;
static DSandboxInfo CreateDummyInfo(uint64_t unique);
bool valid() const { return !m_user.empty(); }
void set(const std::string &id);
void update(const DSandboxInfo &src);
void sendImpl(ThriftBuffer &thrift);
void recvImpl(ThriftBuffer &thrift);
private:
mutable std::string m_cached_id;
};
///////////////////////////////////////////////////////////////////////////////
DECLARE_BOOST_TYPES(DThreadInfo);
class DThreadInfo {
public:
int64_t m_id;
std::string m_desc;
std::string m_type;
std::string m_url;
int m_index; // used by DebuggerClient
void sendImpl(ThriftBuffer &thrift);
void recvImpl(ThriftBuffer &thrift);
};
///////////////////////////////////////////////////////////////////////////////
class BreakPointInfo;
DECLARE_BOOST_TYPES(DFunctionInfo);
class DFunctionInfo {
public:
std::string m_namespace;
std::string m_class;
std::string m_function;
std::string getName() const;
std::string site(std::string &preposition) const;
std::string desc(const BreakPointInfo *bpi) const;
void sendImpl(ThriftBuffer &thrift);
void recvImpl(ThriftBuffer &thrift);
};
///////////////////////////////////////////////////////////////////////////////
DECLARE_BOOST_TYPES(Macro);
class Macro {
public:
std::string m_name;
StringVec m_cmds;
unsigned int m_index; // currently playing position
std::string desc(const char *indent);
void load(Hdf node);
void save(Hdf node);
};
///////////////////////////////////////////////////////////////////////////////
// Simple base class which can be overridden to provide implementation-specific
// usage logging for the debugger from both client- and server-side.
class DebuggerUsageLogger {
public:
virtual ~DebuggerUsageLogger() {}
virtual void init() {}
virtual void log(const std::string &mode, const std::string &cmd,
const std::string &data) {}
};
///////////////////////////////////////////////////////////////////////////////
}}
#endif // incl_HPHP_EVAL_DEBUGGER_BASE_H_