bool Debugger::switchSandboxImpl(DebuggerProxyPtr proxy, const StringData* newSid, bool force) { TRACE(2, "Debugger::switchSandboxImpl\n"); // When attaching to the sandbox, ensure that hphpd is the active debugger. // If this fails, we'll end up returning failure to the CmdMachine on the // hphpd client that attempted the attach, and it will inform the user. auto instance = HphpdHook::GetInstance(); if (!DebuggerHook::setActiveDebuggerInstance(instance, true)) { return false; } // Take the new sandbox DebuggerProxyPtr otherProxy; { ProxyMap::accessor acc; if (m_proxyMap.insert(acc, newSid)) { acc->second = proxy; } else { // the sandbox indicated by newId is already attached by another proxy if (!force) { return false; } // Delay the destruction of the proxy originally attached to the sandbox // to avoid calling a DebuggerProxy destructor (which can sleep) while // holding m_mutex. otherProxy = acc->second; acc->second = proxy; } } if (proxy->getSandbox().valid()) { // Detach from the old sandbox const StringData* oldSid = makeStaticString(proxy->getSandboxId()); setDebuggerFlag(oldSid, false); m_proxyMap.erase(oldSid); } setDebuggerFlag(newSid, true); if (otherProxy) { otherProxy->stop(); } return true; }
bool Debugger::switchSandboxImpl(DebuggerProxyPtr proxy, const StringData* newSid, bool force) { TRACE(2, "Debugger::switchSandboxImpln"); // Take the new sandbox DebuggerProxyPtr otherProxy; { ProxyMap::accessor acc; if (m_proxyMap.insert(acc, newSid)) { acc->second = proxy; } else { // the sandbox indicated by newId is already attached by another proxy if (!force) { return false; } // Delay the destruction of the proxy originally attached to the sandbox // to avoid calling a DebuggerProxy destructor (which can sleep) while // holding m_mutex. otherProxy = acc->second; acc->second = proxy; } } if (proxy->getSandbox().valid()) { // Detach from the old sandbox const StringData* oldSid = StringData::GetStaticString(proxy->getSandboxId()); setDebuggerFlag(oldSid, false); m_proxyMap.erase(oldSid); } setDebuggerFlag(newSid, true); if (otherProxy) { otherProxy->forceQuit(); } return true; }
void Debugger::removeProxy(DebuggerProxyPtr proxy) { if (proxy->getSandbox().valid()) { const StringData* sid = StringData::GetStaticString(proxy->getSandboxId()); setDebuggerFlag(sid, false); m_proxyMap.erase(sid); } const StringData* dummySid = StringData::GetStaticString(proxy->getDummyInfo().id()); m_proxyMap.erase(dummySid); // Clear the debugger blacklist PC upon last detach if JIT is used if (RuntimeOption::EvalJit && countConnectedProxy() == 0) { VM::Transl::Translator::Get()->clearDbgBL(); } }
// NB: when this returns, the Debugger class no longer has any references to the // given proxy. It will likely be destroyed when the caller's reference goes out // of scope. void Debugger::removeProxy(DebuggerProxyPtr proxy) { TRACE(2, "Debugger::removeProxy\n"); if (proxy->getSandbox().valid()) { const StringData* sid = makeStaticString(proxy->getSandboxId()); setDebuggerFlag(sid, false); m_proxyMap.erase(sid); } const StringData* dummySid = makeStaticString(proxy->getDummyInfo().id()); m_proxyMap.erase(dummySid); // Clear the debugger blacklist PC upon last detach if JIT is used if (RuntimeOption::EvalJit && countConnectedProxy() == 0) { jit::mcg->tx().clearDbgBL(); } }