4#include <private/qv4stacklimits_p.h>
5#include <private/qobject_p.h>
6#include <private/qthread_p.h>
8#include <QtCore/qfile.h>
15# include <QtCore/qt_windows.h>
16#elif defined(Q_OS_FREEBSD_KERNEL) || defined(Q_OS_OPENBSD)
17# include <pthread_np.h>
18#elif defined(Q_OS_LINUX)
20# include <sys/resource.h>
21# include <sys/syscall.h>
22# if defined(__GLIBC__) && QT_CONFIG(dlopen)
25#elif defined(Q_OS_DARWIN)
26# include <sys/resource.h>
27#elif defined(Q_OS_QNX)
29# include <sys/procfs.h>
30# include <sys/types.h>
32#elif defined(Q_OS_INTEGRITY)
33# include <INTEGRITY.h>
34#elif defined(Q_OS_VXWORKS)
36#elif defined(Q_OS_WASM)
37# include <emscripten/stack.h>
51#elif defined(Q_OS_MACOS)
54#elif defined(Q_OS_ANDROID)
58#elif defined(Q_OS_LINUX)
62#elif defined(Q_OS_QNX)
77template<
typename Size>
80#if Q_STACK_GROWTH_DIRECTION > 0
87template<
typename Size>
90#if Q_STACK_GROWTH_DIRECTION > 0
106#if defined(Q_OS_DARWIN) || defined(Q_OS_LINUX)
113static qsizetype getMainStackSizeFromRlimit()
116 return (getrlimit(RLIMIT_STACK, &
limit) == 0 &&
limit.rlim_cur != RLIM_INFINITY)
122#if defined(Q_OS_INTEGRITY)
126 Address stackLow, stackHigh;
127 CheckSuccess(GetTaskStackLimits(CurrentTask(), &stackLow, &stackHigh));
128# if Q_STACK_GROWTH_DIRECTION < 0
135#elif defined(Q_OS_DARWIN)
139 pthread_t thread = pthread_self();
141 pthread_get_stackaddr_np(thread),
143 ? getMainStackSizeFromRlimit()
144 :
qsizetype(pthread_get_stacksize_np(thread)));
147#elif defined(Q_OS_WIN)
158 PNT_TIB64 pTib =
reinterpret_cast<PNT_TIB64
>(NtCurrentTeb());
160 PNT_TIB pTib =
reinterpret_cast<PNT_TIB
>(NtCurrentTeb());
165 quint8 *stackBase =
reinterpret_cast<quint8 *
>(pTib->StackBase);
169 MEMORY_BASIC_INFORMATION mbi = {};
170 if (!VirtualQuery(&mbi, &mbi,
sizeof(mbi)))
171 qFatal(
"Could not retrieve memory information for stack.");
173 quint8 *stackLimit =
reinterpret_cast<quint8 *
>(mbi.AllocationBase);
177#elif defined(Q_OS_OPENBSD)
192 rc = pthread_stackseg_np(pthread_self, &ss);
193#if Q_STACK_GROWTH_DIRECTION < 0
200#elif defined(Q_OS_QNX)
204 const auto tid = pthread_self();
205 procfs_status status;
208 const int fd =
open(
"/proc/self/ctl", O_RDONLY);
210 qFatal(
"Could not open /proc/self/ctl");
213 if (devctl(
fd, DCMD_PROC_TIDSTATUS, &status,
sizeof(status), 0) != EOK)
214 qFatal(
"Could not query thread status for current thread");
216 if (status.tid != tid)
217 qFatal(
"Thread status query returned garbage");
219#if Q_STACK_GROWTH_DIRECTION < 0
228#elif defined(Q_OS_WASM)
232 const uintptr_t
base = emscripten_stack_get_base();
233 const uintptr_t
end = emscripten_stack_get_end();
238#elif defined(Q_OS_VXWORKS)
242 TASK_DESC taskDescription;
243 taskInfoGet(taskIdSelf(), &taskDescription);
253 pthread_t thread = pthread_self();
254 pthread_attr_t sattr;
255# if defined(PTHREAD_NP_H) || defined(_PTHREAD_NP_H_) || defined(Q_OS_NETBSD)
256 pthread_attr_init(&sattr);
257 pthread_attr_get_np(thread, &sattr);
259 pthread_getattr_np(thread, &sattr);
266 int rc = pthread_attr_getstack(&sattr, &stackBase, ®ionSize);
267 pthread_attr_destroy(&sattr);
270 qFatal(
"Cannot find stack base");
272# if Q_STACK_GROWTH_DIRECTION < 0
279#if defined(Q_OS_LINUX)
281static void *stackBaseFromLibc()
283#if defined(__GLIBC__) && QT_CONFIG(dlopen)
284 void **libcStackEnd =
static_cast<void **
>(dlsym(RTLD_DEFAULT,
"__libc_stack_end"));
287 if (
void *stackBase = *libcStackEnd)
298static StackSegment stackSegmentFromProc()
320 if (!
ok ||
base > stackAddr)
339 if (getpid() !=
static_cast<pid_t
>(syscall(SYS_gettid)))
346 const qsizetype stackSize = getMainStackSizeFromRlimit();
351 if (
void *
base = stackBaseFromLibc())
356 const StackSegment
segment = stackSegmentFromProc();
358# if Q_STACK_GROWTH_DIRECTION > 0
359 void *stackBase =
reinterpret_cast<void *
>(
segment.base);
361 void *stackBase =
reinterpret_cast<void *
>(
segment.limit);
qsizetype indexOf(QLatin1StringView s, qsizetype from=0, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
QString sliced(qsizetype pos) const &
qulonglong toULongLong(bool *ok=nullptr, int base=10) const
Returns the string converted to an {unsigned long long} using base base, which is 10 by default and m...
Combined button and popup list for selecting options.
static void * incrementStackPointer(void *base, Size amount)
static void * decrementStackPointer(void *base, Size amount)
static StackProperties createStackProperties(void *base, qsizetype size=PlatformStackSize)
StackProperties stackProperties()
StackProperties stackPropertiesGeneric(qsizetype stackSize=0)
#define QT_WARNING_DISABLE_GCC(text)
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLuint GLenum GLsizei length
QScopeGuard< typename std::decay< F >::type > qScopeGuard(F &&f)
[qScopeGuard]
#define QStringLiteral(str)
#define Q_STACK_GROWTH_DIRECTION
file open(QIODevice::ReadOnly)