Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > [QT4] подение при вызове exec() !


Автор: Remiznik 6.6.2009, 15:48
Странная ошибка трудно обьяснить словами в чем проблема но я попробую!

Создаю простое диалоговое окно и при вызове его в приложение он блокирует работу приложение пока не будет какихто действий в этом диалогового окне !

вот примерный код
 
Код

class myDialog : public QDialog
{}

void MainWindow::showDialog()
{
      myDialog * mydialog=new myDialog;
     // ..... здесь идёт какаято настройка окна типа содержимого LineEdit

     if( mydialog->exec() == QDialog::Accepted )
    {
          // при нажатие на какуто кнопку здесь происходит снятие даных с myDialog
     }
    delete mydialog;


вот примерно такой код часто мной используемый и всегда нормально работающий ! Но на одной форме он падает при вызове exec(). Сразу скажу форма совершено обычная и работает нормально и падает только при вызове exec().

Самое странное во всем этом что иногда она срабатывает нормально а иногда падает и мне ни как не отследить от чего это происходит. Бывает 10 раз вызывается нормально а на 11 упадёт всё приложение .

П.С немогу выложить полный код вызывающий форму и саму форму так как там много всего написано и сейчас с собой точной программы нет !

Автор: SABROG 6.6.2009, 16:41
Что говорит отладчик?

Автор: mes 6.6.2009, 20:13
Цитата(Remiznik @  6.6.2009,  14:48 Найти цитируемый пост)
П.С немогу выложить полный код вызывающий форму и саму форму так как там много всего написано и сейчас с собой точной программы нет ! 

Я думаю, где то Вы допустили ошибку.. и думаю, что она как раз в той части, которую Вы не показали. К сожалению не могу показать точно, где именно у Вас ошибка, как минимум из за того что не обладаю телепатическими способностями.  smile 

Ну вобщем какой вопрос, такой ответ  smile 

Автор: Remiznik 7.6.2009, 13:58
Да я понимаю вопрос не странный какойто абстрактный, нет не четкого примера не результата ошибки. Так что я и не просил четкова ответа как с этим бороться !

Просто интересно было бы послушать мысли участников форума почему может падать приложение и почему имено функция exec() и почему имено эта функция приводит к падению ? Просто в документации по этой функции нечего особенного не написано, только то что она блокирует приложение и в результате работы возвращаете значение !

Кстате при падение она у меня не возвращаете никакого значения, и я незнаю в каком имено месте внутри неё происходит сбой !

Автор: SABROG 7.6.2009, 14:01
Цитата(Remiznik @  7.6.2009,  13:58 Найти цитируемый пост)
Кстате при падение она у меня не возвращаете никакого значения, и я незнаю в каком имено месте внутри неё происходит сбой ! 

А может она и не падает вовсе, а закрывается? Каким отладчиком пользовался?

Автор: Remiznik 7.6.2009, 14:07
отладчиком не пользуюсь ! к сожеленью очень старый компьютер и ось совсем дубовая трудно на нём что дельное установить и работать тоже трудно .... можно сказать пишу в текстовом редакторе и потом компилирую ... только вот формы создаю в Disinger!

падает точно пишит Segmentation fault . core dump !

Автор: SABROG 7.6.2009, 14:10
gdb консольный.

Автор: Remiznik 7.6.2009, 14:12
Цитата(SABROG @ 7.6.2009,  14:10)
gdb консольный.

надо попробовать !

но всёравно узнать мнения что такого делает эта функция что приложение падает ))) 

Автор: Любитель 7.6.2009, 19:31
Функция не виновата smile 
Падает где-то твой диалог, вероятно кривая работа с памятью..

Автор: SABROG 7.6.2009, 19:35
Кстати вместо этого

Код

delete mydialog;



Лучше использовать это

Код

mydialog->deleteLater();


Правда, если честно я не понимаю зачем создавать диалог в куче, а не в стеке. Да и родителя лучше передать:

Код

myDialog * mydialog=new myDialog(this);

Автор: Remiznik 7.6.2009, 20:11
Цитата(Любитель @ 7.6.2009,  19:31)
Функция не виновата smile 
Падает где-то твой диалог, вероятно кривая работа с памятью..

Любитель, я форму отдельно тестировал нармально работает а имено в главной программе падает !


SABROG, всё это пробовал нечего не меняеть так же падете .

Автор: SABROG 7.6.2009, 21:25
Попробуй отладчик, потом напиши о результатах.

Автор: Любитель 7.6.2009, 22:53
Цитата(Remiznik @  7.6.2009,  20:11 Найти цитируемый пост)
Любитель, я форму отдельно тестировал нармально работает а имено в главной программе падает !

Ну.. что сказать - значит плохо тестировал. Ещё раз - код, написанный вначале, рабочий, хотя и несколько странный, ибо:
Цитата(SABROG @  7.6.2009,  19:35 Найти цитируемый пост)
Правда, если честно я не понимаю зачем создавать диалог в куче, а не в стеке.

Кстати, насчёт родителя - при ручном удалении это как раз излишне.

Как ты его "отдельно" тестировал?

Автор: SABROG 7.6.2009, 22:58
Цитата(Любитель @  7.6.2009,  22:53 Найти цитируемый пост)
Кстати, насчёт родителя - при ручном удалении это как раз излишне.

А я думаю наоборот не лишне перестраховаться, если забудешь сам удалить. В конкретно этой ситуации это никак не помогло бы, но лучше выработать привычку.

Автор: Remiznik 8.6.2009, 06:35
Любитель, код который я привёл здесь это пример как я вызываю и где падает ! это не реальный код ...... реальный код до вызова этой функции содержит много настроек и загрузок !

тестировал просто написал маленькое окно в котором только кнопка для вызова моей формы ...... и тупо сидел тыкал на кнопку ждал когда упадёт ! не падало а в главном падает значит ошибка гдето в главной программе но как вызов exec() связан с главной программой ?

Автор: Любитель 8.6.2009, 09:16
Ладно.. В любом случае глупо гадать smile Проще увидеть нормальный стект-трейс от дебаггера smile

Цитата(SABROG @  7.6.2009,  22:58 Найти цитируемый пост)
А я думаю наоборот не лишне перестраховаться, если забудешь сам удалить. 

Это уже философский вопрос.. Но, если свято следовать принципам RAII, то такой ситуации ("забудешь удалить") просто не может быть.

Автор: SABROG 8.6.2009, 10:49
Цитата(Любитель @  8.6.2009,  09:16 Найти цитируемый пост)
Это уже философский вопрос.

Ну да, для этих целей есть QSharedPointer.

Автор: Remiznik 8.6.2009, 19:02
Поделюсь своими соображениями ну от специалистов жду ответа такое возможно )

Для начла наверно всетаки придется поподробнее рассказать о том что хочу делать !

Есть главная программа и нужно открыть файл но не один их несколько в одном данный в другом описание ! Файл с даными очень большой .... и потому перед загрузкой файла выскакивает форма в которой указано диапазон файла (временной) к примеру от 0 до 20 сек это примерно файл весом 50 и больше метров !

так и все эти загрузки происходят в одной функции и вот я подумал если даных слишком много то стек может переполниться и упасть всё приложение ... но я не уверен это догадка ! Вопрос только почему падение происходит на функции exec() тоесть при отображение формы и блокировки !

Код

void MainWindow::openFile()
{
    if( loadFile ) { fileCloseProject(); }
    
     QString fileName = QFileDialog::getOpenFileName(this,"Open...", ".formular"); 
     std::cerr<<(fileName.toStdString()).c_str()   ;
            if (!fileName.isEmpty())
            {
          loadFile=true;
                   readFormular( fileName );  // чтение начального файла с описанием данных 
                  showFormular();                 // отображение даных в QTextEdit
                fileName.replace(".formular",".data");
           
                navigator= new NavigatorForm(this); // собственный клас тоже большого размера 
                       // настройка этого окна        
                            
                       if (checker->->isChecked())
                       {          
                              showDialog(); // эта та функция в которой происходит вызов формы с диапазоном файла  где и происходит падение 
                        }
                       readData(fileName,MeasChannels);   //чтение  основных даных 
                       ........
                 }
}
         


это далеко не полный перечень всего что делается в одной функции так как после загрузки файла сразу нужно вывести дополнительные окна для работы . так что функции получилась очень большая и еше она загружает много даных в оперативку из файла !! 
так может она падать из-за того что очень большая ?

Автор: SABROG 8.6.2009, 21:50
Цитата(Remiznik @  8.6.2009,  19:02 Найти цитируемый пост)
std::cerr<<(fileName.toStdString()).c_str()

Жесть какая. Чем qPrintable() не угодил? Да и вообще, если надо писать в stderr используй это:

Код

qCritical("File '%s'...", qPrintable(fileName));


Если просто в консоль то qDebug() или QTextStream(stdout). Хотя конечно никто не запрещает использовать стандартную библиотеку.

Цитата(Remiznik @  8.6.2009,  19:02 Найти цитируемый пост)
if (checker->->isChecked())

А это я вообще не понял.

P.S.: кстати, что сказал отладчик?

Автор: Remiznik 8.6.2009, 22:44
это всё не суть важно меня подения волнуют больше !

с отладчиком не разабрался почемуто при входе в QFileDialog::getOpenFileName(this,"Open...", ".formular");  приложение виснит и а отладчик не даёт дальше крутить шаги (

Автор: SABROG 8.6.2009, 23:29
Цитата(Remiznik @  8.6.2009,  22:44 Найти цитируемый пост)
это всё не суть важно меня подения волнуют больше !

Тогда предлагаю забыть о коде и сосредоточиться на отладке.

Цитата(Remiznik @  8.6.2009,  22:44 Найти цитируемый пост)
с отладчиком не разабрался почемуто

Просто документацию не читал, причина то понятна.

Цитата(Remiznik @  8.6.2009,  22:44 Найти цитируемый пост)
отладчик не даёт дальше крутить шаги

"крутить"? Куда? Какой отладчик используешь? Где backtrace, call stack?

Автор: Remiznik 8.6.2009, 23:40
gdb 6  запускаю приложение просто под отладчиком всё нармально работает но при вызове QFileDialog::getOpenFileName виснит приложение и нечего не происходит не появляеться окно диалога !!

да с документацией только сегодня начал знакомиться так что пока разбираюсь что кчему )

Автор: Remiznik 17.6.2009, 11:20
покопался отладчиком вот что выдаёт стек вызывов !
Код

681                     tmpStr.setNum((int)(endFile*period/time));
(gdb)
682                     intervalDialog->lineEditEnd->setText(tmpStr);
(gdb)
683                             if( intervalDialog->exec() == QDialog::Accepted )
(gdb) s
 
Program received signal SIGSEGV, Segmentation fault.
0x406641c7 in QAbstractButton::isChecked () from /usr/lib/qt4/lib/libQtGui.so.4
(gdb) bt
#0  0x406641c7 in QAbstractButton::isChecked () from /usr/lib/qt4/lib/libQtGui.so.4
#1  0x0805177b in MainWindow::paintEvent (this=0xbffff430, e=0xbfffd570) at src/mainwindow.cpp:406
#2  0x4025c711 in QWidget::event () from /usr/lib/qt4/lib/libQtGui.so.4
#3  0x406ce853 in QMainWindow::event () from /usr/lib/qt4/lib/libQtGui.so.4
#4  0x4020eb40 in QApplicationPrivate::notify_helper () from /usr/lib/qt4/lib/libQtGui.so.4
#5  0x4020d57c in QApplication::notify () from /usr/lib/qt4/lib/libQtGui.so.4
#6  0x40e83b18 in QCoreApplication::notifyInternal () from /usr/lib/qt4/lib/libQtCore.so.4
#7  0x40273e74 in qt_sendSpontaneousEvent () from /usr/lib/qt4/lib/libQtGui.so.4
#8  0x40256663 in QWidgetPrivate::drawWidget () from /usr/lib/qt4/lib/libQtGui.so.4
#9  0x403c58fa in QWidgetBackingStore::cleanRegion () from /usr/lib/qt4/lib/libQtGui.so.4
#10 0x403c37fc in qt_syncBackingStore () from /usr/lib/qt4/lib/libQtGui.so.4
#11 0x4025cb79 in QWidget::event () from /usr/lib/qt4/lib/libQtGui.so.4
#12 0x406ce853 in QMainWindow::event () from /usr/lib/qt4/lib/libQtGui.so.4
#13 0x4020eb40 in QApplicationPrivate::notify_helper () from /usr/lib/qt4/lib/libQtGui.so.4
#14 0x4020d57c in QApplication::notify () from /usr/lib/qt4/lib/libQtGui.so.4
#15 0x40e83b18 in QCoreApplication::notifyInternal () from /usr/lib/qt4/lib/libQtCore.so.4
#16 0x40e8481c in QCoreApplicationPrivate::sendPostedEvents () from /usr/lib/qt4/lib/libQtCore.so.4
#17 0x40e84505 in QCoreApplication::sendPostedEvents () from /usr/lib/qt4/lib/libQtCore.so.4
#18 0x40eb0435 in ?? () from /usr/lib/qt4/lib/libQtCore.so.4
#19 0x40fbe3c3 in ?? () from /lib/libglib-2.0.so.0
#20 0x0806c998 in ?? ()
#21 0x00000000 in ?? ()
(gdb) n
Single stepping until exit from function _ZNK15QAbstractButton9isCheckedEv,
which has no line number information.
 
Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.         


у кого есть какие соображение ? 

Автор: mes 17.6.2009, 11:36
Цитата(Remiznik @  17.6.2009,  10:20 Найти цитируемый пост)
у кого есть какие соображение ?  

догадка : невалидный this у кнопки
покажите содержание MainWindow::paintEvent, конструктора этого класса, функцию в которой создаются контролы (если не в конструкторе) и список дата_членов.

Автор: SABROG 17.6.2009, 13:08
Другая догадка - проблема в Qt с отрисовкой. Уже третий раз сталкиваюсь, похожий стек вызовов тут у человека и связан тоже с чекингом: http://www.forum.crossplatform.ru/index.php?showtopic=2931

Автор: Любитель 17.6.2009, 13:49
Цитата(SABROG @  17.6.2009,  13:08 Найти цитируемый пост)
Другая догадка - проблема в Qt с отрисовкой.

Да не - тут же на своём обработчики пэинта падает:
Цитата(Remiznik @  17.6.2009,  11:20 Найти цитируемый пост)
at src/mainwindow.cpp:406


Там похоже проверка чека какой-т кнопки по невалидному указателю на эту кнопку.

Автор: Remiznik 17.6.2009, 15:09
вот вы столько понаписали но я както не догоняю каким оброзом exec() связан с каким-то QAbstractButton::isChecked ()  но это ешо както понять можно на форме кнопки есть !

но вот эта страка для меня вобше загадка 
#1  0x0805177b in MainWindow::paintEvent (this=0xbffff430, e=0xbfffd570) at src/mainwindow.cpp:406
каким оброзом exec() связон с прорисовкой главного окна моего приложения ! И до этого проблем с функцией отрисовки небыло так что мне нечего не понятно !

Автор: Любитель 17.6.2009, 15:17
К тебе пришёл мессадж на перерисовку (MainWindow) - вызвалось событие перерисовки. Вполне нормально. Вопрос в том, почему оно свалилось smile Покажи 406-ую строчку-то эту smile Затем посмотри, к какой там кнопке обращение. И проверь все присваивания и вызовы делита для этого указателя (а также все смерти парента этой кнопки и т. д.).

Автор: mes 17.6.2009, 15:48
Цитата(Remiznik @  17.6.2009,  14:09 Найти цитируемый пост)
каким оброзом exec()

Интересно, а что по Вашему делает метод exec() ?

Автор: Remiznik 17.6.2009, 23:40
давайте по порядку ))

во первых !

это какойто страный вызов MainWindow::paintEvent (this=0xbffff430, e=0xbfffd570) at src/mainwindow.cpp:406 так как в начале кажой функции у менять есть консольное сообшение о том что даная ыункция вызываеться и при подение на консоли нечего нет тоесть вызываеться какаято левая функция или както страно !

во вторых 

я смотрел стек при нармальной работе это всего не вызываеться даный стек который я привёл создаёться только при падении 

в третьих 
учитывая предыдцшее что я не могу отследить в каком месте имено падение так как я явно при нармально работе не вижу какая функция вызываеться как такое вобше может происходить !

mes,  я думаю что метод exec()  прорисовывает по верх всех окон окна которое его вызвало и блокирует работу всего остального приложения . Как это происходит я незнаю и как уже сказал в пунке 2 отследить что вызываеться какието стороние функции можно только при падении. 
И есле уж и вызываеться прорисовка главного окна то только после того как происходит событие закрытие диалогового окна вызвавшего exec() но ни как до этого .... ведь в этом нет смысла !

ну я так думаю ! обьясните если я не прав очень хочеться разобраться !

П.С ешо раз напоню что приложение падает не каждый раз при вызове exec() . Оно может упасть и с 1-го вызова так и 10-го.

Автор: SABROG 18.6.2009, 08:25
Дану, чего гадать-то. Без полных исходников программы мы тебе уже ничем не поможем, как выясняется Qt вполне может падать из-за выхода за пределы массива и портить данные где-нибудь совсем в другом месте без AV.

Автор: mes 18.6.2009, 09:57
Цитата(Remiznik @  17.6.2009,  22:40 Найти цитируемый пост)
  я думаю что метод exec()  прорисовывает по верх всех окон окна которое его вызвало и блокирует работу всего остального приложения 

поправка 1 : не прорисовывает, а показывает (т.е фактически устанавливает флаг окну о том, что окно теперь видимо и может быть отрисовано) 
 прорисовка происходит в другом месте и в другое время (при обработке сообщения о прорисовке).
поправка 2 : блокирует не работу всего приложения, а только юзерское взаимодействие (в зависимости от режима со всеми остальными окнами приложения, или только с родительским)
Цитата(Remiznik @  17.6.2009,  22:40 Найти цитируемый пост)
Как это происходит я незнаю и как уже сказал в пунке 2 отследить что вызываеться какието стороние функции можно только при падении. 

Происходит путем добавления своего цикла обработки сообщений, в котором все "нежелательные" сообщения игнорируются. Однако остальные (не юзерского взаимодействия) продолжают спокойно обрабатываться.

Цитата(Remiznik @  17.6.2009,  22:40 Найти цитируемый пост)
И есле уж и вызываеться прорисовка главного окна то только после того как происходит событие закрытие диалогового окна вызвавшего exec() но ни как до этого .... ведь в этом нет смысла !

А если диалоговое окно переместили в сторону ? на старом месте остается пустота или остатки Вашего даилога ?!  smile 
Перерисовка окон происходит при любом ресайзинге и перемещении диалогового окна, в том числе и при первом (когда оно толжко появилось).
Точнее сказать не сама перерисовка, а вызов функции перерисовки, а она уж решает нужно ли рисовать какую то область или нет.


Цитата(Remiznik @  17.6.2009,  22:40 Найти цитируемый пост)
П.С ешо раз напоню что приложение падает не каждый раз при вызове exec() . Оно может упасть и с 1-го вызова так и 10-го. 

Если у Вас муссор в какой нибудь переменной, то именно так и будет.

Цитата(Remiznik @  17.6.2009,  22:40 Найти цитируемый пост)
это какойто страный вызов MainWindow::paintEvent (this=0xbffff430, e=0xbfffd570) at src/mainwindow.cpp:406 так как в начале кажой функции у менять есть консольное сообшение о том что даная ыункция вызываеться и при подение на консоли нечего нет тоесть вызываеться какаято левая функция или както страно !

Во первых неужто так трудно показать эту функцию ? если сомневаетесь она или нет, то нужна та которая лежит в файле mainwindow.cpp на 406 строчке.  smile 
Во вторых, Вы свое сообщение наверняка отправляете в поток, и поэтому Вы не дождетесь его появления на консоли если прога упадет.  smile 

Цитата(Remiznik @  17.6.2009,  22:40 Найти цитируемый пост)
учитывая предыдцшее что я не могу отследить в каком месте имено падение так как я явно при нармально работе не вижу какая функция вызываеться как такое вобше может происходить !

Может все таки выложите ту часть кода, о которой Вас просили Выше, или же она под строгим секретом ?!  smile 

Автор: Remiznik 18.6.2009, 10:32
выложу просто под рукой счас нет ! 

но должен заметить что я закоментил всю функцию отрисовки тоесть вызов её остаёться но никаких действий не происходит и вроде падатьперестало но я не уверен так как я несколько раз проверел не упало но как уже говарил она может и не спервого а с n-го раза упасть такчто тестирую.

но я так и не понял как вызываеться эты функция я не понял ! даже если она вызваеться почему на консоль не выводиться что она вызвана ?

Автор: Remiznik 22.6.2009, 10:30
извеняюсь за поднятую панику ) видно глаз совсем замозолился ))) все работает нармально и стек был прав падение вызывалось функцией прорисовки я там не использовал неправельно переменую ! и на консоль всё выводтся нармально .... видимо так заработался что уже не замечал !

всем спасибо)) очень помогли !

Автор: SABROG 22.6.2009, 10:56
Цитата(Remiznik @  22.6.2009,  10:30 Найти цитируемый пост)
всем спасибо)) очень помогли ! 

А я у тебя еще 6 июня спросил, что отладчик говорит. Если бы прислушался, то смог в тот же день свою проблему решить. smile

Автор: Remiznik 22.6.2009, 11:39
я послушал )))
 просто не сразу разобрался что к чему .... и меня смушало что на консоль не выводилось сообшение на что функция вызвана .... оказалось что я вывод на консоль поставил в конце функции и потому до этого места она не доходила ))).... а я это не заметил )

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)