Add support for breaking into debugger for Linux

Use Linux-specific /proc/$PID/status file to check whether we're being
debugged and a generic raise(SIGTRAP) to actually break into the debugger.
This commit is contained in:
Vadim Zeitlin 2016-02-05 14:56:20 +01:00 committed by Martin Hořeňovský
parent e3659cdddd
commit b634e592da
3 changed files with 33 additions and 0 deletions

View File

@ -35,6 +35,10 @@ namespace Catch{
#endif
#endif
#elif defined(CATCH_PLATFORM_LINUX)
#include <signal.h>
#define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { raise(SIGTRAP); }
#elif defined(_MSC_VER)
#define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { __debugbreak(); }
#elif defined(__MINGW32__)

View File

@ -61,6 +61,33 @@
}
} // namespace Catch
#elif defined(CATCH_PLATFORM_LINUX)
#include <fstream>
#include <string>
namespace Catch{
// The standard POSIX way of detecting a debugger is to attempt to
// ptrace() the process, but this needs to be done from a child and not
// this process itself to still allow attaching to this process later
// if wanted, so is rather heavy. Under Linux we have the PID of the
// "debugger" (which doesn't need to be gdb, of course, it could also
// be strace, for example) in /proc/$PID/status, so just get it from
// there instead.
bool isDebuggerActive(){
std::ifstream in("/proc/self/status");
for( std::string line; std::getline(in, line); ) {
static const int PREFIX_LEN = 11;
if( line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0 ) {
// We're traced if the PID is not 0 and no other PID starts
// with 0 digit, so it's enough to check for just a single
// character.
return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0';
}
}
return false;
}
} // namespace Catch
#elif defined(_MSC_VER)
extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
namespace Catch {

View File

@ -15,6 +15,8 @@
#define CATCH_PLATFORM_IPHONE
#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)
#define CATCH_PLATFORM_WINDOWS
#elif defined(linux) || defined(__linux) || defined(__linux__)
#define CATCH_PLATFORM_LINUX
#endif
#endif // TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED