Название: Разное поведение программы при отладке и запуске в обычном режиме
Отправлено: Fregloin от Март 25, 2016, 13:30
Привет. Столкнулся с таким странным поведением моей программы. Если ее запустить обычно, то в консоль выводится сообщение qDebug, которое происходит, если два значения не равны. Если я ставлю точку останова на это место и запускаю отладку, то приложение работает нормально, но на точке останова оно не останавливается и соответственно сообщение в консоль не выдается (получается что оба значения равны). В чем может быть причина? Приложение собрано в конфигурации DEBUG.
Название: Re: Разное поведение программы при отладке и запуске в обычном режиме
Отправлено: Bepec от Март 25, 2016, 13:34
Мало данных что за значения и как они меняются. Но в целом при обычной запуске всё происходит в разы быстрее, а при дебаге соответственно медленнее. Вполне возможно ваше значение в дебаге успевает измениться на правильное.
Название: Re: Разное поведение программы при отладке и запуске в обычном режиме
Отправлено: GreatSnake от Март 25, 2016, 13:55
Или забыл про-инициализить значение.
Название: Re: Разное поведение программы при отладке и запуске в обычном режиме
Отправлено: ssoft от Март 26, 2016, 20:59
Или забыл про-инициализить значение.
Это наиболее вероятный вариант. В отладке часто не проинициализированные значения инициализированы нулями для нужд самого отладчика, в релизе нет - в переменных то, что в памяти осталось.
Название: Re: Разное поведение программы при отладке и запуске в обычном режиме
Отправлено: Fregloin от Март 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(); }
Название: Re: Разное поведение программы при отладке и запуске в обычном режиме
Отправлено: Igors от Март 31, 2016, 13:59
Самое интрересное, что синглтон живет в основном потоке, и по идее он должен блокировать закрытие программы пока не завершит свою работу в соответствующе функции release.
Т.е. Вы допускаете что может быть и "не по идее"? :) Наиболее вероятный вариант - кто-то опять его схватил (уже после или во время release)
|