implement attach and launch
This commit is contained in:
@@ -1,39 +1,42 @@
|
||||
add_library(libedbg libedbg.cpp)
|
||||
SET(SRC
|
||||
process.cpp
|
||||
)
|
||||
add_library(libedbg ${SRC})
|
||||
add_library(edbg::libedbg ALIAS libedbg)
|
||||
|
||||
set_target_properties(
|
||||
libedbg
|
||||
PROPERTIES OUTPUT_NAME edbg
|
||||
libedbg
|
||||
PROPERTIES OUTPUT_NAME edbg
|
||||
)
|
||||
|
||||
target_compile_features(libedbg PUBLIC cxx_std_20)
|
||||
|
||||
target_include_directories(
|
||||
libedbg
|
||||
PUBLIC
|
||||
libedbg
|
||||
PUBLIC
|
||||
$<INSTALL_INTERFACE::include>
|
||||
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include>
|
||||
PRIVATE
|
||||
PRIVATE
|
||||
${CMAKE_SOURCE_DIR}/src/include
|
||||
)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
install(TARGETS libedbg
|
||||
EXPORT edbg-targets
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
||||
EXPORT edbg-targets
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
||||
)
|
||||
|
||||
install(
|
||||
DIRECTORY ${PROJECT_SOURCE_DIR}/include/
|
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
||||
DIRECTORY ${PROJECT_SOURCE_DIR}/include/
|
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
||||
)
|
||||
|
||||
install(
|
||||
EXPORT edbg-targets
|
||||
FILE edbg-config.cmake
|
||||
NAMESPACE edbg::
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/edbg
|
||||
EXPORT edbg-targets
|
||||
FILE edbg-config.cmake
|
||||
NAMESPACE edbg::
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/edbg
|
||||
)
|
||||
@@ -1,6 +0,0 @@
|
||||
#include <iostream>
|
||||
#include <libedbg/libedbg.hpp>
|
||||
|
||||
void edbg::hello() {
|
||||
std::cout << "Hello edbg!\n";
|
||||
}
|
||||
90
src/process.cpp
Normal file
90
src/process.cpp
Normal file
@@ -0,0 +1,90 @@
|
||||
#include <sys/ptrace.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <libedbg/process.hpp>
|
||||
#include <libedbg/error.hpp>
|
||||
|
||||
|
||||
edbg::stop_reason::stop_reason(const int wait_status) {
|
||||
if (WIFEXITED(wait_status)) {
|
||||
reason = process_state::exited;
|
||||
info = WEXITSTATUS(wait_status);
|
||||
} else if (WIFSIGNALED(wait_status)) {
|
||||
reason = process_state::terminated;
|
||||
info = WTERMSIG(wait_status);
|
||||
} else if (WIFSTOPPED(wait_status)) {
|
||||
reason = process_state::stopped;
|
||||
info = WSTOPSIG(wait_status);
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<edbg::process> edbg::process::launch(std::filesystem::path path) {
|
||||
pid_t pid;
|
||||
if ((pid = fork()) < 0) {
|
||||
error::send_errno("fork failed");
|
||||
}
|
||||
|
||||
if (pid == 0) {
|
||||
if (ptrace(PTRACE_TRACEME, 0, nullptr, nullptr) < 0) {
|
||||
error::send_errno("ptrace failed");
|
||||
}
|
||||
if (execlp(path.c_str(), path.c_str(), nullptr) < 0) {
|
||||
error::send_errno("execlp failed");
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<edbg::process> proc(new process(pid, true));
|
||||
proc->wait_on_signal();
|
||||
|
||||
return proc;
|
||||
}
|
||||
|
||||
std::unique_ptr<edbg::process> edbg::process::attach(const pid_t pid) {
|
||||
if (pid == 0) {
|
||||
error::send("invalid pid of 0");
|
||||
}
|
||||
if (ptrace(PTRACE_ATTACH, pid, 0, nullptr) < 0) {
|
||||
error::send_errno("ptrace attach failed");
|
||||
}
|
||||
|
||||
std::unique_ptr<edbg::process> proc(new process(pid, false));
|
||||
proc->wait_on_signal();
|
||||
|
||||
return proc;
|
||||
}
|
||||
|
||||
void edbg::process::resume() {
|
||||
if (ptrace(PTRACE_CONT, pid_, 0, nullptr) < 0) {
|
||||
error::send_errno("ptrace resume failed");
|
||||
}
|
||||
state_ = process_state::running;
|
||||
}
|
||||
|
||||
edbg::stop_reason edbg::process::wait_on_signal() {
|
||||
int wait_status;
|
||||
if (waitpid(pid_, &wait_status, 0) < 0) {
|
||||
error::send_errno("waitpid failed");
|
||||
}
|
||||
const stop_reason reason(wait_status);
|
||||
state_ = reason.reason;
|
||||
return reason;
|
||||
}
|
||||
|
||||
edbg::process::~process() {
|
||||
if (pid_ != 0) {
|
||||
int status;
|
||||
if (state_ == process_state::running) {
|
||||
kill(pid_, SIGSTOP);
|
||||
waitpid(pid_, &status, 0);
|
||||
}
|
||||
ptrace(PTRACE_DETACH, pid_);
|
||||
kill(pid_, SIGCONT);
|
||||
|
||||
if (terminate_on_end_) {
|
||||
kill(pid_, SIGKILL);
|
||||
waitpid(pid_, &status, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user