1

I'm having a hard time figuring out what's causing this segfault. According to my research, it's related to some static variable in my code (see __tcf_0 in the stack trace below). The fact is, I have only one static variable in my code, which is the instance of a singleton class (see below).

This code seems correct to me, yet when the program terminates, a segfault is thrown in ~Logger() (line qDebug() << "Segfault";). The same thing happens when I try to delete a QTextStream* for example. However, printing out to the console using the standard cout works perfectly, as well as doing anything else using the standard library. It seems it only affects some Qt classes.

EDIT: it seems that the problem comes from the QTextStream class. Indeed, qDebug() uses it. Other classes which don't use it don't cause a segfault.

Here are the files and the stack trace:

main.cpp

#include <QCoreApplication>
#include "Logger.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    Logger::getInstance(); // Create Logger instance

    return a.exec();
}

Singleton.h

#ifndef SINGLETON_H
#define SINGLETON_H

template <class T>
class Singleton
{
protected:
    Singleton() = default;
    ~Singleton() = default;


public:
    static T &getInstance()
    {
        static T instance; // <----- static variable here
        return instance;
    }
};

#endif // SINGLETON_H

Logger.h

#ifndef LOGGER_H
#define LOGGER_H

#include "Singleton.h"

class Logger : public Singleton<Logger>
{
    friend class Singleton<Logger>;

private:
    Logger();
    ~Logger();
};

#endif // LOGGER_H

Logger.cpp

#include "Logger.h"

#include <QDebug>
#include <iostream>

Logger::Logger() : Singleton<Logger>()
{
}

Logger::~Logger()
{
    std::cout << "It works" << std::endl;
    qDebug() << "Segfault"; // <----- segfault here
}

Stack trace

0   msvcrt!_msize   C:\Windows\syswow64\msvcrt.dll      0x75cff4fc  
1   ??          0x20d0ea8   
2   msvcrt!.dllonexit   C:\Windows\syswow64\msvcrt.dll      0x75cff52c  
3   (anonymous namespace)::Q_QGS_globalInstance::Holder::~Holder        47  0x6b971717  
4   ??          0xd8fc7add  
5   mingw_onexit    C:\Qt\Qt5.3.0\5.3\mingw482_32\bin\Qt5Cored.dll      0x6b9ae548  
6   atexit  C:\Qt\Qt5.3.0\5.3\mingw482_32\bin\Qt5Cored.dll      0x6b9ae5af  
7   (anonymous namespace)::Q_QGS_globalInstance::innerFunction      47  0x6b971779  
8   QGlobalStatic<QCoreGlobalData, (* (anonymous namespace)::Q_QGS_globalInstance::innerFunction), (* & (anonymous namespace)::Q_QGS_globalInstance::guard)>::operator()(void)      128 0x6b971917  
9   QCoreGlobalData::instance       63  0x6b9718f2  
10  QTextCodec::codecForLocale      680 0x6b97c475  
11  QTextStreamPrivate::reset       399 0x6b8ba6be  
12  QTextStreamPrivate::QTextStreamPrivate      330 0x6b8ba3ce  
13  QTextStream::QTextStream        954 0x6b8bb69b  
14  QDebug::Stream::Stream      66  0x6ba17d27  
15  QDebug::QDebug      78  0x6ba17dfa  
16  QMessageLogger::debug       359 0x6b78cd0e  
17  Logger::~Logger Logger.cpp  13  0x401700    
18  __tcf_0 Singleton.h 15  0x40168c    
19  msvcrt!isspace  C:\Windows\syswow64\msvcrt.dll      0x75cfc3e9  
20  msvcrt!_cexit   C:\Windows\syswow64\msvcrt.dll      0x75d037df  
21  ??              
Community
  • 1
  • 1
GuiTeK
  • 1,561
  • 5
  • 20
  • 39

1 Answers1

3

Reason is simple, QApplication gets destroyed before your singleton destruction, and qDebug needs QApplication object to get current text codec.

This is perfect example why singletons are problematic.

Change code in such way that singleton is cleared before QApplication object, or make it eternal (this may not solve problem completely sicnce some other object could use your singleton after QApplication was destroyed).

Marek R
  • 32,568
  • 6
  • 55
  • 140
  • Yes I was about to post the answer. I was still hesitating about why `QTextCodec::codecForLocale()` would return `NULL` but you confirm my hypothesis. Thank you. Indeed you're right, singletons are evil... I spent hours to figure this out. I've learned my lesson. – GuiTeK Aug 06 '14 at 21:21