Exemplo n.º 1
0
/**
 * Attaches to the target process.
 *
 * @param tids The thread IDs of the threads that belong to the target process.
 *
 * @return A NaviError code that describes whether the operation was successful or not.
 */
NaviError LinuxSystem::attachToProcess() {


  msglog->log(LOG_VERBOSE, "Trying to attach to process %d", getPID());

  int result = ptrace(PTRACE_ATTACH, getPID(), 0, 0);

  if (result) {
    msglog->log(LOG_ALWAYS, "Error: Couldn't attach to process");
    return errno;
  }

  // TODO: Right now multi-threading is not supported
  Thread ts(getPID(), SUSPENDED);
  tids.push_back(ts);
  setActiveThread (getPID());

std  ::string path;
  NaviError pathError = getExecutablePath(getPID(), path);
  if (pathError) {
    msglog->log(
        LOG_ALWAYS,
        "Error: Unable to determine the executable path of the debuggee.");
    return pathError;
  }

  // Generate processStart message and send it to BinNavi.
  fillModules(getPID(), this->modules);
  std::map<std::string, Module>::const_iterator cit = this->modules.find(path);
  if (cit != this->modules.end()) {
    Module processModule = cit->second;
    processStart(processModule, ts);
  } else {
    msglog->log(LOG_ALWAYS,
                "Error: Unable to determine main process module for '%s'",
                path.c_str());
    exit(0);
  }

  return NaviErrors::SUCCESS;
}
Exemplo n.º 2
0
/**
 * Attaches to the target process.
 *
 * @param tids The thread IDs of the threads that belong to the target process.
 *
 * @return A NaviError code that describes whether the operation was successful
 * or not.
 */
NaviError GdbSystem::attachToProcess() {


  std::vector < Thread > tids;
  NaviError attachResult = cpu->attach(tids, this);

  if (attachResult) {
    msglog->log(LOG_VERBOSE, "Error: Couldn't attach to GDB server (Code: %d)",
                attachResult);
  } else {
    unsigned int activeThread;
    cpu->getActiveThread(activeThread, this);
    setActiveThread(activeThread);
    // The module constructor parameters are an optimistic over-approximation
    // since
    // Gdb can not provide us with better info about the executable image.
    processStart(Module("", "", 0, 0xFFFFFFFF),
                 Thread(activeThread, SUSPENDED));
  }

  return attachResult;
}
Exemplo n.º 3
0
/**
 * Starts a new process for debugging.
 *
 * @param path The path to the executable of the process.
 * @param tids The thread IDs of the threads that belong to the target process.
 *
 * @return A NaviError code that describes whether the operation was successful or not.
 */
NaviError LinuxSystem::startProcess(
    const NATIVE_STRING path,
    const std::vector<const NATIVE_STRING>& commands) {


  pid_t pid = fork();

  if (pid == -1) {
    msglog->log(LOG_ALWAYS, "Error: Couldn't fork process");
    return NaviErrors::COULDNT_OPEN_TARGET_PROCESS;
  } else if (pid == 0) {
    ptrace(PTRACE_TRACEME, 0, 0, 0);

    char** child_arguments = new char*[1 + commands.size() + 1];
    child_arguments[0] = new char[strlen(path) + 1];
    strcpy(child_arguments[0], path);

    for (unsigned int i = 0; i < commands.size(); i++) {
      child_arguments[i + 1] = new char[strlen(commands[i]) + 1];
      strcpy(child_arguments[i + 1], commands[i]);
    }

    child_arguments[1 + commands.size()] = 0;

    // Child process
    if (execvp(path, child_arguments) == -1) {
      msglog->log(LOG_ALWAYS, "Error: Could not start the child process '%s'",
                  path);
      exit(0);
    }

    return NaviErrors::SUCCESS;
  } else {
    int status;
    if (waitpid(pid, &status, __WALL) == -1) {
      msglog->log(LOG_ALWAYS, "Error: Wait for target process failed '%s'",
                  path);
      exit(0);
    }

    if (WIFSTOPPED(status)) {
      if (WSTOPSIG(status) == SIGTRAP) {
        msglog->log(LOG_VERBOSE, "Initial STOP signal received");
      } else {
        msglog->log(LOG_ALWAYS, "Error: Received unexpected STOP signal");
        exit(0);
      }
    } else {
      msglog->log(LOG_ALWAYS, "Error: Did not receive initial STOP signal");
      exit(0);
    }

    if (ptrace(
        PTRACE_SETOPTIONS,
        pid,
        0,
        PTRACE_O_TRACECLONE | PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK
            | PTRACE_O_TRACEVFORKDONE) == -1) {
      msglog->log(LOG_ALWAYS, "Error: Could not set ptrace options");
      exit(0);
    }

    msglog->log(LOG_VERBOSE, "PID of the child process is %d", pid);

    setPID(pid);
    Thread ts(pid, SUSPENDED);
    tids.push_back(ts);
    setActiveThread(pid);

    lastMapFileSize = getFileSize(
        "/proc/" + zylib::zycon::toString(pid) + "/maps");

    fillModules(pid, modules);
    this->modules = modules;

    std::map<std::string, Module>::const_iterator cit = this->modules.find(
        getTargetApplicationPath().string());
    if (cit != this->modules.end()) {
      Module processModule = cit->second;
      processStart(processModule, ts);
    } else {
      msglog->log(LOG_ALWAYS,
                  "Error: Unable to determine main process module for '%s'",
                  getTargetApplicationPath().string().c_str());
      exit(0);
    }

    return NaviErrors::SUCCESS;
  }
}
void
draw()
{
   if (!gIsVisible) {
      return;
   }

   ImGui::SetNextWindowSize(ImVec2(600, 300), ImGuiSetCond_FirstUseEver);

   if (!ImGui::Begin("Threads", &gIsVisible)) {
      ImGui::End();
      return;
   }

   sThreadsCache.clear();

   coreinit::internal::lockScheduler();
   auto core0Thread = coreinit::internal::getCoreRunningThread(0);
   auto core1Thread = coreinit::internal::getCoreRunningThread(1);
   auto core2Thread = coreinit::internal::getCoreRunningThread(2);
   auto firstThread = coreinit::internal::getFirstActiveThread();

   for (auto thread = firstThread; thread; thread = thread->activeLink.next) {
      ThreadInfo tinfo;
      tinfo.thread = thread;
      tinfo.id = thread->id;
      tinfo.name = thread->name ? thread->name.get() : "";
      tinfo.state = thread->state;
      tinfo.priority = thread->priority;
      tinfo.basePriority = thread->basePriority;
      tinfo.affinity = thread->attr & coreinit::OSThreadAttributes::AffinityAny;

      if (thread == core0Thread) {
         tinfo.coreId = 0;
      } else if (thread == core1Thread) {
         tinfo.coreId = 1;
      } else if (thread == core2Thread) {
         tinfo.coreId = 2;
      } else {
         tinfo.coreId = -1;
      }

      tinfo.coreTimeNs = thread->coreTimeConsumedNs;

      if (tinfo.coreId != -1) {
         tinfo.coreTimeNs += coreinit::internal::getCoreThreadRunningTime(0);
      }

      sThreadsCache.push_back(tinfo);
   }

   coreinit::internal::unlockScheduler();

   ImGui::Columns(8, "threadList", false);
   ImGui::SetColumnOffset(0, ImGui::GetWindowWidth() * 0.00f);
   ImGui::SetColumnOffset(1, ImGui::GetWindowWidth() * 0.05f);
   ImGui::SetColumnOffset(2, ImGui::GetWindowWidth() * 0.35f);
   ImGui::SetColumnOffset(3, ImGui::GetWindowWidth() * 0.50f);
   ImGui::SetColumnOffset(4, ImGui::GetWindowWidth() * 0.60f);
   ImGui::SetColumnOffset(5, ImGui::GetWindowWidth() * 0.70f);
   ImGui::SetColumnOffset(6, ImGui::GetWindowWidth() * 0.75f);
   ImGui::SetColumnOffset(7, ImGui::GetWindowWidth() * 0.84f);

   ImGui::Text("ID"); ImGui::NextColumn();
   ImGui::Text("Name"); ImGui::NextColumn();
   ImGui::Text("NIA"); ImGui::NextColumn();
   ImGui::Text("State"); ImGui::NextColumn();
   ImGui::Text("Prio"); ImGui::NextColumn();
   ImGui::Text("Aff"); ImGui::NextColumn();
   ImGui::Text("Core"); ImGui::NextColumn();
   ImGui::Text("Core Time"); ImGui::NextColumn();
   ImGui::Separator();

   for (auto &thread : sThreadsCache) {
      // ID
      if (thread.thread == getActiveThread()) {
         // Highlight the currently active thread
         // TODO: Clean this up
         auto idStr = fmt::format("{}", thread.id);
         auto drawList = ImGui::GetWindowDrawList();
         auto lineHeight = ImGui::GetTextLineHeight();
         float glyphWidth = ImGui::CalcTextSize("FF").x - ImGui::CalcTextSize("F").x;
         float idWidth = glyphWidth * idStr.length();
         auto rootPos = ImGui::GetCursorScreenPos();
         auto idMin = ImVec2(rootPos.x - 1, rootPos.y);
         auto idMax = ImVec2(rootPos.x + idWidth + 2, rootPos.y + lineHeight + 1);
         drawList->AddRectFilled(idMin, idMax, ImColor(CurrentBgColor), 2.0f);
         ImGui::TextColored(CurrentColor, "%s", idStr.c_str());
      } else {
         ImGui::Text("%d", thread.id);
      }
      ImGui::NextColumn();

      // Name
      if (isPaused()) {
         auto threadName = thread.name;

         if (thread.name.size() == 0) {
            threadName = fmt::format("(Unnamed Thread {})", thread.id);
         }

         if (ImGui::Selectable(threadName.c_str())) {
            setActiveThread(thread.thread);
         }
      } else {
         ImGui::Text("%s", thread.name.c_str());
      }

      ImGui::NextColumn();

      // NIA
      if (isPaused()) {
         ImGui::Text("%08x", getThreadNia(thread.thread));
      } else {
         ImGui::Text("        ");
      }

      ImGui::NextColumn();

      // Thread State
      ImGui::Text("%s", coreinit::enumAsString(thread.state).c_str());
      ImGui::NextColumn();

      // Priority
      ImGui::Text("%d (%d)", thread.priority, thread.basePriority);
      ImGui::NextColumn();

      // Affinity
      std::string coreAff;

      if (thread.affinity & coreinit::OSThreadAttributes::AffinityCPU0) {
         coreAff += "0";
      }

      if (thread.affinity & coreinit::OSThreadAttributes::AffinityCPU1) {
         if (coreAff.size() != 0) {
            coreAff += "|1";
         } else {
            coreAff += "1";
         }
      }

      if (thread.affinity & coreinit::OSThreadAttributes::AffinityCPU2) {
         if (coreAff.size() != 0) {
            coreAff += "|2";
         } else {
            coreAff += "2";
         }
      }

      ImGui::Text("%s", coreAff.c_str());
      ImGui::NextColumn();

      // Core Id
      if (thread.coreId != -1) {
         ImGui::Text("%d", thread.coreId);
      }

      ImGui::NextColumn();

      // Core Time
      ImGui::Text("%" PRIu64, thread.coreTimeNs / 1000);
      ImGui::NextColumn();
   }

   ImGui::Columns(1);
   ImGui::End();
}