コード例 #1
0
ファイル: cmd_variable.cpp プロジェクト: Fininvest/hhvm
void CmdVariable::PrintVariable(DebuggerClient &client, const String& varName) {
  CmdVariable cmd(client.isStackTraceAsync()
                  ? KindOfVariableAsync : KindOfVariable);
  auto charCount = client.getDebuggerClientShortPrintCharCount();
  cmd.m_frame = client.getFrame();
  auto rcmd = client.xend<CmdVariable>(&cmd);
  if (rcmd->m_version == 2) {
    // Using the new protocol. rcmd contains a list of variables only.
    // Fetch value of varName only, so that we can recover nicely when its
    // value is too large to serialize.
    cmd.m_varName = varName;
    cmd.m_variables.reset();
    cmd.m_version = 2;
    rcmd = client.xend<CmdVariable>(&cmd);
    if (rcmd->m_variables.empty()) {
      // Perhaps the value is too large? See recvImpl.
      // Retry the command with version 1, in which case values are omitted.
      cmd.m_version = 1;
      rcmd = client.xend<CmdVariable>(&cmd);
      if (!rcmd->m_variables.empty()) {
        // It's there without values, and gone with values, so it is too large.
        client.output("...(omitted)");
        return;
      }
    }
  }
  if (!rcmd->m_variables.empty()) {
    for (ArrayIter iter(rcmd->m_variables); iter; ++iter) {
      String name = iter.first().toString();
      if (!name.equal(varName)) continue;
      String value = DebuggerClient::FormatVariable(iter.second(), -1);
      auto excess = value.length() - charCount;
      if (charCount <= 0 || excess <= 0) {
        client.output("%s", value.data());
      } else {
        client.output("%s", value.substr(0, charCount).data());
        if (client.ask("There are %d more characters. Continue? [y/N]", excess)
            == 'y') {
          client.output("%s", value.substr(charCount).data());
          client.tutorial("You can use 'set cc n' to increase the character"
              " limit. 'set cc -1' will remove the limit.");
        }
      }
    }
  }
}
コード例 #2
0
ファイル: cmd_variable.cpp プロジェクト: Barbayar/hiphop-php
void CmdVariable::PrintVariables(DebuggerClient &client, CArrRef variables,
                                 bool global, CStrRef text) {
  bool system = true;
  int i = 0;
  bool found = false;
  for (ArrayIter iter(variables); iter; ++iter) {
    String name = iter.first().toString();
    String value = DebuggerClient::FormatVariable(iter.second(), 200);
    if (!text.empty()) {
      String fullvalue = DebuggerClient::FormatVariable(iter.second(), -1);
      if (name.find(text, 0, false) >= 0 ||
          fullvalue.find(text, 0, false) >= 0) {
        client.print("%s = %s", name.data(), value.data());
        found = true;
      }
    } else {
      if (global && system) {
        client.print("$%s = %s", name.data(), value.data());
      } else {
        client.output("$%s = %s", name.data(), value.data());
      }

      // we knew this is the last system global
      if (global && name == "http_response_header") {
        client.output("%s", "");
        system = false;
      }

      ++i;
      if (i % DebuggerClient::ScrollBlockSize == 0 &&
          client.ask("There are %zd more variables. Continue? [Y/n]",
                      variables.size() - i) == 'n') {
        break;
      }
    }
  }

  if (!text.empty() && !found) {
    client.info("(unable to find specified text in any variables)");
  }
}
コード例 #3
0
void CmdVariable::PrintVariables(DebuggerClient &client, CArrRef variables,
                                 int frame, const String& text, int version) {
  bool global = frame == -1; // I.e. we were called from CmdGlobal, or the
  //client's current frame is the global frame, according to OnServer
  bool system = true;
  int i = 0;
  bool found = false;
  for (ArrayIter iter(variables); iter; ++iter) {
    String name = iter.first().toString();
    String value;
    if (version == 2) {
      // Using the new protocol, so variables contain only names.
      // Fetch the value separately.
      CmdVariable cmd;
      cmd.m_frame = frame;
      cmd.m_variables = null_array;
      cmd.m_varName = name;
      cmd.m_filter = text;
      cmd.m_version = 2;
      auto rcmd = client.xend<CmdVariable>(&cmd);
      if (!rcmd->m_variables.empty()) {
        value = DebuggerClient::FormatVariable(rcmd->m_variables[name], 200);
        found = true;
      } else if (text.empty()) {
        // Not missing because filtered out, assume the value is too large.
        value = s_omitted;
        found = true;
      } else {
        if (name.find(text, 0, false) >= 0) {
          // Server should have matched it.
          // Assume missing because value is too large.
          value = s_omitted;
          found = true;
        } else {
          // The variable was filtered out on the server, using text.
          // Or it was just too large. Either way we let skip over it.
          continue;
        }
      }
    } else {
      value = DebuggerClient::FormatVariable(iter.second(), 200);
    }
    if (version == 0 && !text.empty()) {
      if (name.find(text, 0, false) >= 0) {
        client.print("%s = %s", name.data(), value.data());
        found = true;
      } else {
        String fullvalue = DebuggerClient::FormatVariable(value, -1);
        if (fullvalue.find(text, 0, false) >= 0) {
          client.print("%s = %s", name.data(), value.data());
          found = true;
        }
      }
    } else {
      if (global && system) {
        client.print("$%s = %s", name.data(), value.data());
      } else {
        client.output("$%s = %s", name.data(), value.data());
      }

      // we know s_http_response_header is the last system global
      if (global && name == s_http_response_header) {
        client.output("%s", "");
        system = false;
      }

      ++i;
      if (i % DebuggerClient::ScrollBlockSize == 0 &&
          client.ask("There are %zd more variables. Continue? [Y/n]",
                      variables.size() - i) == 'n') {
        break;
      }
    }
  }

  if (!text.empty() && !found) {
    client.info("(unable to find specified text in any variables)");
  }
}
コード例 #4
0
ファイル: cmd_where.cpp プロジェクト: stone54321277/hhvm
void CmdWhere::onClient(DebuggerClient &client) {
  if (DebuggerCommand::displayedHelp(client)) return;
  if (client.argCount() > 2) {
    help(client);
    return;
  }
  int argBase = 1;
  if ((client.argCount() > 0) && client.arg(argBase, "async")) {
    // We use a different command type for an async stack trace, so we
    // can both send and receive different data and still keep the
    // existing Where command unchanged. This ensures that old clients
    // can still get a stack trace from a newer server, and vice
    // versa.
    m_type = KindOfWhereAsync;
    argBase++;
    client.info("Fetching async stacktrace...");
  }

  Array st = fetchStackTrace(client);
  if (st.empty()) {
    if (m_type != KindOfWhereAsync) {
      client.info("(no stacktrace to display or in global scope)");
      client.info("If you hit the serialization limit, try "
                  "\"set sa off\" to get the stack without args");
    } else {
      client.info("(no async stacktrace to display)");
    }
    return;
  }

  // so list command can default to current frame
  client.moveToFrame(client.getFrame(), false);

  if (client.argCount() < argBase) {
    int i = 0;
    for (ArrayIter iter(st); iter; ++iter) {
      client.printFrame(i, iter.second().toArray());
      ++i;
      if (i % DebuggerClient::ScrollBlockSize == 0 &&
          client.ask("There are %zd more frames. Continue? [Y/n]",
                      st.size() - i) == 'n') {
        break;
      }
    }
  } else {
    std::string snum = client.argValue(argBase);
    int num = atoi(snum.c_str());
    if (snum[0] == '-') {
      snum = snum.substr(1);
    }
    if (!DebuggerClient::IsValidNumber(snum)) {
      client.error("The argument, if specified, has to be numeric.");
      return;
    }
    if (num > 0) {
      for (int i = 0; i < num && i < st.size(); i++) {
        client.printFrame(i, st[i].toArray());
      }
    } else if (num < 0) {
      for (int i = st.size() + num; i < st.size(); i++) {
        client.printFrame(i, st[i].toArray());
      }
    } else {
      client.error("0 was specified for the number of frames");
      client.tutorial(
        "The optional argument is the number of frames to print out. "
        "Use a positive number to print out innermost frames. Use a negative "
        "number to print out outermost frames."
      );
    }
  }
}
コード例 #5
0
ファイル: cmd_variable.cpp プロジェクト: Globalcherry/hhvm
void CmdVariable::PrintVariables(DebuggerClient &client, const Array& variables,
                                 int frame, const String& text, int version) {
  bool global = frame == -1; // I.e. we were called from CmdGlobal, or the
  //client's current frame is the global frame, according to OnServer
  bool system = true;
  int i = 0;
  bool found = false;

  always_assert(version == 2);

  for (ArrayIter iter(variables); iter; ++iter) {
    auto const name = iter.first().toString();
    String value;

    // Using the new protocol, so variables contain only names.  Fetch the value
    // separately.
    CmdVariable cmd(client.isStackTraceAsync()
                    ? KindOfVariableAsync : KindOfVariable);
    cmd.m_frame = frame;
    cmd.m_variables.reset();
    cmd.m_varName = name;
    cmd.m_filter = text;
    cmd.m_formatMaxLen = 200;
    cmd.m_version = 2;
    auto rcmd = client.xend<CmdVariable>(&cmd);
    if (!rcmd->m_variables.empty()) {
      assert(rcmd->m_variables[name].isString());
      value = rcmd->m_variables[name].toString();
      found = true;
    } else if (text.empty()) {
      // Not missing because filtered out, assume the value is too large.
      value = s_omitted;
      found = true;
    } else if (name.find(text, 0, false) >= 0) {
      // Server should have matched it.  Assume missing because value is too
      // large.
      value = s_omitted;
      found = true;
    } else {
      // The variable was filtered out on the server, using text.  Or it was
      // just too large.  Either way we skip over it.
      continue;
    }

    if (global && system) {
      client.print("$%s = %s", name.data(), value.data());
    } else {
      client.output("$%s = %s", name.data(), value.data());
    }

    // We know s_HTTP_RAW_POST_DATA is the last system global.
    if (global && name == s_HTTP_RAW_POST_DATA) {
      client.output("%s", "");
      system = false;
    }

    ++i;
    if (i % DebuggerClient::ScrollBlockSize == 0 &&
        client.ask("There are %zd more variables. Continue? [Y/n]",
                   variables.size() - i) == 'n') {
      break;
    }
  }

  if (!text.empty() && !found) {
    client.info("(unable to find specified text in any variables)");
  }
}
コード例 #6
0
ファイル: cmd_variable.cpp プロジェクト: Orvid/hhvm
void CmdVariable::PrintVariable(DebuggerClient &client, const String& varName) {
  CmdVariable cmd(client.isStackTraceAsync()
                  ? KindOfVariableAsync : KindOfVariable);
  auto charCount = client.getDebuggerClientShortPrintCharCount();
  cmd.m_frame = client.getFrame();
  auto rcmd = client.xend<CmdVariable>(&cmd);

  always_assert(rcmd->m_version == 2);

  // Using the new protocol.  rcmd contains a list of variables only.  Fetch
  // value of varName only, so that we can recover nicely when its value is too
  // large to serialize.
  cmd.m_varName = varName;
  cmd.m_variables.reset();
  cmd.m_formatMaxLen = charCount;
  cmd.m_version = 2;
  rcmd = client.xend<CmdVariable>(&cmd);

  if (rcmd->m_variables.empty()) {
    // Perhaps the value is too large? See recvImpl.  Retry the command with
    // version 1, in which case values are omitted.
    cmd.m_version = 1;
    rcmd = client.xend<CmdVariable>(&cmd);
    if (!rcmd->m_variables.empty()) {
      // It's there without values, and gone with values, so it is too large.
      client.output(s_omitted);
    }
    return;
  }

  auto const get_var = [varName] (const CmdVariable& cmd) {
    assert(cmd.m_variables.size() == 1);
    assert(cmd.m_variables.exists(varName, true /* isKey */));
    assert(cmd.m_variables[varName].isString());
    return cmd.m_variables[varName].toString();
  };

  auto const value = get_var(*rcmd);
  if (charCount <= 0 || value.size() <= charCount) {
    client.output(value);
    return;
  }

  // Don't show the "omitted" suffix.
  auto piece = folly::StringPiece{value.data(), static_cast<size_t>(charCount)};
  client.output(piece);
  if (client.ask("There are more characters. Continue? [y/N]") == 'y') {
    // Now we get the full value, and show the rest.
    cmd.m_variables.reset();
    cmd.m_formatMaxLen = -1;
    rcmd = client.xend<CmdVariable>(&cmd);

    auto value = get_var(*rcmd);
    auto rest = folly::StringPiece {
      value.data() + charCount,
      static_cast<size_t>(value.size() - charCount)
    };
    client.output(rest);
    client.tutorial("You can use 'set cc n' to increase the character"
                    " limit. 'set cc -1' will remove the limit.");
  }
}