Ejemplo n.º 1
0
void CmdConfig::onClient(DebuggerClient &client) {
  if (DebuggerCommand::displayedHelp(client)) return;
  if (client.argCount() == 0) {
    listVars(client);
    return;
  }
  std::string var = client.argValue(1);
  if (var == "help" || client.argCount() < 2) {
    help(client);
    return;
  }

  std::string value = client.argValue(2);
  if (var == "BypassAccessCheck" || var == "bac") {
    if (value == "on") {
      client.print("BypassAccessCheck(bac) set to on.\n"
                    "All code executed from debugger is bypassing "
                    "access check!");
      client.setDebuggerClientBypassCheck(true);
    } else if (value == "off") {
      client.print("BypassAccessCheck(bac) set to off");
      client.setDebuggerClientBypassCheck(false);
    } else {
      help(client);
    }
    return;
  }
  if (var == "LogFile" || var == "lf") {
    // Close the current log file handler
    FILE *f = client.getLogFileHandler();
    if (f != nullptr) {
      fclose(f);
      client.setLogFileHandler(nullptr);
    }

    if (value == "off") {
      value = "";
    } else {
      // Try open the log file and error if it's not working
      f = fopen(value.c_str(), "a");
      if (f == nullptr) {
        client.error("Cannot open log file '%s'",
          value.c_str());
        value = "";
        client.setLogFileHandler(nullptr);
      } else {
        client.setLogFileHandler(f);
      }
    }
    client.print("LogFile(lf) is set to %s", value == "" ? "off"
                                                          : value.c_str());
    client.setLogFile(value);
    return;
  }
  if (var == "PrintLevel" || var == "pl") {
    int pl = strtol(value.c_str(), nullptr, 10);
    if (pl > 0 && pl < DebuggerClient::MinPrintLevel) {
      client.error("%d is invalid for PrintLevel(pl)", pl);
      return;
    }
    client.setDebuggerClientPrintLevel(pl);
    client.print("PrintLevel(pl) is set to %d", pl);
    return;
  }
  if (var == "ShortPrintCharCount" || var == "cc") {
    int cc = strtol(value.c_str(), nullptr, 10);
    if (cc < -1) {
      client.error("%d is invalid for ShortPrintCharCount(cc)", cc);
    } else {
      client.setDebuggerClientShortPrintCharCount(cc);
      client.print("ShortPrintCharCount(cc) is set to %d", cc);
    }
    return;
  }
  if (var == "SmallStep" || var == "ss") {
    if (value == "on") {
      client.print("SmallStep(ss) set to on.\n");
      client.setDebuggerClientSmallStep(true);
    } else if (value == "off") {
      client.print("SmallStep(ss) set to off");
      client.setDebuggerClientSmallStep(false);
    } else {
      help(client);
    }
    return;
  }
  if (var == "StackArgs" || var == "sa") {
    if (value == "on") {
      client.print("StackArgs(sa) set to on.\n");
      client.setDebuggerClientStackArgs(true);
    } else if (value == "off") {
      client.print("StackArgs(sa) set to off");
      client.setDebuggerClientStackArgs(false);
    } else {
      help(client);
    }
    return;
  }
  if (var == "MaxCodeLines" || var == "mcl") {
    // MaxCodeLines: a useful configuration variable for emacs/hphpd-integration
    // to prevent or limit code spew after each breakpoint is hit (since emacs
    // hphpd-mode already loads the source file into a buffer and displays a
    // pointer to the current line).
    int mcl = strtol(value.c_str(), nullptr, 10);
    if (mcl < -1) {
      client.error("%d is invalid for MaxCodeLines(mcl)", mcl);
    } else {
      client.setDebuggerClientMaxCodeLines(mcl);
      client.print("MaxCodeLines(mcl) is set to %d", mcl);
    }
    return;
  }

  listVars(client);
}
Ejemplo n.º 2
0
void CmdInterrupt::onClient(DebuggerClient &client) {
  client.setCurrentLocation(m_threadId, m_bpi);
  if (!client.getDebuggerClientSmallStep()) {
    // Adjust line and char if it's not small stepping
    if (m_bpi->m_line1 == m_bpi->m_line2) {
      m_bpi->m_char1 = 1;
      m_bpi->m_char2 = 100;
    }
  }
  client.setMatchedBreakPoints(m_matched);

  switch (m_interrupt) {
    case SessionStarted:
      if (!m_program.empty()) {
        client.info("Program %s loaded. Type '[r]un' or '[c]ontinue' to go.",
                     m_program.c_str());
        m_bpi->m_file = m_program;
      }
      break;
    case SessionEnded:
      if (!m_program.empty()) {
        client.info("Program %s exited normally.", m_program.c_str());
      }
      break;
    case RequestStarted:
      if (!m_program.empty()) {
        client.info("Web request %s started.", m_program.c_str());
      }
      break;
    case RequestEnded:
      if (!m_program.empty()) {
        client.info("Web request %s ended.", m_program.c_str());
      }
      break;
    case PSPEnded:
      if (!m_program.empty()) {
        client.info("Post-Send Processing for %s was ended.",
                     m_program.c_str());
      }
      break;
    case HardBreakPoint:
    case BreakPointReached:
    case ExceptionThrown: {
      bool found = false;
      bool toggled = false;
      auto *bps = client.getBreakPoints();
      for (unsigned int i = 0; i < m_matched.size(); i++) {
        BreakPointInfoPtr bpm = m_matched[i];
        BreakPointInfoPtr bp;
        int index = 0;
        for (; index < (int)bps->size(); index++) {
          if (bpm->same((*bps)[index])) {
            bp = (*bps)[index];
            break;
          }
        }
        if (bp) {
          found = true;
          if (bp->m_state == BreakPointInfo::Once) {
            bp->m_state = BreakPointInfo::Disabled;
            toggled = true;
          }
          if (m_interrupt == BreakPointReached ||
              m_interrupt == HardBreakPoint) {
            client.info("Breakpoint %d reached %s", bp->index(),
                         m_bpi->site().c_str());
            client.shortCode(m_bpi);
          } else {
            if (m_bpi->m_exceptionClass == BreakPointInfo::ErrorClassName) {
              client.info("Breakpoint %d reached: An error occurred %s",
                           bp->index(), m_bpi->site().c_str());
              client.shortCode(m_bpi);
              client.error("Error Message: %s",
                            m_bpi->m_exceptionObject.c_str());
            } else {
              client.info("Breakpoint %d reached: Throwing %s %s",
                           bp->index(),
                           m_bpi->m_exceptionClass.c_str(),
                           m_bpi->site().c_str());
              client.shortCode(m_bpi);
              if (client.getLogFileHandler()) {
                client.output(m_bpi->m_exceptionObject);
              }
            }
          }
          if (!bpm->m_output.empty()) {
            client.print(bpm->m_output);
          }
        }
      }
      if (toggled) {
        CmdBreak::SendClientBreakpointListToServer(client);
      }
      if (!found) {
        if (m_interrupt == HardBreakPoint) {
          // for HardBreakPoint, default the frame to the caller
          client.setFrame(1);
        }
        client.info("Break %s", m_bpi->site().c_str());
        client.shortCode(m_bpi);
      }
      break;
    }
  }

  if (!m_errorMsg.empty()) {
    client.error(m_errorMsg);
  }

  // watches
  switch (m_interrupt) {
    case SessionStarted:
    case RequestStarted:
      break;
    default: {
      DebuggerClient::WatchPtrVec &watches = client.getWatches();
      for (int i = 0; i < (int)watches.size(); i++) {
        if (i > 0) client.output("%s", "");
        client.info("Watch %d: %s =", i + 1, watches[i]->second.c_str());
        Variant v = CmdPrint().processWatch(client, watches[i]->first,
                                            watches[i]->second);
        client.output(CmdPrint::FormatResult(watches[i]->first, v));
      }
    }
  }
}