Пример #1
0
std::pair<bool,Variant>
DebuggerProxy::ExecutePHP(const std::string &php, String &output,
                          int frame, int flags) {
  TRACE(2, "DebuggerProxy::ExecutePHP\n");
  // Wire up stdout and stderr to our own string buffer so we can pass
  // any output back to the client.
  StringBuffer sb;
  StringBuffer *save = g_context->swapOutputBuffer(nullptr);
  DebuggerStdoutHook stdout_hook(sb);
  DebuggerLoggerHook stderr_hook(sb);

  auto const previousEvalOutputHook = m_evalOutputHook;
  if (previousEvalOutputHook != nullptr) {
    g_context->removeStdoutHook(previousEvalOutputHook);
  }

  m_evalOutputHook = &stdout_hook;
  g_context->addStdoutHook(&stdout_hook);

  if (flags & ExecutePHPFlagsLog) {
    Logger::SetThreadHook(&stderr_hook);
  }
  SCOPE_EXIT {
    g_context->removeStdoutHook(&stdout_hook);
    g_context->swapOutputBuffer(save);
    if (flags & ExecutePHPFlagsLog) {
      Logger::SetThreadHook(nullptr);
    }

    if (previousEvalOutputHook != nullptr) {
      g_context->addStdoutHook(previousEvalOutputHook);
    }

    m_evalOutputHook = previousEvalOutputHook;
  };
  String code(php.c_str(), php.size(), CopyString);
  // We're about to start executing more PHP. This is typically done
  // in response to commands from the client, and the client expects
  // those commands to send more interrupts since, of course, the
  // user might want to debug the code we're about to run. If we're
  // already processing an interrupt, enable signal polling around
  // the execution of the new PHP to ensure that we can handle
  // signals while doing so.
  //
  // Note: we must switch the thread mode to Sticky so we block
  // other threads which may hit interrupts while we're running,
  // since nested processInterrupt() calls would normally release
  // other threads on the way out.
  assertx(m_thread == (int64_t)Process::GetThreadId());
  ThreadMode origThreadMode = m_threadMode;
  switchThreadMode(Sticky, m_thread);
  if (flags & ExecutePHPFlagsAtInterrupt) enableSignalPolling();
  SCOPE_EXIT {
    if (flags & ExecutePHPFlagsAtInterrupt) disableSignalPolling();
    switchThreadMode(origThreadMode, m_thread);
  };
  auto const ret = g_context->evalPHPDebugger(code.get(), frame);
  output = sb.detach();
  return {ret.failed, ret.result};
}
Пример #2
0
/**
 * Fake vfs
 */
ssize_t vfs_console_write(struct _reent *r, int fd, const char *src, size_t len) {
	if (stdout_hook)
		stdout_hook(src, len);
	size_t i;
	for (i = 0; i < len; ++i)
		putch(((const char*) src)[i]);
	return len;
}
Пример #3
0
ssize_t vfs_console_write(struct vfs_file_s *file, const void *src, size_t len)
{
	if (stdout_hook)
		stdout_hook(src, len);
	size_t i;
	for (i = 0; i < len; ++i)
		putch(((const char*)src)[i]);
        
	return len;
}
Пример #4
0
unsigned int debug_routine_stub(unsigned int code, CONTEXT *context)
{
    if(code != EXCEPT_CODE_DEBUG_PRINT)
        return 0;
    
    size_t i;
    size_t len = context->Gpr[4];
    char * src = (char*)context->Gpr[3];
    
    if (stdout_hook)
        stdout_hook(src, len);
    
    for (i = 0; i < len; ++i)
        putch(((const char*)src)[i]);
    
    // Skip over the trap
    context->Iar += 4;
    
    return 1;
}