diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2017-06-14 15:06:09 -0700 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2017-07-03 16:01:14 +0000 |
commit | 2f8a08f31b1bfdc18766bae4983d238ee1cf716c (patch) | |
tree | c170fd43f025e4ed739b8def834a048fdfd40865 /src/corelib/global/qglobal.cpp | |
parent | 2b991efc476c7d50ee606dd4ddb7d15777bbfe8e (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/global/qglobal.cpp')
-rw-r--r-- | src/corelib/global/qglobal.cpp | 17 |
1 files changed, 12 insertions, 5 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(); } /* |