summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2017-06-14 15:06:09 -0700
committerThiago Macieira <thiago.macieira@intel.com>2017-07-03 16:01:14 +0000
commit2f8a08f31b1bfdc18766bae4983d238ee1cf716c (patch)
treec170fd43f025e4ed739b8def834a048fdfd40865 /src/corelib
parent2b991efc476c7d50ee606dd4ddb7d15777bbfe8e (diff)
Make qt_check_pointer more OOM-safe
First, it can never return, so we can mark it Q_NORETURN and add an std::termianate at the end. Though if it did, we'd end up in a null- pointer dereference crash in the caller. Second, add Q_DECL_NOTHROW to it. It can't throw, but it terminates execution. This also prevents both puts and fprintf from escaping via pthread asynchronous cancellation on Linux/glibc. Third, don't use QMessageLogger, since that allocates memory and actually uses QString. If we really are in an OOM situation, then QString's failed allocation would recurse back into qt_check_pointer. We'd compound the OOM situation with a stack overflow... Change-Id: Ia53158e207a94bf49489fffd14c81c47971f4e82 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/global/qglobal.cpp17
-rw-r--r--src/corelib/global/qglobal.h2
2 files changed, 13 insertions, 6 deletions
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index 4f0110dca4..9b76c72c0d 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -3016,13 +3016,20 @@ QString QSysInfo::machineHostName()
If this macro is used outside a function, the behavior is undefined.
*/
-/*
- The Q_CHECK_PTR macro calls this function if an allocation check
- fails.
+/*!
+ \internal
+ The Q_CHECK_PTR macro calls this function if an allocation check
+ fails.
*/
-void qt_check_pointer(const char *n, int l)
+void qt_check_pointer(const char *n, int l) Q_DECL_NOTHROW
{
- QMessageLogger(n, l, nullptr).fatal("Out of memory");
+ // make separate printing calls so that the first one may flush;
+ // the second one could want to allocate memory (fputs prints a
+ // newline and stderr auto-flushes).
+ fputs("Out of memory", stderr);
+ fprintf(stderr, " in %s, line %d\n", n, l);
+
+ std::terminate();
}
/*
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index f2f28343c6..0c74ed4a3e 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -753,7 +753,7 @@ template <> class QStaticAssertFailure<true> {};
#define Q_STATIC_ASSERT_X(Condition, Message) Q_STATIC_ASSERT(Condition)
#endif
-Q_CORE_EXPORT void qt_check_pointer(const char *, int);
+Q_NORETURN Q_CORE_EXPORT void qt_check_pointer(const char *, int) Q_DECL_NOTHROW;
Q_CORE_EXPORT void qBadAlloc();
#ifdef QT_NO_EXCEPTIONS