mirror of
https://github.com/darlinghq/darlingserver.git
synced 2024-11-23 04:19:44 +00:00
Add a set_tracer
call (and implement get_tracer
)
This commit is contained in:
parent
2b0ae0e30b
commit
8bb81313a0
@ -79,6 +79,7 @@ namespace DarlingServer {
|
||||
std::unordered_map<uintptr_t, std::weak_ptr<Kqchan::Process>> _listeningKqchannels;
|
||||
dtape_semaphore_t* _dtapeForkWaitSemaphore;
|
||||
Architecture _architecture;
|
||||
std::weak_ptr<Process> _tracerProcess;
|
||||
|
||||
#if DSERVER_EXTENDED_DEBUG
|
||||
std::unordered_map<uint32_t, uintptr_t> _registeredNames;
|
||||
@ -156,6 +157,9 @@ namespace DarlingServer {
|
||||
MemoryInfo memoryInfo() const;
|
||||
void memoryRegionInfo(uintptr_t address, uintptr_t& startAddress, uint64_t& pageCount, int& protection, uint64_t& mapOffset, bool& shared) const;
|
||||
|
||||
std::shared_ptr<Process> tracerProcess() const;
|
||||
bool setTracerProcess(std::shared_ptr<Process> tracerProcess);
|
||||
|
||||
static std::shared_ptr<Process> currentProcess();
|
||||
static std::shared_ptr<Process> kernelProcess();
|
||||
|
||||
|
@ -131,7 +131,7 @@ calls = [
|
||||
]),
|
||||
|
||||
('get_tracer', [], [
|
||||
('tracer', 'uint32_t'),
|
||||
('tracer', 'int32_t'),
|
||||
]),
|
||||
|
||||
('uidgid', [
|
||||
@ -188,6 +188,11 @@ calls = [
|
||||
('console', '@fd'),
|
||||
]),
|
||||
|
||||
('set_tracer', [
|
||||
('target', 'int32_t'),
|
||||
('tracer', 'int32_t'),
|
||||
], []),
|
||||
|
||||
#
|
||||
# kqueue channels
|
||||
#
|
||||
|
59
src/call.cpp
59
src/call.cpp
@ -417,9 +417,21 @@ void DarlingServer::Call::StartedSuspended::processCall() {
|
||||
|
||||
void DarlingServer::Call::GetTracer::processCall() {
|
||||
int code = 0;
|
||||
uint32_t tracer = 0;
|
||||
int32_t tracer = 0;
|
||||
|
||||
callLog.warning() << "GetTracer: TODO" << callLog.endLog;
|
||||
if (auto thread = _thread.lock()) {
|
||||
if (auto process = thread->process()) {
|
||||
if (auto tracerProcess = process->tracerProcess()) {
|
||||
tracer = tracerProcess->nsid();
|
||||
} else {
|
||||
// leave `tracer` as 0
|
||||
}
|
||||
} else {
|
||||
code = -ESRCH;
|
||||
}
|
||||
} else {
|
||||
code = -ESRCH;
|
||||
}
|
||||
|
||||
_sendReply(code, tracer);
|
||||
};
|
||||
@ -769,4 +781,47 @@ void DarlingServer::Call::ConsoleOpen::processCall() {
|
||||
_sendReply(code, sockets[1]);
|
||||
};
|
||||
|
||||
void DarlingServer::Call::SetTracer::processCall() {
|
||||
int code = 0;
|
||||
std::shared_ptr<Process> targetProcess = nullptr;
|
||||
std::shared_ptr<Process> tracerProcess = nullptr;
|
||||
|
||||
if (_body.target == 0) {
|
||||
if (auto thread = _thread.lock()) {
|
||||
targetProcess = thread->process();
|
||||
}
|
||||
} else {
|
||||
if (auto maybeTargetProcess = processRegistry().lookupEntryByNSID(_body.target)) {
|
||||
targetProcess = *maybeTargetProcess;
|
||||
}
|
||||
}
|
||||
|
||||
if (targetProcess) {
|
||||
if (_body.tracer == 0) {
|
||||
// leave tracer process as nullptr
|
||||
} else {
|
||||
if (auto maybeTracerProcess = processRegistry().lookupEntryByNSID(_body.tracer)) {
|
||||
tracerProcess = *maybeTracerProcess;
|
||||
} else {
|
||||
// intentionally not negated because this is not an internal error;
|
||||
// this is a perfectly valid case
|
||||
code = ESRCH;
|
||||
}
|
||||
}
|
||||
|
||||
if (code == 0) {
|
||||
if (!targetProcess->setTracerProcess(tracerProcess)) {
|
||||
// again, not negated because this isn't an internal error;
|
||||
// simply indicates there was already a tracer set for the target
|
||||
code = EPERM;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// ditto from before
|
||||
code = ESRCH;
|
||||
}
|
||||
|
||||
_sendReply(code);
|
||||
};
|
||||
|
||||
DSERVER_CLASS_SOURCE_DEFS;
|
||||
|
@ -530,3 +530,17 @@ void DarlingServer::Process::_clearPortSet(dtape_port_set_id_t portSetID) {
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
std::shared_ptr<DarlingServer::Process> DarlingServer::Process::tracerProcess() const {
|
||||
std::shared_lock lock(_rwlock);
|
||||
return _tracerProcess.lock();
|
||||
};
|
||||
|
||||
bool DarlingServer::Process::setTracerProcess(std::shared_ptr<Process> tracerProcess) {
|
||||
std::unique_lock lock(_rwlock);
|
||||
if (!_tracerProcess.expired()) {
|
||||
return false;
|
||||
}
|
||||
_tracerProcess = tracerProcess;
|
||||
return true;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user