1349 #if !defined(QT_NO_QOBJECT) 1350 #include "private/qobject_p.h" 1367 void QtSharedPointer::ExternalRefCountData::setQObjectShared(
const QObject *obj,
bool)
1373 qFatal(
"QSharedPointer: pointer %p already has reference counting", obj);
1380 QtSharedPointer::ExternalRefCountData *QtSharedPointer::ExternalRefCountData::getAndRef(
const QObject *obj)
1384 Q_ASSERT_X(!d->
wasDeleted,
"QWeakPointer",
"Detected QWeakPointer creation in a QObject being deleted");
1388 that->weakref.ref();
1410 # ifdef QT_SHARED_POINTER_BACKTRACE_SUPPORT 1411 # if defined(__GLIBC__) && (__GLIBC__ >= 2) && !defined(__UCLIBC__) && !defined(QT_LINUXBASE) 1412 # define BACKTRACE_SUPPORTED 1413 # elif defined(Q_OS_MACX) 1414 # define BACKTRACE_SUPPORTED 1418 # if defined(BACKTRACE_SUPPORTED) 1419 # include <sys/types.h> 1420 # include <execinfo.h> 1422 # include <unistd.h> 1423 # include <sys/wait.h> 1427 static inline QByteArray saveBacktrace() __attribute__((always_inline));
1430 static const int maxFrames = 32;
1433 stacktrace.
resize(
sizeof(
void*) * maxFrames);
1434 int stack_size = backtrace((
void**)stacktrace.
data(), maxFrames);
1435 stacktrace.
resize(
sizeof(
void*) * stack_size);
1440 static void printBacktrace(
QByteArray stacktrace)
1442 void *
const *stack = (
void *
const *)stacktrace.
constData();
1443 int stack_size = stacktrace.
size() /
sizeof(
void*);
1444 char **stack_symbols = backtrace_symbols(stack, stack_size);
1448 if (pipe(filter) != -1)
1452 dup2(fileno(stderr), fileno(stdout));
1453 dup2(filter[0], fileno(stdin));
1456 execlp(
"c++filt",
"c++filt",
"-n", NULL);
1459 execl(
"/bin/cat",
"/bin/cat", NULL);
1471 output =
fdopen(filter[1],
"w");
1474 fprintf(stderr,
"Backtrace of the first creation (most recent frame first):\n");
1475 for (
int i = 0; i < stack_size; ++i) {
1476 if (strlen(stack_symbols[i]))
1477 fprintf(output,
"#%-2d %s\n", i, stack_symbols[i]);
1479 fprintf(output,
"#%-2d %p\n", i, stack[i]);
1484 waitpid(child, 0, 0);
1490 # endif // BACKTRACE_SUPPORTED 1495 const volatile void *pointer;
1496 # ifdef BACKTRACE_SUPPORTED 1553 void QtSharedPointer::internalSafetyCheckAdd2(
const void *d_ptr,
const volatile void *
ptr)
1556 KnownPointers *
const kp = knownPointers();
1561 Q_ASSERT(!kp->dPointers.contains(d_ptr));
1565 const void *other_d_ptr = kp->dataPointers.value(ptr, 0);
1567 # ifdef BACKTRACE_SUPPORTED 1568 printBacktrace(knownPointers()->dPointers.value(other_d_ptr).backtrace);
1570 qFatal(
"QSharedPointer: internal self-check failed: pointer %p was already tracked " 1571 "by another QSharedPointer object %p", ptr, other_d_ptr);
1576 # ifdef BACKTRACE_SUPPORTED 1577 data.backtrace = saveBacktrace();
1580 kp->dPointers.insert(d_ptr, data);
1581 kp->dataPointers.insert(ptr, d_ptr);
1582 Q_ASSERT(kp->dPointers.size() == kp->dataPointers.size());
1588 void QtSharedPointer::internalSafetyCheckRemove2(
const void *d_ptr)
1590 KnownPointers *
const kp = knownPointers();
1597 if (it == kp->dPointers.end()) {
1598 qFatal(
"QSharedPointer: internal self-check inconsistency: pointer %p was not tracked. " 1599 "To use QT_SHAREDPOINTER_TRACK_POINTERS, you have to enable it throughout " 1600 "in your code.", d_ptr);
1604 Q_ASSERT(it2 != kp->dataPointers.end());
1609 kp->dataPointers.erase(it2);
1610 kp->dPointers.erase(it);
1611 Q_ASSERT(kp->dPointers.size() == kp->dataPointers.size());
1620 # ifdef QT_BUILD_INTERNAL 1621 KnownPointers *
const kp = knownPointers();
1622 Q_ASSERT_X(kp,
"internalSafetyCheckSelfCheck()",
"Called after global statics deletion!");
1624 if (kp->dPointers.size() != kp->dataPointers.size())
1625 qFatal(
"Internal consistency error: the number of pointers is not equal!");
1627 if (!kp->dPointers.isEmpty())
1628 qFatal(
"Pointer cleaning failed: %d entries remaining", kp->dPointers.size());
#define QT_END_NAMESPACE
This macro expands to.
The QMutex class provides access serialization between threads.
char * data()
Returns a pointer to the data stored in the byte array.
#define it(className, varName)
The QByteArray class provides an array of bytes.
The QHash class is a template class that provides a hash-table-based dictionary.
Q_AUTOTEST_EXPORT void internalSafetyCheckCleanCheck()
The QObject class is the base class of all Qt objects.
static QObjectPrivate * get(QObject *o)
Q_CORE_EXPORT void internalSafetyCheckRemove(const volatile void *)
bool testAndSetRelease(T *expectedValue, T *newValue)
Atomic test-and-set.
#define QT_BEGIN_NAMESPACE
This macro expands to.
#define Q_GLOBAL_STATIC(TYPE, NAME)
Declares a global static variable with the given type and name.
static const char * data(const QByteArray &arr)
const T * ptr(const T &t)
const char * constData() const
Returns a pointer to the data stored in the byte array.
Q_CORE_EXPORT void qFatal(const char *,...)
#define Q_ASSERT_X(cond, where, what)
The QMutexLocker class is a convenience class that simplifies locking and unlocking mutexes...
void resize(int size)
Sets the size of the byte array to size bytes.
The QHash::iterator class provides an STL-style non-const iterator for QHash and QMultiHash.
static QReadWriteLock lock
#define Q_AUTOTEST_EXPORT
QFuture< void > filter(Sequence &sequence, FilterFunction filterFunction)
int size() const
Returns the number of bytes in this byte array.
#define QT_USE_NAMESPACE
This macro expands to using QT_NAMESPACE if QT_NAMESPACE is defined and nothing otherwise.
Q_CORE_EXPORT void internalSafetyCheckAdd(const volatile void *)
QAtomicPointer< QtSharedPointer::ExternalRefCountData > sharedRefcount