mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-12 13:00:32 +00:00
Add support for DelayForDebugger option on linux
This commit is contained in:
@@ -107,7 +107,7 @@ bool StopChildAtMain(pid_t childPid)
|
||||
return false;
|
||||
}
|
||||
|
||||
void ResumeProcess(pid_t childPid)
|
||||
void ResumeProcess(pid_t childPid, uint32_t delay)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -157,7 +157,7 @@ bool StopChildAtMain(pid_t childPid)
|
||||
return false;
|
||||
}
|
||||
|
||||
void ResumeProcess(pid_t childPid)
|
||||
void ResumeProcess(pid_t childPid, uint32_t delay)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -145,7 +145,7 @@ bool StopChildAtMain(pid_t childPid)
|
||||
return false;
|
||||
}
|
||||
|
||||
void ResumeProcess(pid_t childPid)
|
||||
void ResumeProcess(pid_t childPid, uint32_t delay)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user