Add support for DelayForDebugger option on linux

This commit is contained in:
baldurk
2020-05-23 00:13:04 +01:00
parent b8c9a30d7a
commit f39e05a4d6
6 changed files with 67 additions and 7 deletions
@@ -107,7 +107,7 @@ bool StopChildAtMain(pid_t childPid)
return false;
}
void ResumeProcess(pid_t childPid)
void ResumeProcess(pid_t childPid, uint32_t delay)
{
}
+1 -1
View File
@@ -157,7 +157,7 @@ bool StopChildAtMain(pid_t childPid)
return false;
}
void ResumeProcess(pid_t childPid)
void ResumeProcess(pid_t childPid, uint32_t delay)
{
}
+1 -1
View File
@@ -145,7 +145,7 @@ bool StopChildAtMain(pid_t childPid)
return false;
}
void ResumeProcess(pid_t childPid)
void ResumeProcess(pid_t childPid, uint32_t delay)
{
}
+1 -1
View File
@@ -85,7 +85,7 @@ int GetIdentPort(pid_t childPid);
void StopAtMainInChild();
bool StopChildAtMain(pid_t childPid);
void ResumeProcess(pid_t childPid);
void ResumeProcess(pid_t childPid, uint32_t delay = 0);
__attribute__((visibility("default"))) pid_t fork()
{
+61 -1
View File
@@ -410,10 +410,70 @@ void StopAtMainInChild()
raise(SIGSTOP);
}
void ResumeProcess(pid_t childPid)
void ResumeProcess(pid_t childPid, uint32_t delaySeconds)
{
if(childPid != 0)
{
// if we have a delay, see if the process is paused. If so then detach it but keep it stopped
// and wait to see if someone attaches
if(delaySeconds > 0)
{
uint64_t ip = get_child_ip(childPid);
if(ip != 0)
{
// detach but stop, to allow a debugger to attach
ptrace(PTRACE_DETACH, childPid, NULL, SIGSTOP);
rdcstr filename = StringFormat::Fmt("/proc/%u/status", childPid);
uint64_t start_nano = get_nanotime();
uint64_t end_nano = 0;
const uint64_t timeoutNanoseconds = uint64_t(delaySeconds) * 1000 * 1000 * 1000;
bool connected = false;
// watch for a tracer to attach
do
{
usleep(10);
rdcstr status;
FileIO::ReadAll(filename, status);
int32_t offs = status.find("TracerPid:");
if(offs < 0)
break;
status.erase(0, offs + sizeof("TracerPid:"));
status.trim();
end_nano = get_nanotime();
if(status[0] != '0')
{
RDCLOG("Debugger PID %u attached after %f seconds", atoi(status.c_str()),
double(end_nano - start_nano) / 1000000000.0);
connected = true;
break;
}
} while(end_nano - start_nano < timeoutNanoseconds);
if(!connected)
{
RDCLOG("Timed out waiting for debugger, resuming");
kill(childPid, SIGCONT);
}
return;
}
else
{
RDCERR("Can't delay for debugger without ptrace, check ptrace_scope value");
}
}
// try to detach and resume the process, ignoring any errors if we weren't tracing
ptrace(PTRACE_DETACH, childPid, NULL, NULL);
}
+2 -2
View File
@@ -48,7 +48,7 @@ int GetIdentPort(pid_t childPid);
// us check the ident port and resume.
void StopAtMainInChild();
bool StopChildAtMain(pid_t childPid);
void ResumeProcess(pid_t childPid);
void ResumeProcess(pid_t childPid, uint32_t delay = 0);
#if ENABLED(RDOC_APPLE)
@@ -853,7 +853,7 @@ rdcpair<ReplayStatus, uint32_t> Process::LaunchAndInjectIntoProcess(
// exponential wait to get it as soon as possible
ret = GetIdentPort(childPid);
ResumeProcess(ret);
ResumeProcess(childPid, opts.delayForDebugger);
if(waitForExit)
{