Fix debugging of terminal applications on Linux

On modern linux distributions (Ubuntu >= 10.10, Debian >= Wheezy),
trying to debug a terminal application fails, with
"ptrace: Operation not permitted".

In order to allow the debugger to attach to the created process, the
process itself needs to inform the kernel of the debugging process.

Task-number: QTCREATORBUG-3509
Change-Id: I68670426fad18cbe3b7cce9d57633e58e631e025
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@digia.com>
Reviewed-by: hjk <hjk121@nokiamail.com>
This commit is contained in:
Orgad Shaneh
2014-05-14 11:26:20 +03:00
committed by Orgad Shaneh
parent 4f62d65174
commit a075bad97f
2 changed files with 13 additions and 0 deletions

View File

@@ -162,6 +162,7 @@ bool ConsoleProcess::start(const QString &program, const QString &args)
<< msgPromptToClose() << msgPromptToClose()
<< workingDirectory() << workingDirectory()
<< (d->m_tempFile ? d->m_tempFile->fileName() : QString()) << (d->m_tempFile ? d->m_tempFile->fileName() : QString())
<< QString::number(getpid())
<< pcmd << pargs.toUnixArgs(); << pcmd << pargs.toUnixArgs();
QString xterm = allArgs.takeFirst(); QString xterm = allArgs.takeFirst();

View File

@@ -47,6 +47,16 @@
#include <errno.h> #include <errno.h>
#include <assert.h> #include <assert.h>
#ifdef __linux__
#include <sys/prctl.h>
// Enable compilation with older header that doesn't contain this constant
// for running on newer libraries that do support it
#ifndef PR_SET_PTRACER
#define PR_SET_PTRACER 0x59616d61
#endif
#endif
/* For OpenBSD */ /* For OpenBSD */
#ifndef EPROTO #ifndef EPROTO
# define EPROTO EINVAL # define EPROTO EINVAL
@@ -90,6 +100,7 @@ enum {
ArgMsg, ArgMsg,
ArgDir, ArgDir,
ArgEnv, ArgEnv,
ArgPid,
ArgExe ArgExe
}; };
@@ -289,6 +300,7 @@ int main(int argc, char *argv[])
/* Get a SIGTRAP after exec() has loaded the new program. */ /* Get a SIGTRAP after exec() has loaded the new program. */
#ifdef __linux__ #ifdef __linux__
prctl(PR_SET_PTRACER, atoi(argv[ArgPid]));
ptrace(PTRACE_TRACEME); ptrace(PTRACE_TRACEME);
#else #else
ptrace(PT_TRACE_ME, 0, 0, 0); ptrace(PT_TRACE_ME, 0, 0, 0);