void CmdInternalTesting::onClientImpl(DebuggerClient &client) {
  TRACE(2, "CmdInternalTesting::onClientImpl\n");
  if (DebuggerCommand::displayedHelp(client)) return;
  if (client.argCount() == 0) {
    help(client);
    return;
  }

  client.info("Executing internal test...");
  m_arg = client.argValue(1);

  if (client.arg(1, "badcmdtypesend")) {
    // Give the cmd a bad type and send it over. This should cause the proxy to
    // disconnect from us.
    m_type = KindOfInternalTestingBad;
    client.sendToServer(this);
    // Spin here and wait for the client to be marked as stopped
    // before going back to the event loop. This will give the local
    // proxy time to recgonize the bad cmd, terminate, and wait for
    // the client to stop. This will ensure that we always exit on the
    // same path on both proxy and client threads, and remove any
    // spurious output form ths test case.
    while (!client.internalTestingIsClientStopped()) {
      sleep(1);
    }
    throw DebuggerConsoleExitException(); // Expect no response
  } else if (client.arg(1, "badcmdtypereceive")) {
    client.xend<CmdInternalTesting>(this);
    return;
  } else if (client.arg(1, "shortcmdsend")) {
    m_arg = "shortcmd"; // Force send to drop a field.
    client.sendToServer(this);
    // See note above about this wait.
    while (!client.internalTestingIsClientStopped()) {
      sleep(1);
    }
    throw DebuggerConsoleExitException(); // Expect no response
  } else if (client.arg(1, "shortcmdreceive")) {
    client.xend<CmdInternalTesting>(this);
    return;
  } else if (client.arg(1, "segfaultClient")) {
    int *px = nullptr;
    *px = 42;
  } else if (client.arg(1, "segfaultServer")) {
    client.xend<CmdInternalTesting>(this);
    return;
  }

  help(client);
}
Esempio n. 2
0
void CmdFlowControl::onClient(DebuggerClient &client) {
  if (DebuggerCommand::displayedHelp(client)) return;

  client.setFrame(0);

  if (client.argCount() > 1) {
    help(client);
    return;
  }

  if (client.argCount() == 1) {
    std::string snum = client.argValue(1);
    if (!DebuggerClient::IsValidNumber(snum)) {
      client.error("Count needs to be a number.");
      return;
    }

    m_count = atoi(snum.c_str());
    if (m_count < 1) {
      client.error("Count needs to be a positive number.");
      return;
    }
  }
  m_smallStep = client.getDebuggerClientSmallStep();
  client.sendToServer(this);
  throw DebuggerConsoleExitException();
}
Esempio n. 3
0
bool CmdFlowControl::onClient(DebuggerClient *client) {
  if (DebuggerCommand::onClient(client)) return true;

  client->setFrame(0);

  if (client->argCount() > 1) {
    return help(client);
  }

  if (client->argCount() == 1) {
    string snum = client->argValue(1);
    if (!DebuggerClient::IsValidNumber(snum)) {
      client->error("Count needs to be a number.");
      return true;
    }

    m_count = atoi(snum.c_str());
    if (m_count < 1) {
      client->error("Count needs to be a positive number.");
      return true;
    }
  }

  client->send(this);
  throw DebuggerConsoleExitException();
}
Esempio n. 4
0
bool CmdRun::onClient(DebuggerClient *client) {
  if (DebuggerCommand::onClient(client)) return true;

  m_args = StringVecPtr(client->args(), null_deleter());
  client->send(this);
  throw DebuggerConsoleExitException();
}
Esempio n. 5
0
void CmdRun::onClient(DebuggerClient &client) {
  TRACE(2, "CmdRun::onClient\n");
  if (DebuggerCommand::displayedHelp(client)) return;

  m_args = StringVecPtr(client.args(), null_deleter());
  client.sendToServer(this);
  client.clearCachedLocal();
  client.setFrame(0);
  throw DebuggerConsoleExitException();
}
Esempio n. 6
0
void CmdRun::onClientImpl(DebuggerClient &client) {
  if (DebuggerCommand::displayedHelp(client)) return;

  m_args = StringVecPtr(client.args(), null_deleter());
  m_smallStep = client.getDebuggerSmallStep();
  client.sendToServer(this);
  client.clearCachedLocal();
  client.setFrame(0);
  throw DebuggerConsoleExitException();
}
Esempio n. 7
0
void CmdRun::onClient(DebuggerClient &client) {
  TRACE(2, "CmdRun::onClient\n");
  if (DebuggerCommand::displayedHelp(client)) return;

  m_args = std::shared_ptr<std::vector<std::string>>(client.args(),
    [] (const void*) {});
  client.sendToServer(this);
  client.clearCachedLocal();
  client.setFrame(0);
  throw DebuggerConsoleExitException();
}
Esempio n. 8
0
bool CmdMachine::AttachSandbox(DebuggerClient *client,
                               DSandboxInfoPtr sandbox) {
  if (client->isLocal()) {
    client->error("Local script doesn't have sandbox to attach to.");
    return true;
  }

  CmdMachine cmd;
  cmd.m_body = "attach";
  cmd.m_sandboxes.push_back(sandbox);

  client->send(&cmd);
  client->info("Pre-loading %s, please wait...", sandbox->desc().c_str());
  throw DebuggerConsoleExitException();
}
Esempio n. 9
0
void CmdThread::onClient(DebuggerClient &client) {
  if (DebuggerCommand::displayedHelp(client)) return;
  if (client.argCount() > 1) {
    help(client);
    return;
  }

  if (client.argCount() == 0) {
    m_body = "info";
    auto res = client.xend<CmdThread>(this);
    client.print(res->m_out);
  } else if (client.arg(1, "list")) {
    processList(client);
  } else if (client.arg(1, "normal")) {
    m_body = "normal";
    client.sendToServer(this);
    client.info("Thread is running in normal mode now. Other threads will "
                 "interleave when they hit breakpoints as well.");
  } else if (client.arg(1, "sticky")) {
    m_body = "sticky";
    client.sendToServer(this);
    client.info("Thread is running in sticky mode now. All other threads "
                 "will wait until this thread finishes, when they hit "
                 "breakpoints.");
  } else if (client.arg(1, "exclusive")) {
    m_body = "exclusive";
    client.sendToServer(this);
    client.info("Thread is running in exclusive mode now. All other threads "
                 "will not break, even when they hit breakpoints.");
  } else {
    std::string snum = client.argValue(1);
    if (!DebuggerClient::IsValidNumber(snum)) {
      client.error("'[t]hread {index}' needs a numeric argument.");
      client.tutorial(
        "You will have to run '[t]hread [l]ist' first to see a list of valid "
        "numbers or indices to specify. Thread 1 is always your current "
        "thread. If that's the only thread on the list, you do not have "
        "another thread at break to switch to."
      );
      return;
    }

    int num = atoi(snum.c_str());
    DThreadInfoPtr thread = client.getThread(num);
    if (!thread) {
      processList(client, false);
      thread = client.getThread(num);
      if (!thread) {
        client.error("\"%s\" is not a valid thread index. Choose one from "
                      "this list:", snum.c_str());
        processList(client);
        return;
      }
    }

    if (thread->m_id == client.getCurrentThreadId()) {
      client.info("This is your current thread already.");
      return;
    }

    m_body = "switch";
    m_threads.push_back(thread);
    client.sendToServer(this);
    throw DebuggerConsoleExitException();
  }
}
Esempio n. 10
0
void CmdMachine::onClientImpl(DebuggerClient &client) {
  if (DebuggerCommand::displayedHelp(client)) return;
  if (client.argCount() == 0) {
    help(client);
    return;
  }

  bool rpc = client.arg(1, "rpc");
  if (rpc || client.arg(1, "connect")) {
    if (client.argCount() != 2) {
      help(client);
      return;
    }
    string host = client.argValue(2);
    int port = 0;
    size_t pos = host.find(":");
    if (pos != string::npos) {
      if (!DebuggerClient::IsValidNumber(host.substr(pos + 1))) {
        client.error("Port needs to be a number");
        help(client);
        return;
      }
      port = atoi(host.substr(pos + 1).c_str());
      host = host.substr(0, pos);
    }

    if (rpc) {
      if (client.connectRPC(host, port)) {
        throw DebuggerConsoleExitException();
      }
    } else {
      if (client.connect(host, port)) {
        throw DebuggerConsoleExitException();
      }
    }
    if (!client.initializeMachine()) {
      throw DebuggerConsoleExitException();
    }
    return;
  }

  if (client.arg(1, "disconnect")) {
    if (client.disconnect()) {
      throw DebuggerConsoleExitException();
    }
    if (!client.initializeMachine()) {
      throw DebuggerConsoleExitException();
    }
    return;
  }

  if (client.arg(1, "list")) {
    processList(client);
    return;
  }

  if (client.arg(1, "attach")) {
    DSandboxInfoPtr sandbox;

    string snum = client.argValue(2);
    if (DebuggerClient::IsValidNumber(snum)) {
      int num = atoi(snum.c_str());
      sandbox = client.getSandbox(num);
      if (!sandbox) {
        processList(client, false);
        sandbox = client.getSandbox(num);
        if (!sandbox) {
          client.error("\"%s\" is not a valid sandbox index. Choose one from "
                        "this list:", snum.c_str());
          processList(client);
          return;
        }
      }
    } else {
      int argBase = 2;
      if (client.argCount() >= 2 && client.arg(2, "force")) {
        m_force = true;
        argBase++;
      }
      sandbox = DSandboxInfoPtr(new DSandboxInfo());
      if (client.argCount() < argBase) {
        sandbox->m_user = client.getCurrentUser();
        sandbox->m_name = "default";
      } else if (client.argCount() == argBase) {
        sandbox->m_user = client.getCurrentUser();
        sandbox->m_name = client.argValue(argBase);
      } else if (client.argCount() == argBase + 1) {
        sandbox->m_user = client.argValue(argBase);
        sandbox->m_name = client.argValue(argBase + 1);
      } else {
        help(client);
        return;
      }
    }
    if (AttachSandbox(client, sandbox, m_force)) {
      // Attach succeed, wait for next interrupt
      throw DebuggerConsoleExitException();
    }
    return;
  }

  help(client);
}
Esempio n. 11
0
bool CmdMachine::onClient(DebuggerClient *client) {
  if (DebuggerCommand::onClient(client)) return true;
  if (client->argCount() == 0) return help(client);

  bool rpc = client->arg(1, "rpc");
  if (rpc || client->arg(1, "connect")) {
    if (client->argCount() != 2) {
      return help(client);
    }
    string host = client->argValue(2);
    int port = 0;
    size_t pos = host.find(":");
    if (pos != string::npos) {
      if (!DebuggerClient::IsValidNumber(host.substr(pos + 1))) {
        client->error("Port needs to be a number");
        return help(client);
      }
      port = atoi(host.substr(pos + 1).c_str());
      host = host.substr(0, pos);
    }

    if (rpc) {
      if (client->connectRPC(host, port)) {
        throw DebuggerConsoleExitException();
      }
    } else {
      if (client->connect(host, port)) {
        throw DebuggerConsoleExitException();
      }
    }
    client->initializeMachine();
    return true;
  }

  if (client->arg(1, "disconnect")) {
    if (client->disconnect()) {
      throw DebuggerConsoleExitException();
    }
    client->initializeMachine();
    return true;
  }

  if (client->arg(1, "list")) {
    processList(client);
    return true;
  }

  if (client->arg(1, "attach")) {
    DSandboxInfoPtr sandbox;

    string snum = client->argValue(2);
    if (DebuggerClient::IsValidNumber(snum)) {
      int num = atoi(snum.c_str());
      sandbox = client->getSandbox(num);
      if (!sandbox) {
        processList(client, false);
        sandbox = client->getSandbox(num);
        if (!sandbox) {
          client->error("\"%s\" is not a valid sandbox index. Choose one from "
                        "this list:", snum.c_str());
          processList(client);
          return true;
        }
      }
    } else if (client->argCount() == 2) {
      sandbox = DSandboxInfoPtr(new DSandboxInfo());
      sandbox->m_user = Process::GetCurrentUser();
      sandbox->m_name = snum;
    } else if (client->argCount() == 3) {
      sandbox = DSandboxInfoPtr(new DSandboxInfo());
      sandbox->m_user = snum;
      sandbox->m_name = client->argValue(3);
    } else {
      return help(client);
    }

    return AttachSandbox(client, sandbox);
  }

  return help(client);
}