void TranslatorX64::fCallArrayHelper(const Offset pcOff, const Offset pcNext) {
    DECLARE_FRAME_POINTER(framePtr);
    ActRec* fp = (ActRec*)framePtr->m_savedRbp;

    VMExecutionContext *ec = g_vmContext;
    ec->m_fp = fp;
    ec->m_stack.top() = sp;
    ec->m_pc = fp->unit()->at(pcOff);
    PC pc = fp->unit()->at(pcNext);

    tl_regState = VMRegState::CLEAN;
    bool runFunc = ec->doFCallArray(pc);
    sp = ec->m_stack.top();
    tl_regState = VMRegState::DIRTY;
    if (!runFunc) return;

    ec->m_fp->m_savedRip = framePtr->m_savedRip;
    // smash our return and frame pointer chain
    framePtr->m_savedRip = (uint64_t)ec->m_fp->m_func->getFuncBody();
    framePtr->m_savedRbp = (uint64_t)ec->m_fp;
}
Exemple #2
0
void XDebugProfiler::enableTracing(const String& filename, int64_t opts) {
  assert(!m_tracingEnabled);

  // Attempt to open the passed filename. php5 xdebug doesn't enable tracing
  // if we cannot open the file, so we need to open it now as opposed to when we
  // actually do the writing in order to ensure we handle this case. We keep the
  // file handle open in order to ensure we can still write on tracing stop
  FILE* file;
  if (opts & k_XDEBUG_TRACE_APPEND) {
    file = fopen(filename.data(), "a");
  } else {
    file = fopen(filename.data(), "w");
  }

  // If file is null, opening the passed filename failed. php5 xdebug doesn't
  // do anything in this case, but we should probably notify the user
  if (file == nullptr) {
    raise_warning("xdebug profiler failed to open tracing file %s for writing.",
                  filename.data());
    return;
  }

  m_tracingEnabled = true;
  m_tracingStartIdx = m_nextFrameIdx;
  m_tracingFilename = filename;
  m_tracingFile = file;
  m_tracingOpts = opts;

  // If we're not at the top level, need to grab the call sites for each frame
  // on the stack.
  VMRegAnchor _;
  Offset offset;
  ActRec* fp = vmfp();
  while ((fp = g_context->getPrevVMState(fp, &offset)) != nullptr) {
    FrameData frame;
    frame.func = fp->func();
    frame.line = fp->unit()->getLineNumber(offset);
    m_tracingStartFrameData.push_back(frame);
  }
}