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:
Mike Magruder
2013-06-11 11:07:26 -07:00
commit de sgolemon
commit 5d25a36a61
14 arquivos alterados com 2 adições e 1062 exclusões
+1 -2
Ver Arquivo
@@ -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;
}
-2
Ver Arquivo
@@ -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;
-1
Ver Arquivo
@@ -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
-278
Ver Arquivo
@@ -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());
}
}
}
///////////////////////////////////////////////////////////////////////////////
}}
-64
Ver Arquivo
@@ -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_
-1
Ver Arquivo
@@ -379,7 +379,6 @@ void Debugger::registerSandbox(const DSandboxInfo &sandbox) {
DebuggerProxyPtr proxy = findProxy(sid);
if (proxy) {
ti->m_reqInjectionData.setDebugger(true);
proxy->writeInjTablesToThread();
}
}
-4
Ver Arquivo
@@ -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
+1 -31
Ver Arquivo
@@ -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;
-10
Ver Arquivo
@@ -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;
};
///////////////////////////////////////////////////////////////////////////////
-112
Ver Arquivo
@@ -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;
}
}
///////////////////////////////////////////////////////////////////////////////
}}
-68
Ver Arquivo
@@ -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_
-272
Ver Arquivo
@@ -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
-154
Ver Arquivo
@@ -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_ */
-63
Ver Arquivo
@@ -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_ */