QProcess/Unix: add a flag to disable core dumps
[ChangeLog][QtCore][QProcess] Added UnixProcessFlag::DisableCoreDumps. Change-Id: I8c763c4e520fe9347856fffd457b5082696826d3 Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de> Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
This commit is contained in:
parent
38caabed3f
commit
9df6e8ad3b
@ -896,6 +896,16 @@ void QProcessPrivate::Channel::clear()
|
|||||||
if QProcess will actually use \c{vfork(2)} and if \c{vfork(2)} is
|
if QProcess will actually use \c{vfork(2)} and if \c{vfork(2)} is
|
||||||
different from standard \c{fork(2)}.
|
different from standard \c{fork(2)}.
|
||||||
|
|
||||||
|
\value [since 6.9] DisableCoreDumps Requests that QProcess disable core
|
||||||
|
dumps in the child process. This is useful if the executable being
|
||||||
|
run is likely to crash but users and maintainers are going to be
|
||||||
|
uninterested in generating bug reports for those conditions (for
|
||||||
|
example, the executable is a test process). This setting does not
|
||||||
|
affect the exitStatus() of the crashed process. It is implemented
|
||||||
|
by setting the core dump size resource soft limit to zero, meaning
|
||||||
|
the application can still reverse this change by raising it to a
|
||||||
|
value up to the hard limit.
|
||||||
|
|
||||||
\sa setUnixProcessParameters(), unixProcessParameters()
|
\sa setUnixProcessParameters(), unixProcessParameters()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -191,6 +191,7 @@ public:
|
|||||||
CreateNewSession = 0x0040, // like POSIX_SPAWN_SETSID
|
CreateNewSession = 0x0040, // like POSIX_SPAWN_SETSID
|
||||||
DisconnectControllingTerminal = 0x0080,
|
DisconnectControllingTerminal = 0x0080,
|
||||||
ResetIds = 0x0100, // like POSIX_SPAWN_RESETIDS
|
ResetIds = 0x0100, // like POSIX_SPAWN_RESETIDS
|
||||||
|
DisableCoreDumps = 0x0200,
|
||||||
};
|
};
|
||||||
Q_DECLARE_FLAGS(UnixProcessFlags, UnixProcessFlag)
|
Q_DECLARE_FLAGS(UnixProcessFlags, UnixProcessFlag)
|
||||||
struct UnixProcessParameters
|
struct UnixProcessParameters
|
||||||
|
@ -885,6 +885,15 @@ static const char *applyProcessParameters(const QProcess::UnixProcessParameters
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Disable core dumps near the end. This isn't expected to fail.
|
||||||
|
if (struct rlimit lim; getrlimit(RLIMIT_CORE, &lim) == 0 && lim.rlim_cur) {
|
||||||
|
// We'll leave rlim_max untouched, so the child can set it back if it
|
||||||
|
// wants to. We don't expect setrlimit() to fail, so we ignore its
|
||||||
|
// return value.
|
||||||
|
lim.rlim_cur = 0;
|
||||||
|
(void) setrlimit(RLIMIT_CORE, &lim);
|
||||||
|
}
|
||||||
|
|
||||||
// Apply UID and GID parameters last. This isn't expected to fail either:
|
// Apply UID and GID parameters last. This isn't expected to fail either:
|
||||||
// either we're trying to impersonate what we already are, or we're EUID or
|
// either we're trying to impersonate what we already are, or we're EUID or
|
||||||
// EGID root, in which case we are allowed to do this.
|
// EGID root, in which case we are allowed to do this.
|
||||||
|
@ -96,6 +96,18 @@ int main(int argc, char **argv)
|
|||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cmd == "no-coredumps") {
|
||||||
|
struct rlimit corelimit;
|
||||||
|
if (getrlimit(RLIMIT_CORE, &corelimit) != 0) {
|
||||||
|
// this shouldn't happen, so just assume it worked
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
if (corelimit.rlim_cur == 0)
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
fprintf(stderr, "rlim_cur = %lx\n", (unsigned long)corelimit.rlim_cur);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
if (cmd == "setsid") {
|
if (cmd == "setsid") {
|
||||||
pid_t pgid = getpgrp();
|
pid_t pgid = getpgrp();
|
||||||
if (pgid == getpid())
|
if (pgid == getpid())
|
||||||
|
@ -1774,6 +1774,7 @@ void tst_QProcess::unixProcessParameters_data()
|
|||||||
addRow("file-descriptors", P::CloseFileDescriptors);
|
addRow("file-descriptors", P::CloseFileDescriptors);
|
||||||
addRow("setsid", P::CreateNewSession);
|
addRow("setsid", P::CreateNewSession);
|
||||||
addRow("reset-ids", P::ResetIds);
|
addRow("reset-ids", P::ResetIds);
|
||||||
|
addRow("no-coredumps", P::DisableCoreDumps);
|
||||||
|
|
||||||
// On FreeBSD, we need to be session leader to disconnect from the CTTY
|
// On FreeBSD, we need to be session leader to disconnect from the CTTY
|
||||||
addRow("noctty", P::DisconnectControllingTerminal | P::CreateNewSession);
|
addRow("noctty", P::DisconnectControllingTerminal | P::CreateNewSession);
|
||||||
@ -1788,6 +1789,7 @@ void tst_QProcess::unixProcessParameters()
|
|||||||
struct Scope {
|
struct Scope {
|
||||||
int devnull;
|
int devnull;
|
||||||
struct sigaction old_sigusr1, old_sigpipe;
|
struct sigaction old_sigusr1, old_sigpipe;
|
||||||
|
struct rlimit old_corelimit = {};
|
||||||
Scope()
|
Scope()
|
||||||
{
|
{
|
||||||
int fd = open("/dev/null", O_RDONLY);
|
int fd = open("/dev/null", O_RDONLY);
|
||||||
@ -1806,6 +1808,13 @@ void tst_QProcess::unixProcessParameters()
|
|||||||
sigset_t *set = &act.sa_mask; // reuse this sigset_t
|
sigset_t *set = &act.sa_mask; // reuse this sigset_t
|
||||||
sigaddset(set, SIGUSR2);
|
sigaddset(set, SIGUSR2);
|
||||||
sigprocmask(SIG_BLOCK, set, nullptr);
|
sigprocmask(SIG_BLOCK, set, nullptr);
|
||||||
|
|
||||||
|
if (getrlimit(RLIMIT_CORE, &old_corelimit) == 0 && old_corelimit.rlim_max) {
|
||||||
|
struct rlimit new_corelimit = old_corelimit;
|
||||||
|
new_corelimit.rlim_cur = new_corelimit.rlim_max;
|
||||||
|
if (setrlimit(RLIMIT_CORE, &new_corelimit) != 0)
|
||||||
|
old_corelimit = {};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
~Scope()
|
~Scope()
|
||||||
{
|
{
|
||||||
@ -1822,6 +1831,9 @@ void tst_QProcess::unixProcessParameters()
|
|||||||
sigset_t *set = &old_sigusr1.sa_mask; // reuse this sigset_t
|
sigset_t *set = &old_sigusr1.sa_mask; // reuse this sigset_t
|
||||||
sigaddset(set, SIGUSR2);
|
sigaddset(set, SIGUSR2);
|
||||||
sigprocmask(SIG_BLOCK, set, nullptr);
|
sigprocmask(SIG_BLOCK, set, nullptr);
|
||||||
|
|
||||||
|
if (old_corelimit.rlim_max)
|
||||||
|
setrlimit(RLIMIT_CORE, &old_corelimit);
|
||||||
}
|
}
|
||||||
} scope;
|
} scope;
|
||||||
|
|
||||||
@ -1837,6 +1849,11 @@ void tst_QProcess::unixProcessParameters()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (params.flags & QProcess::UnixProcessFlag::DisableCoreDumps
|
||||||
|
&& scope.old_corelimit.rlim_max == 0) {
|
||||||
|
QSKIP("Cannot raise the core size limit (hard limit is set to zero)");
|
||||||
|
}
|
||||||
|
|
||||||
QProcess process;
|
QProcess process;
|
||||||
process.setUnixProcessParameters(params);
|
process.setUnixProcessParameters(params);
|
||||||
process.setStandardInputFile(QProcess::nullDevice()); // so we can't mess with SIGPIPE
|
process.setStandardInputFile(QProcess::nullDevice()); // so we can't mess with SIGPIPE
|
||||||
|
Loading…
x
Reference in New Issue
Block a user