diff --git a/renderdoc/os/os_specific.h b/renderdoc/os/os_specific.h index 7e51fd462..88d991b33 100644 --- a/renderdoc/os/os_specific.h +++ b/renderdoc/os/os_specific.h @@ -317,7 +317,7 @@ namespace OSUtility { inline void ForceCrash(); inline void DebugBreak(); -inline bool DebuggerPresent(); +bool DebuggerPresent(); enum { Output_DebugMon, diff --git a/renderdoc/os/posix/android/android_process.cpp b/renderdoc/os/posix/android/android_process.cpp index 97356b727..7ae4d63a7 100644 --- a/renderdoc/os/posix/android/android_process.cpp +++ b/renderdoc/os/posix/android/android_process.cpp @@ -77,3 +77,46 @@ int GetIdentPort(pid_t childPid) return ret; } + +// because OSUtility::DebuggerPresent is called often we want it to be +// cheap. Opening and parsing a file would cause high overhead on each +// call, so instead we just cache it at startup. This fails in the case +// of attaching to processes +bool debuggerPresent = false; + +void CacheDebuggerPresent() +{ + FILE *f = FileIO::fopen("/proc/self/status", "r"); + + if(f == NULL) + { + RDCWARN("Couldn't open /proc/self/status"); + return; + } + + // read through the proc file to check for TracerPid + while(ret == 0 && !feof(f)) + { + const size_t sz = 512; + char line[sz]; + line[sz - 1] = 0; + fgets(line, sz - 1, f); + + int tracerpid = 0; + int num = sscanf(line, "TracerPid: %d", &tracerpid); + + // found TracerPid line + if(num == 1) + { + debuggerPresent = (tracerpid != 0); + break; + } + } + + FileIO::fclose(f); +} + +bool OSUtility::DebuggerPresent() +{ + return debuggerPresent; +} diff --git a/renderdoc/os/posix/apple/apple_process.cpp b/renderdoc/os/posix/apple/apple_process.cpp index 6d573117d..a8318156f 100644 --- a/renderdoc/os/posix/apple/apple_process.cpp +++ b/renderdoc/os/posix/apple/apple_process.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include "os/os_specific.h" char **GetCurrentEnvironment() @@ -133,3 +134,23 @@ int GetIdentPort(pid_t childPid) return 0; } + +void CacheDebuggerPresent() +{ +} + +// from https://developer.apple.com/library/mac/qa/qa1361/_index.html on how to detect the debugger +bool OSUtility::DebuggerPresent() +{ +// apple requires that this only be called in debug builds +#if defined(RELEASE) + return false; +#else + int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()}; + kinfo_proc info = {}; + size_t size = sizeof(info); + sysctl(mib, ARRAY_COUNT(mib), &info, &size, NULL, 0); + + return info.kp_proc.p_flag & P_TRACED; +#endif +} diff --git a/renderdoc/os/posix/linux/linux_process.cpp b/renderdoc/os/posix/linux/linux_process.cpp index 97356b727..27f4352dc 100644 --- a/renderdoc/os/posix/linux/linux_process.cpp +++ b/renderdoc/os/posix/linux/linux_process.cpp @@ -77,3 +77,46 @@ int GetIdentPort(pid_t childPid) return ret; } + +// because OSUtility::DebuggerPresent is called often we want it to be +// cheap. Opening and parsing a file would cause high overhead on each +// call, so instead we just cache it at startup. This fails in the case +// of attaching to processes +bool debuggerPresent = false; + +void CacheDebuggerPresent() +{ + FILE *f = FileIO::fopen("/proc/self/status", "r"); + + if(f == NULL) + { + RDCWARN("Couldn't open /proc/self/status"); + return; + } + + // read through the proc file to check for TracerPid + while(!feof(f)) + { + const size_t sz = 512; + char line[sz]; + line[sz - 1] = 0; + fgets(line, sz - 1, f); + + int tracerpid = 0; + int num = sscanf(line, "TracerPid: %d", &tracerpid); + + // found TracerPid line + if(num == 1) + { + debuggerPresent = (tracerpid != 0); + break; + } + } + + FileIO::fclose(f); +} + +bool OSUtility::DebuggerPresent() +{ + return debuggerPresent; +} diff --git a/renderdoc/os/posix/posix_specific.h b/renderdoc/os/posix/posix_specific.h index bf8d3a637..cc618d521 100644 --- a/renderdoc/os/posix/posix_specific.h +++ b/renderdoc/os/posix/posix_specific.h @@ -46,10 +46,7 @@ inline void DebugBreak() { raise(SIGTRAP); } -inline bool DebuggerPresent() -{ - return true; -} +bool DebuggerPresent(); void WriteOutput(int channel, const char *str); }; diff --git a/renderdoc/os/posix/posix_threading.cpp b/renderdoc/os/posix/posix_threading.cpp index de37dbc10..cfa1dd696 100644 --- a/renderdoc/os/posix/posix_threading.cpp +++ b/renderdoc/os/posix/posix_threading.cpp @@ -26,6 +26,8 @@ #include #include "os/os_specific.h" +void CacheDebuggerPresent(); + uint64_t Timing::GetUnixTimestamp() { return (uint64_t)time(NULL); @@ -128,6 +130,8 @@ void Init() int err = pthread_key_create(&OSTLSHandle, NULL); if(err != 0) RDCFATAL("Can't allocate OS TLS slot"); + + CacheDebuggerPresent(); } void Shutdown()