QProcess/Unix: detect ASan and TSan dynamically
Fixes: QTBUG-117533 Fixes: QTBUG-117954 Task-number: QTBUG-104493 Pick-to: 6.6 Change-Id: I09c3950e719e4b259bc7fffd1793ee472c5d5a9a Reviewed-by: Ahmad Samir <a.samirh78@gmail.com> (cherry picked from commit 7c4e271fe73f4775d308d5851c07bc21cdd08570) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
49bfdf7e67
commit
9962441bfd
@ -245,6 +245,7 @@ struct QChildProcess
|
|||||||
CharPointerList envp;
|
CharPointerList envp;
|
||||||
sigset_t oldsigset;
|
sigset_t oldsigset;
|
||||||
int workingDirectory = -2;
|
int workingDirectory = -2;
|
||||||
|
bool isUsingVfork = usingVfork();
|
||||||
|
|
||||||
bool ok() const
|
bool ok() const
|
||||||
{
|
{
|
||||||
@ -290,7 +291,7 @@ struct QChildProcess
|
|||||||
// We only block Unix signals if we're using vfork(), to avoid a
|
// We only block Unix signals if we're using vfork(), to avoid a
|
||||||
// changing behavior to the user's modifier and because in some OSes
|
// changing behavior to the user's modifier and because in some OSes
|
||||||
// this action would block crashing signals too.
|
// this action would block crashing signals too.
|
||||||
if (usingVfork()) {
|
if (isUsingVfork) {
|
||||||
sigset_t emptyset;
|
sigset_t emptyset;
|
||||||
sigfillset(&emptyset);
|
sigfillset(&emptyset);
|
||||||
pthread_sigmask(SIG_SETMASK, &emptyset, &oldsigset);
|
pthread_sigmask(SIG_SETMASK, &emptyset, &oldsigset);
|
||||||
@ -299,7 +300,7 @@ struct QChildProcess
|
|||||||
|
|
||||||
void restoreSignalMask() const noexcept
|
void restoreSignalMask() const noexcept
|
||||||
{
|
{
|
||||||
if (usingVfork())
|
if (isUsingVfork)
|
||||||
pthread_sigmask(SIG_SETMASK, &oldsigset, nullptr);
|
pthread_sigmask(SIG_SETMASK, &oldsigset, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,7 +309,7 @@ struct QChildProcess
|
|||||||
template <typename Lambda> int doFork(Lambda &&childLambda)
|
template <typename Lambda> int doFork(Lambda &&childLambda)
|
||||||
{
|
{
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
if (usingVfork()) {
|
if (isUsingVfork) {
|
||||||
QT_IGNORE_DEPRECATIONS(pid = vfork();)
|
QT_IGNORE_DEPRECATIONS(pid = vfork();)
|
||||||
} else {
|
} else {
|
||||||
pid = fork();
|
pid = fork();
|
||||||
@ -320,7 +321,7 @@ struct QChildProcess
|
|||||||
|
|
||||||
int startChild(pid_t *pid)
|
int startChild(pid_t *pid)
|
||||||
{
|
{
|
||||||
int ffdflags = FFD_CLOEXEC | (usingVfork() ? 0 : FFD_USE_FORK);
|
int ffdflags = FFD_CLOEXEC | (isUsingVfork ? 0 : FFD_USE_FORK);
|
||||||
return ::vforkfd(ffdflags, pid, &QChildProcess::startProcess, this);
|
return ::vforkfd(ffdflags, pid, &QChildProcess::startProcess, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -616,6 +617,10 @@ inline QString QChildProcess::resolveExecutable(const QString &program)
|
|||||||
return program;
|
return program;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
__attribute__((weak)) pid_t __interceptor_vfork();
|
||||||
|
}
|
||||||
|
|
||||||
inline bool globalUsingVfork() noexcept
|
inline bool globalUsingVfork() noexcept
|
||||||
{
|
{
|
||||||
#if defined(__SANITIZE_ADDRESS__) || __has_feature(address_sanitizer)
|
#if defined(__SANITIZE_ADDRESS__) || __has_feature(address_sanitizer)
|
||||||
@ -638,7 +643,10 @@ inline bool globalUsingVfork() noexcept
|
|||||||
return false;
|
return false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return true;
|
// Dynamically detect whether libasan or libtsan are loaded into the
|
||||||
|
// process' memory. We need this because the user's code may be compiled
|
||||||
|
// with ASan or TSan, but not Qt.
|
||||||
|
return __interceptor_vfork == nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool QChildProcess::usingVfork() const noexcept
|
inline bool QChildProcess::usingVfork() const noexcept
|
||||||
|
Loading…
x
Reference in New Issue
Block a user