Russian Qt Forum
Сентябрь 30, 2024, 22:22 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Разное поведение программы при отладке и запуске в обычном режиме  (Прочитано 4744 раз)
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« : Март 25, 2016, 13:30 »

Привет. Столкнулся с таким странным поведением моей программы. Если ее запустить обычно, то в консоль выводится сообщение qDebug, которое происходит, если два значения не равны.
Если я ставлю точку останова на это место и запускаю отладку, то приложение работает нормально, но на точке останова оно не останавливается и соответственно сообщение в консоль не выдается (получается что оба значения равны). В чем может быть причина? Приложение собрано в конфигурации DEBUG.
Записан
Bepec
Гость
« Ответ #1 : Март 25, 2016, 13:34 »

Мало данных что за значения и как они меняются.
Но в целом при обычной запуске всё происходит в разы быстрее, а при дебаге соответственно медленнее. Вполне возможно ваше значение в дебаге успевает измениться на правильное.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #2 : Март 25, 2016, 13:55 »

Или забыл про-инициализить значение.
Записан

Qt 5.11/4.8.7 (X11/Win)
ssoft
Программист
*****
Offline Offline

Сообщений: 582


Просмотр профиля
« Ответ #3 : Март 26, 2016, 20:59 »

Или забыл про-инициализить значение.
Это наиболее вероятный вариант. В отладке часто не проинициализированные значения инициализированы нулями для нужд самого отладчика, в релизе нет - в переменных то, что в памяти осталось.
Записан
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #4 : Март 31, 2016, 12:49 »

Выяснил проблему, но не знаю пока как решить.
Привожу код файла main.cpp.
Есть глобальный синглтон, доступный с любой точки программы. Проблема в том, что при отладке все успевает освободиться до завершения работы программы.
Если запустить без отладки, то ресурсы не успевают освободиться и программа закрывается. Если поставить паузу в пару секунд, то тогда сообщения на консоль доходят.
Код:
QApplication a(argc, argv);

    CGlobalObjectPool::instance(); //инициализация синглтона

    MainWindow w;
    w.startWork();
    w.show();
    int result = a.exec();

    CGlobalObjectPool::release(); //освобождение синглтона и его ресурсов

    QThread::sleep(2); //без этого не успевает вывестись в консоль сообщения об успешном освобождении ресурсов

    return result;
Самое интрересное, что синглтон живет в основном потоке, и по идее он должен блокировать закрытие программы пока не завершит свою работу в соответствующе функции release.

Вот код синглтона
Код:
class   CGlobalObject;
class   CGlobalObjectFactory;

class RAILCORESHARED_EXPORT CGlobalObjectPool : public QObject
{
    Q_OBJECT

    QMap<CInterfaceTag,CGlobalObjectFactory*>   p_factoryMap;
    QMap<CGlobalObjectFactory*,CGlobalObject*>  p_objectMap;

    explicit CGlobalObjectPool(QObject *parent = 0);

    void    finalize();
    void    deleteGlobalObjects();

    static  QPointer<CGlobalObjectPool> p_instance;

public:

    ~CGlobalObjectPool();

    static  CGlobalObjectPool   *  instance();

    void    registerGlobalObjectFactory(CGlobalObjectFactory * factory);
    void    unregisterGlobalObjectFactory(CGlobalObjectFactory * factory);
    QList<CGlobalObjectFactory*>    registeredFactories();
    QList<CGlobalObject*>           globalObjects();

    void    createGlobalObjects();
    void    intializeGlobalObjects();
    static  void    release();

public  slots:

    void    cleanup();
};
Код:
#include "cglobalobjectfactory.h"
#include "cglobalobject.h"
#include "cglobalobjectpool.h"

QPointer<CGlobalObjectPool> CGlobalObjectPool::p_instance;

CGlobalObjectPool::CGlobalObjectPool(QObject *parent) :
    QObject(parent)
{
    qDebug("create CGlobalObjectPool");
}

CGlobalObjectPool *CGlobalObjectPool::instance()
{
    return  p_instance.isNull()?p_instance = new CGlobalObjectPool():p_instance;
}

CGlobalObjectPool::~CGlobalObjectPool()
{
    qDebug("destroy CGlobalObjectPool");
}

void CGlobalObjectPool::registerGlobalObjectFactory(CGlobalObjectFactory * factory)
{
    if(factory)
    {
        CInterfaceTag   t(factory->tag());
        CGlobalObjectFactory * prevObject = instance()->p_factoryMap.value(t);
        if(prevObject)
        {
            qWarning("Global object with tag '%s' already registered in GO pool, ignoring",qPrintable(t.toString()));
            return;
        }
        //qDebug("Registering global object %s",qPrintable(factory->tag().toString()));
        p_factoryMap[t] = factory;
        p_objectMap[factory] = nullptr;
    }
}

void CGlobalObjectPool::unregisterGlobalObjectFactory(CGlobalObjectFactory * factory)
{
    if(factory) {
        p_factoryMap.remove(factory->tag());
        p_objectMap.remove(factory);
    }
}

QList<CGlobalObjectFactory *> CGlobalObjectPool::registeredFactories()
{
    return  instance()->p_factoryMap.values();
}

QList<CGlobalObject *> CGlobalObjectPool::globalObjects()
{
    return  p_objectMap.values();
}

void CGlobalObjectPool::createGlobalObjects()
{
    for(QMap<CGlobalObjectFactory*,CGlobalObject*>::iterator it=p_objectMap.begin();it!=p_objectMap.end();it++) {
        if(!it.value()) {
            qDebug("create global object for %s",qPrintable(it.key()->tag().toString()));
            it.key()->createGlobalObject();
            it.value() = it.key()->globalObject();
            //qDebug("ok");
        }
    }
}

void CGlobalObjectPool::intializeGlobalObjects()
{
    for(QMap<CGlobalObjectFactory*,CGlobalObject*>::iterator it=p_objectMap.begin();it!=p_objectMap.end();it++) {
        if(it.value()) {
            it.value()->commitInitialization();
        }
    }
}

void CGlobalObjectPool::finalize()
{
    qDebug("finalizing %d global objects ...", p_objectMap.size());

    QMapIterator<CGlobalObjectFactory*,CGlobalObject*>  mapIt(p_objectMap);
    while(mapIt.hasNext()) {
        mapIt.next();

        qDebug("try to finalize %s",qPrintable(mapIt.key()->tag().toString()));
        if(mapIt.value()) {
            qDebug("finalize global object for %s",qPrintable(mapIt.key()->tag().toString()));
            //mapIt.value()->finalize();
            qDebug("ok");
        } else {
            qDebug("global object is NULL!!");
        }
    }

    qDebug("finalizing done ...");
}

void CGlobalObjectPool::deleteGlobalObjects()
{
    qDebug("destroying ...");
    for(QMap<CGlobalObjectFactory*,CGlobalObject*>::iterator it=p_objectMap.begin();it!=p_objectMap.end();it++) {
        if(it.value()) {
            qDebug("destroy global object for %s",qPrintable(it.key()->tag().toString()));
            it.key()->destroyGlobalObject();
            it.value() = nullptr;
            qDebug("ok");
        }
    }
    qDebug("destroy done ...");
}

void CGlobalObjectPool::release()
{
    if(!p_instance.isNull()) {
        p_instance->finalize();
        p_instance->deleteGlobalObjects();
        qDebug("release done");
        delete  p_instance.data();
    }
}

void CGlobalObjectPool::cleanup()
{
    release();
}
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Март 31, 2016, 13:59 »

Самое интрересное, что синглтон живет в основном потоке, и по идее он должен блокировать закрытие программы пока не завершит свою работу в соответствующе функции release.
Т.е. Вы допускаете что может быть и "не по идее"?  Улыбающийся Наиболее вероятный вариант - кто-то опять его схватил (уже после или во время release)
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.055 секунд. Запросов: 23.