Tweaks to Process helper class and bug fix

This commit is contained in:
Nav
2022-09-15 20:18:26 +01:00
parent 054bde947b
commit 1f0a82d599
5 changed files with 34 additions and 24 deletions

View File

@@ -7,6 +7,7 @@
#include "src/Logger/Logger.hpp" #include "src/Logger/Logger.hpp"
#include "src/Helpers/Paths.hpp" #include "src/Helpers/Paths.hpp"
#include "src/Helpers/Process.hpp"
#include "src/Exceptions/InvalidConfig.hpp" #include "src/Exceptions/InvalidConfig.hpp"
@@ -509,7 +510,7 @@ namespace Bloom
} }
void Application::onDebugSessionFinished(const Events::DebugSessionFinished& event) { void Application::onDebugSessionFinished(const Events::DebugSessionFinished& event) {
if (this->environmentConfig->shutdownPostDebugSession) { if (this->environmentConfig->shutdownPostDebugSession || Process::isManagedByClion()) {
this->shutdown(); this->shutdown();
} }
} }

View File

@@ -24,7 +24,7 @@ namespace Bloom::DebugServer::Gdb::CommandPackets
Logger::debug("Handling Detach packet"); Logger::debug("Handling Detach packet");
try { try {
if (Process::isManagedByClion(Process::getParentProcessId())) { if (Process::isManagedByClion()) {
targetControllerConsole.suspendTargetController(); targetControllerConsole.suspendTargetController();
} }

View File

@@ -125,7 +125,7 @@ namespace Bloom::DebugServer::Gdb
std::bind(&GdbRspDebugServer::onTargetExecutionStopped, this, std::placeholders::_1) std::bind(&GdbRspDebugServer::onTargetExecutionStopped, this, std::placeholders::_1)
); );
if (Process::isManagedByClion(Process::getParentProcessId())) { if (Process::isManagedByClion()) {
Logger::warning( Logger::warning(
"Bloom's process is being managed by CLion - Bloom will automatically shutdown upon detaching from GDB." "Bloom's process is being managed by CLion - Bloom will automatically shutdown upon detaching from GDB."
); );

View File

@@ -2,6 +2,7 @@
#include <unistd.h> #include <unistd.h>
#include <string> #include <string>
#include <map>
namespace Bloom namespace Bloom
{ {
@@ -13,47 +14,50 @@ namespace Bloom
return getppid(); return getppid();
} }
bool Process::isManagedByClion(::pid_t processId) { bool Process::isManagedByClion(std::optional<::pid_t> parentProcessId) {
static auto cachedResult = std::optional<bool>(); if (!parentProcessId.has_value()) {
parentProcessId = Process::getParentProcessId();
}
if (cachedResult.has_value()) { static auto cachedResultsByProcessId = std::map<::pid_t, bool>();
return cachedResult.value();
if (cachedResultsByProcessId.contains(*parentProcessId)) {
return cachedResultsByProcessId.at(*parentProcessId);
} }
// Walk the process tree until we find CLion // Walk the process tree until we find CLion
auto processId = *parentProcessId;
while (processId != 0) { while (processId != 0) {
const auto processInfo = Process::getProcessInfo(processId); const auto processInfo = Process::getProcessInfo(processId);
if (!processInfo.has_value()) { if (!processInfo) {
break; break;
} }
auto* processInfoPtr = processInfo.value(); const auto commandLine = std::string(processInfo->cmd);
const auto commandLine = std::string(processInfoPtr->cmd);
if (commandLine.find("clion.sh") != std::string::npos) { if (commandLine.find("clion.sh") != std::string::npos) {
freeproc(processInfoPtr); cachedResultsByProcessId[*parentProcessId] = true;
cachedResult = true;
return true; return true;
} }
processId = processInfoPtr->ppid; processId = processInfo->ppid;
freeproc(processInfoPtr);
} }
cachedResult = true; cachedResultsByProcessId[*parentProcessId] = false;
return false; return false;
} }
std::optional<::proc_t*> Process::getProcessInfo(::pid_t processId) { Process::ProcT Process::getProcessInfo(::pid_t processId) {
auto* proc = ::openproc(PROC_FILLSTAT | PROC_FILLARG | PROC_PID, &processId); auto proc = std::unique_ptr<::PROCTAB, decltype(&::closeproc)>(
auto* processInfo = ::readproc(proc, NULL); ::openproc(PROC_FILLSTAT | PROC_FILLARG | PROC_PID, &processId),
::closeproc
);
auto processInfo = ProcT(::readproc(proc.get(), NULL), ::freeproc);
if (processInfo == NULL) { if (processInfo == NULL) {
return std::nullopt; return ProcT(nullptr, ::freeproc);
} }
closeproc(proc);
return processInfo; return processInfo;
} }
} }

View File

@@ -1,6 +1,7 @@
#pragma once #pragma once
#include <optional> #include <optional>
#include <memory>
#include <proc/readproc.h> #include <proc/readproc.h>
namespace Bloom namespace Bloom
@@ -25,12 +26,16 @@ namespace Bloom
/** /**
* Returns true if the given process is managed by CLion. * Returns true if the given process is managed by CLion.
* *
* @param processId * @param parentProcessId
* If not provided, this function will perform the check against the current process.
*
* @return * @return
*/ */
static bool isManagedByClion(::pid_t processId); static bool isManagedByClion(std::optional<::pid_t> parentProcessId = std::nullopt);
private: private:
static std::optional<::proc_t*> getProcessInfo(::pid_t processId); using ProcT = std::unique_ptr<::proc_t, decltype(&::freeproc)>;
static ProcT getProcessInfo(::pid_t processId);
}; };
} }