Remove the rest of the dead instrumentation code
This is the follow on to https://phabricator.fb.com/D805320. Removing the rest of the instrumentation code.
Esse commit está contido em:
@@ -78,7 +78,7 @@ VMExecutionContext::VMExecutionContext() :
|
||||
m_preg_backtrace_limit(RuntimeOption::PregBacktraceLimit),
|
||||
m_preg_recursion_limit(RuntimeOption::PregRecursionLimit),
|
||||
m_lambdaCounter(0), m_nesting(0),
|
||||
m_injTables(nullptr), m_breakPointFilter(nullptr), m_lastLocFilter(nullptr),
|
||||
m_breakPointFilter(nullptr), m_lastLocFilter(nullptr),
|
||||
m_interpreting(false), m_dbgNoBreak(false),
|
||||
m_coverPrevLine(-1), m_coverPrevUnit(nullptr),
|
||||
m_executingSetprofileCallback(false) {
|
||||
@@ -137,7 +137,6 @@ VMExecutionContext::~VMExecutionContext() {
|
||||
delete *it;
|
||||
}
|
||||
|
||||
delete m_injTables;
|
||||
delete m_breakPointFilter;
|
||||
delete m_lastLocFilter;
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#include "hphp/runtime/vm/funcdict.h"
|
||||
#include "hphp/runtime/vm/func.h"
|
||||
#include "hphp/runtime/vm/bytecode.h"
|
||||
#include "hphp/runtime/vm/instrumentation.h"
|
||||
#include "hphp/util/base.h"
|
||||
#include "hphp/util/lock.h"
|
||||
#include "hphp/util/thread_local.h"
|
||||
@@ -669,7 +668,6 @@ public:
|
||||
VarEnv* getVarEnv();
|
||||
void setVar(StringData* name, TypedValue* v, bool ref);
|
||||
Array getLocalDefinedVariables(int frame);
|
||||
HPHP::InjectionTables* m_injTables;
|
||||
HPHP::PCFilter* m_breakPointFilter;
|
||||
HPHP::PCFilter* m_lastLocFilter;
|
||||
bool m_interpreting;
|
||||
|
||||
@@ -50,7 +50,6 @@
|
||||
#include "hphp/runtime/debugger/cmd/cmd_signal.h"
|
||||
#include "hphp/runtime/debugger/cmd/cmd_macro.h"
|
||||
#include "hphp/runtime/debugger/cmd/cmd_config.h"
|
||||
#include "hphp/runtime/debugger/cmd/cmd_instrument.h"
|
||||
#include "hphp/runtime/debugger/cmd/cmd_complete.h"
|
||||
//tag: new_cmd.php inserts new command here, do NOT remove/modify this line
|
||||
|
||||
|
||||
@@ -1,278 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| 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_instrument.h"
|
||||
#include "hphp/runtime/vm/instrumentation.h"
|
||||
#include "hphp/runtime/ext/ext_file.h"
|
||||
|
||||
namespace HPHP { namespace Eval {
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRACE_SET_MOD(debugger);
|
||||
|
||||
void CmdInstrument::sendImpl(DebuggerThriftBuffer &thrift) {
|
||||
DebuggerCommand::sendImpl(thrift);
|
||||
thrift.write(m_type);
|
||||
thrift.write(m_enabled);
|
||||
assert(m_instPoints);
|
||||
InstPointInfo::SendImpl(*m_instPoints, thrift);
|
||||
}
|
||||
|
||||
void CmdInstrument::recvImpl(DebuggerThriftBuffer &thrift) {
|
||||
DebuggerCommand::recvImpl(thrift);
|
||||
thrift.read(m_type);
|
||||
thrift.read(m_enabled);
|
||||
InstPointInfo::RecvImpl(m_ips, thrift);
|
||||
}
|
||||
|
||||
void CmdInstrument::help(DebuggerClient &client) {
|
||||
client.helpTitle("Instrument Command");
|
||||
// TODO: more functionalities
|
||||
client.helpCmds("inst here <file> [desc]",
|
||||
"inject <file> to here",
|
||||
"inst <func>() <file> [desc]",
|
||||
"inject <file> to the entry point of <func>",
|
||||
"inst [l]ist",
|
||||
"list injections",
|
||||
"inst [c]lear",
|
||||
"clear all injections",
|
||||
nullptr);
|
||||
client.helpBody(
|
||||
"Use this command to instrument the program"
|
||||
);
|
||||
}
|
||||
|
||||
void CmdInstrument::onClientImpl(DebuggerClient &client) {
|
||||
if (DebuggerCommand::displayedHelp(client)) return;
|
||||
if (client.argCount() == 1) {
|
||||
if (client.argValue(1) == "list" || client.argValue(1) == "l") {
|
||||
listInst(client);
|
||||
return;
|
||||
}
|
||||
if (client.argValue(1) == "clear" || client.argValue(1) == "c") {
|
||||
clearInst(client);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (client.argCount() < 2 || client.argValue(1) == "help") {
|
||||
help(client);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string loc = client.argValue(1);
|
||||
std::string file = client.argValue(2);
|
||||
std::string desc;
|
||||
if (client.argCount() >= 3) {
|
||||
desc = client.argValue(3);
|
||||
}
|
||||
Variant code = f_file_get_contents(file.c_str());
|
||||
if (code.isNull()) {
|
||||
client.error("Unable to read from file %s", file.c_str());
|
||||
return;
|
||||
}
|
||||
m_instPoints = client.getInstPoints();
|
||||
if (loc == "here") {
|
||||
InstPointInfoPtr ipi(new InstPointInfo());
|
||||
ipi->setLocHere();
|
||||
ipi->m_code = (std::string) code.toString();
|
||||
ipi->m_desc = desc;
|
||||
m_instPoints->push_back(ipi);
|
||||
} else if (loc.rfind("()") == loc.size() - 2){
|
||||
InstPointInfoPtr ipi(new InstPointInfo());
|
||||
ipi->setLocFuncEntry(loc.substr(0, loc.size() - 2));
|
||||
ipi->m_code = (std::string) code.toString();
|
||||
ipi->m_desc = desc;
|
||||
m_instPoints->push_back(ipi);
|
||||
} else {
|
||||
client.error("Not implemented\n");
|
||||
return;
|
||||
}
|
||||
m_type = ActionWrite;
|
||||
CmdInstrumentPtr instCmdPtr = client.xend<CmdInstrument>(this);
|
||||
if (!instCmdPtr->m_enabled) {
|
||||
client.error("Instrumentation is not enabled on the server");
|
||||
}
|
||||
client.setInstPoints(instCmdPtr->m_ips);
|
||||
CmdInstrument::PrintInstPoints(client);
|
||||
}
|
||||
|
||||
static const StaticString s_valid("valid");
|
||||
static const StaticString s_desc("desc");
|
||||
static const StaticString s_type("type");
|
||||
static const StaticString s_file_line("file_line");
|
||||
static const StaticString s_file("file");
|
||||
static const StaticString s_line("line");
|
||||
static const StaticString s_func_entry("func_entry");
|
||||
static const StaticString s_func("func");
|
||||
|
||||
void CmdInstrument::setClientOutput(DebuggerClient &client) {
|
||||
// Output all instrumentation point info
|
||||
client.setOutputType(DebuggerClient::OTValues);
|
||||
Array values;
|
||||
InstPointInfoPtrVec* ips = client.getInstPoints();
|
||||
for (unsigned int i = 0; i < ips->size(); i++) {
|
||||
InstPointInfoPtr ipi = (*ips)[i];
|
||||
Array instpoint;
|
||||
instpoint.set(s_valid, ipi->m_valid);
|
||||
instpoint.set(s_desc, ipi->m_desc);
|
||||
if (ipi->m_locType == InstPointInfo::LocFileLine) {
|
||||
instpoint.set(s_type, s_file_line);
|
||||
instpoint.set(s_file, ipi->m_file);
|
||||
instpoint.set(s_line, ipi->m_line);
|
||||
} else if (ipi->m_locType == InstPointInfo::LocFuncEntry) {
|
||||
instpoint.set(s_type, s_func_entry);
|
||||
instpoint.set(s_func, ipi->m_func);
|
||||
}
|
||||
values.append(instpoint);
|
||||
}
|
||||
client.setOTValues(values);
|
||||
}
|
||||
|
||||
bool CmdInstrument::onServer(DebuggerProxy &proxy) {
|
||||
m_instPoints = &m_ips;
|
||||
m_enabled = true;
|
||||
if (m_type == ActionRead) {
|
||||
readFromTable(proxy);
|
||||
} else if (m_type == ActionWrite) {
|
||||
validateAndWriteToTable(proxy);
|
||||
}
|
||||
return proxy.sendToClient(this);
|
||||
}
|
||||
|
||||
void CmdInstrument::readFromTable(DebuggerProxy &proxy) {
|
||||
proxy.readInjTablesFromThread();
|
||||
m_ips.clear();
|
||||
if (!proxy.getInjTables()) {
|
||||
// nothing there
|
||||
return;
|
||||
}
|
||||
// Bytecode address
|
||||
InjectionTableInt64* tablePC =
|
||||
proxy.getInjTables()->getInt64Table(InstHookTypeBCPC);
|
||||
if (tablePC) {
|
||||
for (InjectionTableInt64::const_iterator it = tablePC->begin();
|
||||
it != tablePC->end(); ++it) {
|
||||
const Injection* inj = it->second;
|
||||
InstPointInfoPtr ipi(new InstPointInfo());
|
||||
ipi->m_valid = true;
|
||||
if (inj->m_desc) {
|
||||
ipi->m_desc = inj->m_desc->data();
|
||||
}
|
||||
ipi->m_locType = InstPointInfo::LocFileLine;
|
||||
// TODO use pc to figure out m_file and m_line
|
||||
// uchar* pc = (uchar*)it->first;
|
||||
m_ips.push_back(ipi);
|
||||
}
|
||||
}
|
||||
InjectionTableSD* tableFEntry =
|
||||
proxy.getInjTables()->getSDTable(InstHookTypeFuncEntry);
|
||||
if (tableFEntry) {
|
||||
for (InjectionTableSD::const_iterator it = tableFEntry->begin();
|
||||
it != tableFEntry->end(); ++it) {
|
||||
const Injection* inj = it->second;
|
||||
InstPointInfoPtr ipi(new InstPointInfo());
|
||||
ipi->m_valid = true;
|
||||
if (inj->m_desc) {
|
||||
ipi->m_desc = inj->m_desc->data();
|
||||
}
|
||||
ipi->m_func = it->first->data();
|
||||
ipi->m_locType = InstPointInfo::LocFuncEntry;
|
||||
m_ips.push_back(ipi);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CmdInstrument::validateAndWriteToTable(DebuggerProxy &proxy) {
|
||||
if (!proxy.getInjTables()) {
|
||||
proxy.setInjTables(new InjectionTables());
|
||||
}
|
||||
InjectionTableInt64* tablePC = nullptr;
|
||||
InjectionTableSD* tableFEntry = nullptr;
|
||||
|
||||
for (int i = 0; i < (int)m_ips.size(); i++) {
|
||||
InstPointInfoPtr ipi = m_ips[i];
|
||||
const Injection* inj =
|
||||
InjectionCache::GetInjection(ipi->m_code, ipi->m_desc);
|
||||
if (!inj) { // error in the code
|
||||
continue;
|
||||
}
|
||||
if (ipi->m_locType == InstPointInfo::LocHere ||
|
||||
ipi->m_locType == InstPointInfo::LocFileLine) {
|
||||
// bytecode address
|
||||
const uchar *pc = ipi->lookupPC();
|
||||
if (pc == nullptr) {
|
||||
continue;
|
||||
}
|
||||
if (tablePC == nullptr) {
|
||||
tablePC = new InjectionTableInt64();
|
||||
}
|
||||
ipi->m_valid = true;
|
||||
(*tablePC)[(int64_t)pc] = inj;
|
||||
}
|
||||
if (ipi->m_locType == InstPointInfo::LocFuncEntry) {
|
||||
StackStringData sd(ipi->m_func.c_str(), ipi->m_func.size(), AttachLiteral);
|
||||
const StringData* sdCache = InjectionCache::GetStringData(&sd);
|
||||
if (tableFEntry == nullptr) {
|
||||
tableFEntry = new InjectionTableSD();
|
||||
}
|
||||
ipi->m_valid = true;
|
||||
(*tableFEntry)[sdCache] = inj;
|
||||
}
|
||||
}
|
||||
|
||||
proxy.getInjTables()->setInt64Table(InstHookTypeBCPC, tablePC);
|
||||
proxy.getInjTables()->setSDTable(InstHookTypeFuncEntry, tableFEntry);
|
||||
|
||||
proxy.writeInjTablesToThread();
|
||||
}
|
||||
|
||||
void CmdInstrument::listInst(DebuggerClient &client) {
|
||||
m_type = ActionRead;
|
||||
m_instPoints = client.getInstPoints();
|
||||
CmdInstrumentPtr instCmdPtr = client.xend<CmdInstrument>(this);
|
||||
client.setInstPoints(instCmdPtr->m_ips);
|
||||
PrintInstPoints(client);
|
||||
}
|
||||
|
||||
void CmdInstrument::clearInst(DebuggerClient &client) {
|
||||
m_type = ActionWrite;
|
||||
m_instPoints = client.getInstPoints();
|
||||
m_instPoints->clear();
|
||||
CmdInstrumentPtr instCmdPtr = client.xend<CmdInstrument>(this);
|
||||
client.setInstPoints(instCmdPtr->m_ips);
|
||||
PrintInstPoints(client);
|
||||
}
|
||||
|
||||
void CmdInstrument::PrintInstPoints(DebuggerClient &client) {
|
||||
InstPointInfoPtrVec* ips = client.getInstPoints();
|
||||
int size = ips->size();
|
||||
client.print("%d instrumentation points", size);
|
||||
for (int i = 0; i < size; i++) {
|
||||
InstPointInfoPtr ipi = (*ips)[i];
|
||||
if (ipi->m_locType == InstPointInfo::LocFileLine) {
|
||||
client.print(" %d\t%s\t%s\tfile:\t%s:%d", i,
|
||||
ipi->m_valid ? "valid" : "invalid",
|
||||
ipi->m_desc.c_str(), ipi->m_file.c_str(), ipi->m_line);
|
||||
} else if (ipi->m_locType == InstPointInfo::LocFuncEntry) {
|
||||
client.print(" %d\t%s\t%s\tfunc entry:\t%s", i,
|
||||
ipi->m_valid ? "valid" : "invalid",
|
||||
ipi->m_desc.c_str(), ipi->m_func.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
}}
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| 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_CMD_INSTRUMENT_H_
|
||||
#define incl_HPHP_EVAL_DEBUGGER_CMD_INSTRUMENT_H_
|
||||
|
||||
#include "hphp/runtime/debugger/debugger_command.h"
|
||||
#include "hphp/runtime/debugger/inst_point.h"
|
||||
|
||||
namespace HPHP { namespace Eval {
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DECLARE_BOOST_TYPES(CmdInstrument);
|
||||
class CmdInstrument : public DebuggerCommand {
|
||||
public:
|
||||
CmdInstrument() : DebuggerCommand(KindOfInstrument), m_type(ActionRead),
|
||||
m_enabled(false), m_instPoints(nullptr) {}
|
||||
|
||||
virtual void help(DebuggerClient &client);
|
||||
virtual void setClientOutput(DebuggerClient &client);
|
||||
virtual bool onServer(DebuggerProxy &proxy);
|
||||
|
||||
protected:
|
||||
virtual void onClientImpl(DebuggerClient &client);
|
||||
virtual void sendImpl(DebuggerThriftBuffer &thrift);
|
||||
virtual void recvImpl(DebuggerThriftBuffer &thrift);
|
||||
|
||||
private:
|
||||
enum ActionType {
|
||||
ActionRead,
|
||||
ActionWrite,
|
||||
};
|
||||
int8_t m_type;
|
||||
bool m_enabled;
|
||||
|
||||
InstPointInfoPtrVec *m_instPoints;
|
||||
InstPointInfoPtrVec m_ips;
|
||||
|
||||
void readFromTable(DebuggerProxy &proxy);
|
||||
void validateAndWriteToTable(DebuggerProxy &proxy);
|
||||
|
||||
void listInst(DebuggerClient &client);
|
||||
void clearInst(DebuggerClient &client);
|
||||
|
||||
static void PrintInstPoints(DebuggerClient &client);
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
}}
|
||||
|
||||
#endif // incl_HPHP_EVAL_DEBUGGER_CMD_INSTRUMENT_H_
|
||||
@@ -379,7 +379,6 @@ void Debugger::registerSandbox(const DSandboxInfo &sandbox) {
|
||||
DebuggerProxyPtr proxy = findProxy(sid);
|
||||
if (proxy) {
|
||||
ti->m_reqInjectionData.setDebugger(true);
|
||||
proxy->writeInjTablesToThread();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
|
||||
#include "hphp/runtime/debugger/debugger.h"
|
||||
#include "hphp/runtime/debugger/debugger_client_settings.h"
|
||||
#include "hphp/runtime/debugger/inst_point.h"
|
||||
#include "hphp/runtime/base/debuggable.h"
|
||||
#include "hphp/util/text_color.h"
|
||||
#include "hphp/util/hdf.h"
|
||||
@@ -233,8 +232,6 @@ public:
|
||||
*/
|
||||
BreakPointInfoPtr getCurrentLocation() const { return m_breakpoint;}
|
||||
BreakPointInfoPtrVec *getBreakPoints() { return &m_breakpoints;}
|
||||
InstPointInfoPtrVec *getInstPoints() { return &m_instPoints;}
|
||||
void setInstPoints(InstPointInfoPtrVec &ips) { m_instPoints = ips;}
|
||||
void setMatchedBreakPoints(BreakPointInfoPtrVec breakpoints);
|
||||
void setCurrentLocation(int64_t threadId, BreakPointInfoPtr breakpoint);
|
||||
BreakPointInfoPtrVec *getMatchedBreakPoints() { return &m_matched;}
|
||||
@@ -421,7 +418,6 @@ private:
|
||||
BreakPointInfoPtrVec m_breakpoints;
|
||||
BreakPointInfoPtr m_breakpoint;
|
||||
BreakPointInfoPtrVec m_matched;
|
||||
InstPointInfoPtrVec m_instPoints;
|
||||
|
||||
// list command's current location, which may be different from m_breakpoint
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ DebuggerProxy::DebuggerProxy(SmartPtr<Socket> socket, bool local)
|
||||
: m_stopped(false), m_local(local), m_dummySandbox(nullptr),
|
||||
m_hasBreakPoints(false), m_threadMode(Normal), m_thread(0),
|
||||
m_signalThread(this, &DebuggerProxy::pollSignal),
|
||||
m_signum(CmdSignal::SignalNone), m_injTables(nullptr) {
|
||||
m_signum(CmdSignal::SignalNone) {
|
||||
TRACE(2, "DebuggerProxy::DebuggerProxy\n");
|
||||
m_thrift.create(socket);
|
||||
m_dummyInfo = DSandboxInfo::CreateDummyInfo((int64_t)this);
|
||||
@@ -49,8 +49,6 @@ DebuggerProxy::~DebuggerProxy() {
|
||||
m_dummySandbox->stop();
|
||||
}
|
||||
|
||||
delete m_injTables;
|
||||
|
||||
Debugger::UsageLog("server", "disconnect");
|
||||
TRACE_RB(2, "DebuggerProxy::~DebuggerProxy complete\n");
|
||||
}
|
||||
@@ -715,34 +713,6 @@ BreakPointInfoPtr DebuggerProxy::getBreakPointAtCmd(CmdInterrupt& cmd) {
|
||||
return BreakPointInfoPtr();
|
||||
}
|
||||
|
||||
void DebuggerProxy::readInjTablesFromThread() {
|
||||
TRACE(2, "DebuggerProxy::readInjTablesFromThread\n");
|
||||
ThreadInfo* ti = ThreadInfo::s_threadInfo.getNoCheck();
|
||||
if (ti->m_reqInjectionData.getDummySandbox()) {
|
||||
return;
|
||||
}
|
||||
if (m_injTables) {
|
||||
delete m_injTables;
|
||||
m_injTables = nullptr;
|
||||
}
|
||||
if (!g_vmContext->m_injTables) {
|
||||
return;
|
||||
}
|
||||
m_injTables = g_vmContext->m_injTables->clone();
|
||||
}
|
||||
|
||||
void DebuggerProxy::writeInjTablesToThread() {
|
||||
TRACE(2, "DebuggerProxy::writeInjTablesToThread\n");
|
||||
if (g_vmContext->m_injTables) {
|
||||
delete g_vmContext->m_injTables;
|
||||
g_vmContext->m_injTables = nullptr;
|
||||
}
|
||||
if (!m_injTables) {
|
||||
return;
|
||||
}
|
||||
g_vmContext->m_injTables = m_injTables->clone();
|
||||
}
|
||||
|
||||
int DebuggerProxy::getRealStackDepth() {
|
||||
TRACE(2, "DebuggerProxy::getRealStackDepth\n");
|
||||
int depth = 0;
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#include "hphp/util/async_func.h"
|
||||
#include "hphp/runtime/base/file/socket.h"
|
||||
#include "hphp/runtime/debugger/dummy_sandbox.h"
|
||||
#include "hphp/runtime/vm/instrumentation.h"
|
||||
|
||||
namespace HPHP { namespace Eval {
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@@ -105,12 +104,6 @@ public:
|
||||
void checkStop();
|
||||
void forceQuit();
|
||||
|
||||
// For instrumentation
|
||||
HPHP::InjectionTables* getInjTables() const { return m_injTables; }
|
||||
void setInjTables(HPHP::InjectionTables* tables) { m_injTables = tables;}
|
||||
void readInjTablesFromThread();
|
||||
void writeInjTablesToThread();
|
||||
|
||||
private:
|
||||
bool blockUntilOwn(CmdInterrupt &cmd, bool check);
|
||||
bool checkBreakPoints(CmdInterrupt &cmd);
|
||||
@@ -151,9 +144,6 @@ private:
|
||||
|
||||
Mutex m_signumMutex;
|
||||
int m_signum;
|
||||
|
||||
// For instrumentation
|
||||
HPHP::InjectionTables* m_injTables;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -1,112 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| 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/inst_point.h"
|
||||
#include "hphp/runtime/debugger/debugger.h"
|
||||
#include "hphp/runtime/debugger/debugger_proxy.h"
|
||||
#include "hphp/runtime/debugger/debugger_thrift_buffer.h"
|
||||
|
||||
namespace HPHP { namespace Eval {
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
TRACE_SET_MOD(debugger);
|
||||
|
||||
const uchar* InstPointInfo::lookupPC() {
|
||||
TRACE(2, "InstPointInfo::lookupPC\n");
|
||||
VMExecutionContext* context = g_vmContext;
|
||||
if (m_locType == LocHere) {
|
||||
// Instrument to current location
|
||||
ActRec *fp = context->getFP();
|
||||
if (!fp) {
|
||||
return nullptr;
|
||||
}
|
||||
PC pc = context->getPC();
|
||||
HPHP::Unit *unit = fp->m_func->unit();
|
||||
if (!unit) {
|
||||
return nullptr;
|
||||
}
|
||||
m_file = unit->filepath()->data();
|
||||
m_line = unit->getLineNumber(unit->offsetOf(pc));
|
||||
return pc;
|
||||
}
|
||||
// TODO for file and line
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void InstPointInfo::setLocHere() {
|
||||
TRACE(2, "InstPointInfo::setLocHere\n");
|
||||
m_locType = LocHere;
|
||||
}
|
||||
|
||||
void InstPointInfo::setLocFileLine(const std::string& file, int line) {
|
||||
TRACE(2, "InstPointInfo::setLocFileLine\n");
|
||||
m_locType = LocFileLine;
|
||||
m_file = file;
|
||||
m_line = line;
|
||||
}
|
||||
|
||||
void InstPointInfo::setLocFuncEntry(const std::string& func) {
|
||||
TRACE(2, "InstPointInfo::setLocFuncEntry\n");
|
||||
m_locType = LocFuncEntry;
|
||||
m_func = func;
|
||||
}
|
||||
|
||||
void InstPointInfo::sendImpl(DebuggerThriftBuffer &thrift) {
|
||||
TRACE(2, "InstPointInfo::sendImpl\n");
|
||||
thrift.write(m_locType);
|
||||
thrift.write(m_valid);
|
||||
thrift.write(m_file);
|
||||
thrift.write(m_line);
|
||||
thrift.write(m_func);
|
||||
thrift.write(m_desc);
|
||||
thrift.write(m_code);
|
||||
}
|
||||
|
||||
void InstPointInfo::recvImpl(DebuggerThriftBuffer &thrift) {
|
||||
TRACE(2, "InstPointInfo::recvImpl\n");
|
||||
thrift.read(m_locType);
|
||||
thrift.read(m_valid);
|
||||
thrift.read(m_file);
|
||||
thrift.read(m_line);
|
||||
thrift.read(m_func);
|
||||
thrift.read(m_desc);
|
||||
thrift.read(m_code);
|
||||
}
|
||||
|
||||
void InstPointInfo::SendImpl(const InstPointInfoPtrVec& ips,
|
||||
DebuggerThriftBuffer &thrift) {
|
||||
TRACE(2, "InstPointInfo::SendImpl\n");
|
||||
int16_t size = ips.size();
|
||||
thrift.write(size);
|
||||
for (int i = 0; i < size; i++) {
|
||||
ips[i]->sendImpl(thrift);
|
||||
}
|
||||
}
|
||||
|
||||
void InstPointInfo::RecvImpl(InstPointInfoPtrVec& ips,
|
||||
DebuggerThriftBuffer &thrift) {
|
||||
TRACE(2, "InstPointInfo::RecvImpl\n");
|
||||
int16_t size;
|
||||
thrift.read(size);
|
||||
ips.resize(size);
|
||||
for (int i = 0; i < size; i++) {
|
||||
InstPointInfoPtr ipi(new InstPointInfo());
|
||||
ipi->recvImpl(thrift);
|
||||
ips[i] = ipi;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
}}
|
||||
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| 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_INST_POINT_H_
|
||||
#define incl_HPHP_EVAL_DEBUGGER_INST_POINT_H_
|
||||
|
||||
#include "hphp/runtime/base/complex_types.h"
|
||||
#include "hphp/runtime/debugger/debugger_thrift_buffer.h"
|
||||
|
||||
namespace HPHP { namespace Eval {
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DECLARE_BOOST_TYPES(InstPointInfo);
|
||||
class InstPointInfo {
|
||||
public:
|
||||
InstPointInfo() : m_locType(LocTypeCount), m_valid(false), m_line(0) {}
|
||||
|
||||
const uchar* lookupPC();
|
||||
|
||||
// Set loc based on file and line, called on client side
|
||||
void setLocHere();
|
||||
void setLocFileLine(const std::string& file, int line);
|
||||
void setLocFuncEntry(const std::string& func);
|
||||
|
||||
void sendImpl(DebuggerThriftBuffer &thrift);
|
||||
void recvImpl(DebuggerThriftBuffer &thrift);
|
||||
|
||||
static void SendImpl(const InstPointInfoPtrVec& ips,
|
||||
DebuggerThriftBuffer &thrift);
|
||||
static void RecvImpl(InstPointInfoPtrVec& ips,
|
||||
DebuggerThriftBuffer &thrift);
|
||||
|
||||
public:
|
||||
enum LocationType {
|
||||
LocHere,
|
||||
LocFileLine,
|
||||
LocFuncEntry,
|
||||
LocTypeCount
|
||||
};
|
||||
int m_locType;
|
||||
bool m_valid;
|
||||
std::string m_file;
|
||||
int32_t m_line;
|
||||
std::string m_func;
|
||||
// TODO: add more info
|
||||
|
||||
std::string m_desc;
|
||||
std::string m_code;
|
||||
};
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
}}
|
||||
|
||||
#endif // incl_HPHP_EVAL_DEBUGGER_INST_POINT_H_
|
||||
@@ -1,272 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| 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/vm/instrumentation.h"
|
||||
#include "hphp/runtime/vm/unit.h"
|
||||
#include "hphp/runtime/vm/runtime.h"
|
||||
#include "hphp/runtime/base/execution_context.h"
|
||||
|
||||
namespace HPHP {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Injection::execute() const {
|
||||
if (m_builtin) {
|
||||
assert(m_callback);
|
||||
// Execute function in runtime
|
||||
m_callback(m_arg);
|
||||
return;
|
||||
}
|
||||
// Execute php code piece
|
||||
TypedValue retval;
|
||||
VarEnv *varEnv = nullptr;
|
||||
ActRec *cfpSave = nullptr;
|
||||
ObjectData *this_ = nullptr;
|
||||
Class *cls = nullptr;
|
||||
ActRec *fp = g_vmContext->getFP();
|
||||
if (fp) {
|
||||
if (!fp->hasVarEnv()) {
|
||||
fp->m_varEnv = VarEnv::createLazyAttach(fp);
|
||||
}
|
||||
varEnv = fp->m_varEnv;
|
||||
cfpSave = varEnv->getCfp();
|
||||
if (fp->hasThis()) {
|
||||
this_ = fp->getThis();
|
||||
} else if (fp->hasClass()) {
|
||||
cls = fp->getClass();
|
||||
}
|
||||
}
|
||||
// Note: For now we don't merge analysis code's class and function.
|
||||
// Later we might decide to do so
|
||||
g_vmContext->invokeFunc(&retval, m_unit->getMain(curClass()),
|
||||
null_array, this_, cls, varEnv);
|
||||
if (varEnv) {
|
||||
varEnv->setCfp(cfpSave);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static InjectionCache* s_injectionCache = nullptr;
|
||||
|
||||
class InjectionCacheHolder {
|
||||
public:
|
||||
InjectionCacheHolder() {
|
||||
s_injectionCache = new InjectionCache();
|
||||
}
|
||||
~InjectionCacheHolder() {
|
||||
delete s_injectionCache;
|
||||
}
|
||||
};
|
||||
|
||||
static InjectionCacheHolder s_injectionCacheHolder;
|
||||
|
||||
const Injection* InjectionCache::GetInjection(const StringData* code,
|
||||
const StringData* desc) {
|
||||
return s_injectionCache->getInjectionImpl(code, desc);
|
||||
}
|
||||
|
||||
const Injection* InjectionCache::GetInjection(const std::string& code,
|
||||
const std::string& desc) {
|
||||
return s_injectionCache->getInjectionImpl(code, desc);
|
||||
}
|
||||
|
||||
const Injection* InjectionCache::GetInjection(Injection::Callback callback,
|
||||
void *arg,
|
||||
const StringData* desc) {
|
||||
return s_injectionCache->getInjectionImpl(callback, arg, desc);
|
||||
}
|
||||
|
||||
const StringData* InjectionCache::GetStringData(const StringData* sd) {
|
||||
return s_injectionCache->getStringData(sd);
|
||||
}
|
||||
|
||||
void InjectionCache::ClearCache() {
|
||||
s_injectionCache->clearCacheImpl();
|
||||
}
|
||||
|
||||
const Injection* InjectionCache::getInjectionImpl(const StringData* code,
|
||||
const StringData* desc) {
|
||||
Unit* unit = getUnit(getStringData(code));
|
||||
if (unit == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
Injection injection(unit, getStringData(desc));
|
||||
const Injection* inj = getInjection(&injection);
|
||||
return inj;
|
||||
}
|
||||
|
||||
const Injection* InjectionCache::getInjectionImpl(const std::string& code,
|
||||
const std::string& desc) {
|
||||
StackStringData sdCode(code.c_str(), code.size(), AttachLiteral);
|
||||
StackStringData sdDesc(desc.c_str(), desc.size(), AttachLiteral);
|
||||
return getInjectionImpl(&sdCode, &sdDesc);
|
||||
}
|
||||
|
||||
const Injection* InjectionCache::getInjectionImpl(Injection::Callback callback,
|
||||
void *arg,
|
||||
const StringData* desc) {
|
||||
Injection injection(callback, arg, desc);
|
||||
const Injection* inj = getInjection(&injection);
|
||||
return inj;
|
||||
}
|
||||
|
||||
void InjectionCache::clearCacheImpl() {
|
||||
WriteLock lock(m_lock);
|
||||
for (InjectionMap::iterator iter = m_injectionCache.begin();
|
||||
iter != m_injectionCache.end(); ++iter) {
|
||||
delete iter->first;
|
||||
}
|
||||
m_injectionCache.clear();
|
||||
|
||||
for (UnitMap::iterator iter = m_unitCache.begin();
|
||||
iter != m_unitCache.end(); ++iter) {
|
||||
delete iter->second;
|
||||
}
|
||||
m_unitCache.clear();
|
||||
|
||||
for (StringDataMap::iterator iter = m_sdCache.begin();
|
||||
iter != m_sdCache.end(); ++iter) {
|
||||
delete iter->first;
|
||||
}
|
||||
m_sdCache.clear();
|
||||
}
|
||||
|
||||
const StringData* InjectionCache::getStringData(const StringData* sd) {
|
||||
ReadLock lock(m_lock);
|
||||
StringDataMap::const_accessor accFind;
|
||||
if (m_sdCache.find(accFind, sd)) {
|
||||
return accFind->first;
|
||||
}
|
||||
accFind.release(); // Release read lock
|
||||
// Gap of lock
|
||||
StringData* sdata = new StringData(sd->data(), sd->size(), CopyMalloc);
|
||||
StringDataMap::accessor accInsert;
|
||||
if (!m_sdCache.insert(accInsert, sdata)) {
|
||||
// Same string inserted in gap of the lock
|
||||
delete sdata;
|
||||
}
|
||||
return accInsert->first;
|
||||
}
|
||||
|
||||
Unit* InjectionCache::getUnit(const StringData* code) {
|
||||
ReadLock lock(m_lock);
|
||||
// Note: caller needs to make sure the parameter code is not temporary
|
||||
UnitMap::accessor acc;
|
||||
if (m_unitCache.insert(acc, code)) {
|
||||
Unit* unit = compile_string(code->data(), code->size());
|
||||
// Here we save it even if unit == NULL, that at least saves us from
|
||||
// compiling same illegal string
|
||||
acc->second = unit;
|
||||
}
|
||||
return acc->second;
|
||||
}
|
||||
|
||||
const Injection* InjectionCache::getInjection(const Injection* inj) {
|
||||
ReadLock lock(m_lock);
|
||||
InjectionMap::const_accessor accFind;
|
||||
if (m_injectionCache.find(accFind, inj)) {
|
||||
return accFind->first;
|
||||
}
|
||||
accFind.release();
|
||||
Injection *injection = new Injection(*inj);
|
||||
InjectionMap::accessor accInsert;
|
||||
if (!m_injectionCache.insert(accInsert, injection)) {
|
||||
delete injection;
|
||||
}
|
||||
return accInsert->first;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
InjectionTables::InjectionTables()
|
||||
: m_int64Tables(InstHookTypeInt64Count), m_sdTables(InstHookTypeSDCount) {
|
||||
for (int i = 0; i < InstHookTypeInt64Count; i++) {
|
||||
m_int64Tables[i] = nullptr;
|
||||
}
|
||||
for (int i = 0; i < InstHookTypeSDCount; i++) {
|
||||
m_sdTables[i] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
InjectionTables::~InjectionTables() {
|
||||
clear();
|
||||
}
|
||||
|
||||
void InjectionTables::clear() {
|
||||
for (int i = 0; i < InstHookTypeInt64Count; i++) {
|
||||
setInt64Table(i, nullptr);
|
||||
}
|
||||
for (int i = 0; i < InstHookTypeSDCount; i++) {
|
||||
setSDTable(i, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
InjectionTables* InjectionTables::clone() {
|
||||
InjectionTables* newTables = new InjectionTables();
|
||||
for (int i = 0; i < InstHookTypeInt64Count; i++) {
|
||||
InjectionTableInt64* table = m_int64Tables[i];
|
||||
if (!table) {
|
||||
newTables->m_int64Tables[i] = nullptr;
|
||||
continue;
|
||||
}
|
||||
InjectionTableInt64* newTable = new InjectionTableInt64();
|
||||
newTable->insert(table->begin(), table->end());
|
||||
newTables->m_int64Tables[i] = newTable;
|
||||
}
|
||||
for (int i = 0; i < InstHookTypeSDCount; i++) {
|
||||
InjectionTableSD* table = m_sdTables[i];
|
||||
if (!table) {
|
||||
newTables->m_sdTables[i] = nullptr;
|
||||
continue;
|
||||
}
|
||||
InjectionTableSD* newTable = new InjectionTableSD();
|
||||
newTable->insert(table->begin(), table->end());
|
||||
newTables->m_sdTables[i] = newTable;
|
||||
}
|
||||
return newTables;
|
||||
}
|
||||
|
||||
void InjectionTables::setInt64Table(int hookType, InjectionTableInt64* table) {
|
||||
if (m_int64Tables[hookType]) {
|
||||
delete m_int64Tables[hookType];
|
||||
}
|
||||
m_int64Tables[hookType] = table;
|
||||
}
|
||||
|
||||
void InjectionTables::setSDTable(int hookType, InjectionTableSD* table) {
|
||||
if (m_sdTables[hookType]) {
|
||||
delete m_sdTables[hookType];
|
||||
}
|
||||
m_sdTables[hookType] = table;
|
||||
}
|
||||
|
||||
int InjectionTables::countInjections() {
|
||||
int total = 0;
|
||||
for (int i = 0; i < InstHookTypeInt64Count; i++) {
|
||||
total += m_int64Tables[i]->size();
|
||||
}
|
||||
for (int i = 0; i < InstHookTypeSDCount; i++) {
|
||||
total += m_sdTables[i]->size();
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
} // HPHP::VM
|
||||
@@ -1,154 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| 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_INSTRUMENTATION_H_
|
||||
#define incl_HPHP_INSTRUMENTATION_H_
|
||||
|
||||
#include "hphp/runtime/vm/core_types.h"
|
||||
#include "hphp/runtime/vm/unit.h"
|
||||
#include "tbb/concurrent_hash_map.h"
|
||||
#include "hphp/util/lock.h"
|
||||
|
||||
namespace HPHP {
|
||||
|
||||
// Define a set of hooks to be used
|
||||
enum InstHookTypeInt64 {
|
||||
InstHookTypeBCPC, // bytecode pc
|
||||
InstHookTypeInt64Count
|
||||
};
|
||||
|
||||
enum InstHookTypeSD {
|
||||
InstHookTypeCustomEvt, // custom event by name
|
||||
InstHookTypeFuncEntry, // function entry
|
||||
InstHookTypeSDCount
|
||||
};
|
||||
|
||||
class Injection {
|
||||
public:
|
||||
Injection(Unit* unit, const StringData* desc)
|
||||
: m_builtin(false), m_unit(unit), m_arg(nullptr), m_desc(desc) { }
|
||||
typedef void (*Callback)(void*);
|
||||
Injection(Callback callback, void* arg, const StringData* desc)
|
||||
: m_builtin(true), m_callback(callback), m_arg(arg), m_desc(desc) { }
|
||||
Injection(const Injection& inj)
|
||||
: m_builtin(inj.m_builtin), m_unit(inj.m_unit), m_arg(inj.m_arg),
|
||||
m_desc(inj.m_desc) {}
|
||||
|
||||
bool m_builtin;
|
||||
union {
|
||||
Unit* m_unit;
|
||||
Callback m_callback;
|
||||
};
|
||||
void *m_arg;
|
||||
const StringData* m_desc;
|
||||
|
||||
void execute() const;
|
||||
};
|
||||
|
||||
struct InjectionHashCompare {
|
||||
bool equal(const Injection *i1, const Injection *i2) const {
|
||||
assert(i1 && i2);
|
||||
return memcmp(i1, i2, sizeof(Injection)) == 0;
|
||||
}
|
||||
size_t hash(const Injection *i) const {
|
||||
assert(i);
|
||||
return i->m_desc->hash() ^ hash_int64((int64_t)i->m_unit);
|
||||
}
|
||||
};
|
||||
|
||||
class InjectionCacheHolder;
|
||||
|
||||
class InjectionCache {
|
||||
public:
|
||||
static const Injection* GetInjection(const StringData* code,
|
||||
const StringData* desc);
|
||||
static const Injection* GetInjection(const std::string& code,
|
||||
const std::string& desc);
|
||||
static const Injection* GetInjection(Injection::Callback callback, void *arg,
|
||||
const StringData* desc);
|
||||
static const StringData* GetStringData(const StringData* sd);
|
||||
// ClearCache should be called with caution since it destroys code units.
|
||||
static void ClearCache();
|
||||
|
||||
private:
|
||||
InjectionCache() {}
|
||||
~InjectionCache() { clearCacheImpl(); }
|
||||
|
||||
typedef tbb::concurrent_hash_map<const StringData*, void*,
|
||||
StringDataHashCompare> StringDataMap;
|
||||
const StringData* getStringData(const StringData* sd);
|
||||
StringDataMap m_sdCache;
|
||||
|
||||
typedef tbb::concurrent_hash_map<const StringData*, Unit*,
|
||||
StringDataHashCompare> UnitMap;
|
||||
Unit* getUnit(const StringData* code);
|
||||
UnitMap m_unitCache;
|
||||
|
||||
typedef tbb::concurrent_hash_map<const Injection*, void*,
|
||||
InjectionHashCompare> InjectionMap;
|
||||
const Injection* getInjection(const Injection* inj);
|
||||
InjectionMap m_injectionCache;
|
||||
|
||||
ReadWriteMutex m_lock;
|
||||
|
||||
void clearCacheImpl();
|
||||
const Injection* getInjectionImpl(const StringData* code,
|
||||
const StringData* desc);
|
||||
const Injection* getInjectionImpl(const std::string& code,
|
||||
const std::string& desc);
|
||||
const Injection* getInjectionImpl(Injection::Callback callback, void *arg,
|
||||
const StringData* desc);
|
||||
friend class InjectionCacheHolder;
|
||||
};
|
||||
|
||||
typedef hphp_hash_map<int64_t, const Injection*, int64_hash> InjectionTableInt64;
|
||||
typedef hphp_hash_map<const StringData*, const Injection*, string_data_hash,
|
||||
string_data_same> InjectionTableSD;
|
||||
|
||||
class InjectionTables {
|
||||
public:
|
||||
InjectionTables();
|
||||
~InjectionTables();
|
||||
|
||||
void clear();
|
||||
InjectionTables* clone();
|
||||
|
||||
InjectionTableInt64* getInt64Table(int hookType) {
|
||||
assert(hookType < InstHookTypeInt64Count);
|
||||
assert(hookType < (int)m_int64Tables.size());
|
||||
return m_int64Tables[hookType];
|
||||
}
|
||||
InjectionTableSD* getSDTable(int hookType) {
|
||||
assert(hookType < InstHookTypeSDCount);
|
||||
assert(hookType < (int)m_sdTables.size());
|
||||
return m_sdTables[hookType];
|
||||
}
|
||||
|
||||
void setInt64Table(int hookType, InjectionTableInt64* table);
|
||||
void setSDTable(int hookType, InjectionTableSD* table);
|
||||
|
||||
int countInjections();
|
||||
|
||||
private:
|
||||
std::vector<InjectionTableInt64*> m_int64Tables;
|
||||
std::vector<InjectionTableSD*> m_sdTables;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
} // HPHP::VM
|
||||
|
||||
#endif /* incl_HPHP_INSTRUMENTATION_H_ */
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| 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_INSTRUMENTATION_HOOK_H_
|
||||
#define incl_HPHP_INSTRUMENTATION_HOOK_H_
|
||||
|
||||
#include "hphp/runtime/vm/instrumentation.h"
|
||||
#include "hphp/runtime/base/execution_context.h"
|
||||
|
||||
namespace HPHP {
|
||||
|
||||
inline void instHookInt64Impl(InjectionTableInt64* table, int64_t val) {
|
||||
if (!table) return;
|
||||
InjectionTableInt64::const_iterator it = table->find(val);
|
||||
if (LIKELY(it == table->end())) return;
|
||||
it->second->execute();
|
||||
}
|
||||
|
||||
inline void instHookInt64(int type, int64_t val) {
|
||||
assert(type < InstHookTypeInt64Count);
|
||||
InjectionTableInt64* injTable = g_vmContext->m_injTables ?
|
||||
g_vmContext->m_injTables->getInt64Table(type) : nullptr;
|
||||
instHookInt64Impl(injTable, val);
|
||||
}
|
||||
|
||||
inline void instHookSD(int type, const StringData* sd) {
|
||||
assert(type < InstHookTypeSDCount);
|
||||
InjectionTableSD* injTable = g_vmContext->m_injTables ?
|
||||
g_vmContext->m_injTables->getSDTable(type) : nullptr;
|
||||
if (LIKELY(!injTable)) return;
|
||||
InjectionTableSD::const_iterator it = injTable->find(sd);
|
||||
if (LIKELY(it == injTable->end())) return;
|
||||
it->second->execute();
|
||||
}
|
||||
|
||||
inline void instHookStr(int type, const char* str) {
|
||||
StackStringData sd(str, AttachLiteral);
|
||||
instHookSD(type, &sd);
|
||||
}
|
||||
|
||||
#define INST_HOOK_PC(table, pc) instHookInt64Impl(table, (int64_t)pc)
|
||||
|
||||
#define INST_HOOK_EVT_STR(str) instHookStr(InstHookTypeCustomEvt, str)
|
||||
#define INST_HOOK_EVT_SD(sd) instHookSD(InstHookTypeCustomEvt, sd)
|
||||
|
||||
#define INST_HOOK_FENTRY(sd) instHookSD(InstHookTypeFuncEntry, sd)
|
||||
|
||||
} // HPHP::VM
|
||||
|
||||
#endif /* incl_HPHP_INSTRUMENTATION_HOOK_H_ */
|
||||
Referência em uma Nova Issue
Bloquear um usuário