Arquivos
hhvm/hphp/runtime/debugger/debugger.h
T
Mike Magruder 6e6ebfe8d8 Change hphpd –h option to make it a little easier to use, provide warning when no server specified
People sometimes make mistakes and launch hphpd without connecting to a server, but expect to be in the server environment when evaluating expressions. Modified the –h option to not require a host specification, and default to localhost, so "hphpd –h" is a valid way to launch now. Provide a warning on launch when no args are specified at all warning the user that they're not connected, and giving suggestions for how to connect if necessary. There are reasonable use cases for launching hphpd with no args (so, no connection and no local script to debug) and I didn't want to take those away by automatically connecting to a server at localhost if launched with no args. I'm hoping the warning is sufficiently helpful.
2013-06-25 12:22:59 -07:00

206 linhas
8.2 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_H_
#define incl_HPHP_EVAL_DEBUGGER_H_
#include "hphp/util/lock.h"
#include "hphp/runtime/debugger/debugger_proxy.h"
#include "hphp/runtime/base/program_functions.h"
#include "tbb/concurrent_hash_map.h"
#include "tbb/concurrent_queue.h"
namespace HPHP { namespace Eval {
// Tag used on server log messages to highlight that they are likely useful to
// show to users.
#define DEBUGGER_LOG_TAG "[DBGINFO] "
///////////////////////////////////////////////////////////////////////////////
// The Debugger generally manages proxies, sandboxes, and is the inital handler
// of interrupts from the VM. It associates VM threads with sandboxes, and
// sandboxes with proxies. Interrupts get minimal handling before being handed
// off to the proper proxy.
DECLARE_BOOST_TYPES(CmdInterrupt);
class Debugger {
public:
Debugger() : m_usageLogger(nullptr) {}
// Start/stop Debugger for remote debugging.
static bool StartServer();
static DebuggerProxyPtr StartClient(const DebuggerClientOptions &options);
static void Stop();
// Add a new sandbox a debugger can connect to.
static void RegisterSandbox(const DSandboxInfo &sandbox);
static void UnregisterSandbox(CStrRef id);
static void RegisterThread();
// Add/remove/change DebuggerProxy.
static DebuggerProxyPtr CreateProxy(SmartPtr<Socket> socket, bool local);
static void RemoveProxy(DebuggerProxyPtr proxy);
static bool SwitchSandbox(DebuggerProxyPtr proxy, const std::string &newId,
bool force);
static int CountConnectedProxy();
static DebuggerProxyPtr GetProxy();
static void GetRegisteredSandboxes(DSandboxInfoPtrVec &sandboxes);
static bool IsThreadDebugging(int64_t tid);
static void RetireDummySandboxThread(DummySandbox* toRetire);
static void CleanupDummySandboxThreads();
// Request interrupt on threads that a proxy is attached to
static void RequestInterrupt(DebuggerProxyPtr proxy);
// Debugger session to be called in a loop
static void DebuggerSession(const DebuggerClientOptions& options,
bool restart);
// Called from differnt time point of execution thread.
static void InterruptSessionStarted(const char *file,
const char *error = nullptr);
static void InterruptSessionEnded(const char *file);
static void InterruptRequestStarted(const char *url);
static void InterruptRequestEnded(const char *url);
static void InterruptPSPEnded(const char *url);
// Interrupt from VM
static void InterruptVMHook(int type = BreakPointReached,
CVarRef e = null_variant);
// Surround text with color, if set.
static void SetTextColors();
static String ColorStdout(CStrRef s);
static String ColorStderr(CStrRef s);
// Log debugging state when we're shutting the server down.
enum ShutdownKind {
Normal,
Abnormal
};
static void LogShutdown(ShutdownKind shutdownKind);
// Usage logging
static void SetUsageLogger(DebuggerUsageLogger *usageLogger);
static void InitUsageLogging();
static void UsageLog(const std::string &mode, const std::string &cmd,
const std::string &data = "");
static void UsageLogInterrupt(const std::string &mode, CmdInterrupt &cmd);
private:
static Debugger s_debugger;
static bool s_clientStarted;
static void Interrupt(int type, const char *program,
InterruptSite *site = nullptr, const char *error = nullptr);
static void InterruptWithUrl(int type, const char *url);
static const char *InterruptTypeName(CmdInterrupt &cmd);
// The following maps use a "sandbox id", or sid, which is a string containing
// the user's name, a tab, and the sandbox name. I.e., "mikemag\tdefault".
// Map of "sandbox id"->proxy. The map contains an entry for every active
// proxy attached to this process, keyed by the sandbox being debugged. It
// also contains an entry for the proxy's dummy sandbox, keyed by the dummy
// sandbox id which is basically the proxy pointer rendered as a string.
typedef tbb::concurrent_hash_map<const StringData*, DebuggerProxyPtr,
StringDataHashCompare> ProxyMap;
ProxyMap m_proxyMap;
// Map of "sandbox id"->"sandbox info" for any sandbox the process has seen.
// Entries are made when a request is received for a sandbox, or when a switch
// to a new sandbox id is made via CmdMachine. The latter alows a debugger to
// "pre-attach" to a sandbox before the first request is every received.
// Entries are never removed.
typedef tbb::concurrent_hash_map<const StringData*, DSandboxInfoPtr,
StringDataHashCompare> SandboxMap;
SandboxMap m_sandboxMap;
// Map of "sandbox id"->"set of threads executing requests in the sandbox".
typedef std::set<ThreadInfo*> ThreadInfoSet;
typedef tbb::concurrent_hash_map<const StringData*, ThreadInfoSet,
StringDataHashCompare> SandboxThreadInfoMap;
SandboxThreadInfoMap m_sandboxThreadInfoMap;
// "thread id"->"thread info". Each thread which is being debugged is
// added to this map.
typedef tbb::concurrent_hash_map<int64_t, ThreadInfo*> ThreadInfoMap;
ThreadInfoMap m_threadInfos;
typedef tbb::concurrent_queue<DummySandbox*> DummySandboxQ;
DummySandboxQ m_cleanupDummySandboxQ;
bool isThreadDebugging(int64_t id);
void registerThread();
void addOrUpdateSandbox(const DSandboxInfo &sandbox);
DSandboxInfoPtr getSandbox(const StringData* sid);
void getSandboxes(DSandboxInfoPtrVec &sandboxes);
void registerSandbox(const DSandboxInfo &sandbox);
void unregisterSandbox(const StringData* sandboxId);
void getSandboxThreads(const DSandboxInfo &sandbox,
std::set<ThreadInfo*>& set);
void requestInterrupt(DebuggerProxyPtr proxy);
void setDebuggerFlag(const StringData* sandboxId, bool flag);
DebuggerProxyPtr createProxy(SmartPtr<Socket> socket, bool local);
void removeProxy(DebuggerProxyPtr proxy);
DebuggerProxyPtr findProxy(const StringData* sandboxId);
int countConnectedProxy() { return m_proxyMap.size(); } ;
void updateProxySandbox(DebuggerProxyPtr proxy,
const StringData* sandboxId);
bool switchSandboxImpl(DebuggerProxyPtr proxy,
const StringData* newSid,
bool force);
bool switchSandbox(DebuggerProxyPtr proxy, const std::string &newId,
bool force);
void retireDummySandboxThread(DummySandbox* toRetire);
void cleanupDummySandboxThreads();
// A usage logger which is set by a provider to an implementation-specific
// subclass if usage logging is enabled.
DebuggerUsageLogger *m_usageLogger;
};
class DebuggerDummyEnv {
public:
DebuggerDummyEnv();
~DebuggerDummyEnv();
};
// Suppress the debugger's ability to get interrupted while executing PHP.
// Primarily used to suppress debugger events while evaling PHP in response
// to commands like print, or for expressions in conditional breakpoints.
class EvalBreakControl {
public:
explicit EvalBreakControl(bool noBreak);
~EvalBreakControl();
private:
bool m_noBreakSave;
};
///////////////////////////////////////////////////////////////////////////////
}}
#endif // incl_HPHP_EVAL_DEBUGGER_H_