void Debugger::InterruptRequestStarted(const char *url) { TRACE(2, "Debugger::InterruptRequestStarted\n"); if (isDebuggerAttached()) { get().registerThread(); // Register this thread as being debugged InterruptWithUrl(RequestStarted, url); } }
void Debugger::InterruptRequestEnded(const char *url) { TRACE(2, "Debugger::InterruptRequestEnded: url=%s\n", url); if (isDebuggerAttached()) { InterruptWithUrl(RequestEnded, url); } const String& sandboxId = g_context->getSandboxId(); get().unregisterSandbox(sandboxId.get()); }
void Debugger::InterruptPSPEnded(const char *url) { if (!RuntimeOption::EnableHphpdDebugger) return; try { TRACE(2, "Debugger::InterruptPSPEnded\n"); if (isDebuggerAttached()) { InterruptWithUrl(PSPEnded, url); } } catch (const Eval::DebuggerException&) {} }
// The flag for this is in the VM's normal ThreadInfo, but we don't // have a way to get that given just a tid. Use our own map to find it // and answer the question. bool Debugger::isThreadDebugging(int64_t tid) { TRACE(2, "Debugger::isThreadDebugging tid=%" PRIx64 "\n", tid); ThreadInfoMap::const_accessor acc; if (m_threadInfos.find(acc, tid)) { ThreadInfo* ti = acc->second; auto isDebugging = isDebuggerAttached(ti); TRACE(2, "Is thread debugging? %d\n", isDebugging); return isDebugging; } TRACE(2, "Thread was never registered, assuming it is not debugging\n"); return false; }
void autoTypecheck(const Unit* unit) { if (RuntimeOption::RepoAuthoritative || !RuntimeOption::AutoTypecheck || tl_doneAutoTypecheck || !unit->isHHFile() || isDebuggerAttached()) { return; } tl_doneAutoTypecheck = true; vm_call_user_func("\\HH\\Client\\typecheck_and_error", Variant{staticEmptyArray()}); }
static void disableMbedInterface(void) { static const uint32_t debugDetachWaitTimeout = 5000; /* mbed interface exists on JTAG bus so if no debugger, then no potential for mbed interface. */ if (!isDebuggerAttached()) return; fetchAndSaveMbedUid(); __mriDisableMbed(); __try waitForDebuggerToDetach(debugDetachWaitTimeout); __catch __rethrow; setMbedDetectedFlag(); }
void checkHHConfig(const Unit* unit) { if (RuntimeOption::RepoAuthoritative || !RuntimeOption::LookForTypechecker || s_foundHHConfig || !unit->isHHFile() || isDebuggerAttached()) { return; } const std::string &s = unit->filepath()->toCppString(); boost::filesystem::path p(s); while (p != "/" && p != "") { p.remove_filename(); p /= ".hhconfig"; if (boost::filesystem::exists(p)) { break; } p.remove_filename(); } if (p == "/" || p == "") { raise_error( "%s appears to be a Hack file, but you do not appear to be running " "the Hack typechecker. See the documentation at %s for information on " "getting it running. You can also set " "`-d hhvm.hack.lang.look_for_typechecker=0` " "to disable this check (not recommended).", s.c_str(), "http://docs.hhvm.com/hack/typechecker/setup" ); } else { s_foundHHConfig = true; } }
void Unit::merge() { if (UNLIKELY(!m_initialMergeDone)) { SimpleLock lock(m_preConstsLock); if (LIKELY(!m_initialMergeDone)) { if (!RuntimeOption::RepoAuthoritative) { Transl::mergePreConsts(m_preConsts); } for (MutableFuncRange fr(nonMainFuncs()); !fr.empty();) { loadFunc(fr.popFront()); } m_initialMergeDone = true; } } Func** it = funcHoistableBegin(); Func** fend = funcEnd(); if (it != fend) { bool debugger = isDebuggerAttached(); do { Func* func = *it; ASSERT(func->top()); setCachedFunc(func, debugger); } while (++it != fend); } bool redoHoistable = false; int ix = m_firstHoistablePreClass; int end = m_firstMergablePreClass; // iterate over all the potentially hoistable classes // with no fatals on failure while (ix < end) { PreClass* pre = (PreClass*)m_mergeables[ix++]; if (!defClass(pre, false)) redoHoistable = true; } if (UNLIKELY(redoHoistable)) { // if this unit isnt mergeOnly, we're done if (!isMergeOnly()) return; // as a special case, if all the classes are potentially // hoistable, we dont list them twice, but instead // iterate over them again // At first glance, it may seem like we could leave // the maybe-hoistable classes out of the second list // and then always reset ix to 0; but that gets this // case wrong if there's an autoloader for C, and C // extends B: // // class A {} // class B implements I {} // class D extends C {} // // because now A and D go on the maybe-hoistable list // B goes on the never hoistable list, and we // fatal trying to instantiate D before B if (end == (int)m_mergeables.size()) ix = m_firstHoistablePreClass; } end = m_mergeables.size(); // iterate over all but the guaranteed hoistable classes // fataling if we fail. while (ix < end) { PreClass* pre = (PreClass*)m_mergeables[ix++]; defClass(pre, true); } }
void Func::setCached() { setCachedFunc(this, isDebuggerAttached()); }