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

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

Страниц: [1] 2 3 ... 6   Вниз
  Печать  
Автор Тема: Странная ошибка SIG SEGV  (Прочитано 35244 раз)
vbi
Гость
« : Март 21, 2012, 10:52 »

Пока приложение работает (при запуске создает 32 потока с QNetworkAccessManager и каждый менеджер постоянно делает запросы и возвращает QNetworkReply), время от времени появляется ошибка "Segmentation fault" с одним и тем же бектрейсом:



Приложение может проработать сутки, и ошибка не появится, а может проработать 1 час и появится эта ошибка. Бьюсь над ней месяц не могу ничего придумать. Много раз и код переписывал.
Главное ни одного из моих классов в бектрейсе нет, так что где искать проблему - не знаю Грустный
Кто поможет?
Благодарю наперед!
Записан
vbi
Гость
« Ответ #1 : Март 21, 2012, 11:03 »

Вот 725 строчка в qstring.h (4.8.0):

Код:
...
725    inline QString::QString(const QString &other) : d(other.d)
726    { Q_ASSERT(&other != this); d->ref.ref(); }
...
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #2 : Март 21, 2012, 11:10 »

Код показывай.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
mutineer
Гость
« Ответ #3 : Март 21, 2012, 11:11 »

Возможно ты где-то портишь память
Записан
vbi
Гость
« Ответ #4 : Март 21, 2012, 11:25 »

Кода много, много модулей...

Вот объект, который работает в параллельном потоке (их 32 шт.)

Конструктор:
Код:

    timer = new QTimer();
    connect(this, SIGNAL(startTimer()),timer,SLOT(start()));
    connect(this, SIGNAL(stopTimer()),timer,SLOT(stop()));
    connect(timer, SIGNAL(timeout()), this, SLOT(checkWork()));
    timer->setInterval(30000); // 30 sec


Процедура, которая запускает работу:
Код:
    if(!sManagerWasCreated)
    {
        manager = new QNetworkAccessManager(); // тут утечки памяти
        sManagerWasCreated = true;
    }
    emit startTimer();
    connect(manager, SIGNAL(finished(QNetworkReply*)),this, SLOT(checkSiteFinished(QNetworkReply*))); 
    replyWasDeleted = false;
    reply = manager->get(QNetworkRequest(QUrl(sDomain,QUrl::TolerantMode)));                    //qDebug()<<"4"; 
    connect(reply,SIGNAL(destroyed()),this,SLOT(replyDestroyed()));

Вот прцедура которая получает QNetworkReply:

Код:
    if(!mtx.tryLock()) return;
    emit stopTimer();
    //qDebug()<<"finished begin";
    //    if(isFinished())
    //    {
    //        return;
    //    }


    QByteArray data;
    try
    {
        data = reply->read(reply->bytesAvailable());
    }
    catch(int e)
    {                           //qDebug()<<"error read";
        emit siteErrorSig();
        try
        {
            if(!replyWasDeleted)
            {
                reply->abort();
                reply->deleteLater();
            }
        }
        catch(int e)
        {
            //qDebug()<<"Error deleting reply";
        }
        //manager->deleteLater();
        offNode();
        return;
    }

    try
    {
        reply->abort();//qDebug()<<"6";
        reply->deleteLater();
    }
    catch(int e)
    {
        //qDebug()<<"Error deleting reply";
    }

Вот процедура таймера (если QNetworkReply не приходит):
Код:
   if(!mtx.tryLock()) return;
    emit stopTimer();
    try
    {
        if(!replyWasDeleted)
        {
            reply->abort();
            reply->deleteLater();
        }
    }
    catch(int e)
    {
        //qDebug()<<"Error deleting reply";
    }
    //manager->deleteLater();
Записан
mutineer
Гость
« Ответ #5 : Март 21, 2012, 11:28 »

сразу вопрос не совсем в тему: а разве эти методы кидают какие-нить исключения?
Код:
reply->abort();
reply->deleteLater();
Записан
vbi
Гость
« Ответ #6 : Март 21, 2012, 11:36 »

Кидают.
После выполнения
Код:
reply = manager->get(QNetworkRequest(QUrl(sDomain,QUrl::TolerantMode)));
reply потом каким-то образом иногда становится удаленным, т. е. объекта не существует. Тогда кидало ошибку.
Но потом я повесил слот
Код:
connect(reply,SIGNAL(destroyed()),this,SLOT(replyDestroyed()));
на удаление reply где меняется переменная replyWasDeleted
и проверяю ее. Если она истина, то не пытаюсь удалить reply.  Теперь исключение можно убрать. Я так оставил на всякий случай
Записан
mutineer
Гость
« Ответ #7 : Март 21, 2012, 11:38 »

а можно делать как все и просто обнулять reply...

Ну а по поводу топика: по приведенному коду ничего сказать не могу
Записан
vbi
Гость
« Ответ #8 : Март 21, 2012, 11:39 »

там еще куча кода. Еще у меня есть QWebView, который время от времени загружает страницы. Он грузит страницы, потом ищутся ссылки на такой странице и для каждой ссылки запускается поток, описанный выше.
Записан
V1KT0P
Гость
« Ответ #9 : Март 21, 2012, 11:44 »

там еще куча кода. Еще у меня есть QWebView, который время от времени загружает страницы. Он грузит страницы, потом ищутся ссылки на такой странице и для каждой ссылки запускается поток, описанный выше.
Попробуй писать лог, в начале каждой функции выводи сообщение о том что функция начала свое выполнение, а в конце о том что закончила. Если повезет найдешь в какой функции ошибка возникает.
Записан
mutineer
Гость
« Ответ #10 : Март 21, 2012, 11:45 »

Попробуй писать лог, в начале каждой функции выводи сообщение о том что функция начала свое выполнение, а в конце о том что закончила. Если повезет найдешь в какой функции ошибка возникает.
бектрейс намекает что не повезет
Записан
mutineer
Гость
« Ответ #11 : Март 21, 2012, 11:46 »

какая версия Qt, какая ось?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #12 : Март 21, 2012, 11:47 »

Не вижу где replyWasDeleted устанавливается в true. Если deleteLater успеет проскочить - обращение к удаленному объекту. В любом случае включить печати в конструкторе/деструкторе и посмотреть на вылете
Записан
V1KT0P
Гость
« Ответ #13 : Март 21, 2012, 11:52 »

Попробуй писать лог, в начале каждой функции выводи сообщение о том что функция начала свое выполнение, а в конце о том что закончила. Если повезет найдешь в какой функции ошибка возникает.
бектрейс намекает что не повезет
Можно же унаследоваться от QNetworkAccessManager и туда понапихать проверок с выводом параметров.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #14 : Март 21, 2012, 12:11 »

Но потом я повесил слот
Код:
connect(reply,SIGNAL(destroyed()),this,SLOT(replyDestroyed()));
на удаление reply где меняется переменная replyWasDeleted
и проверяю ее. Если она истина, то не пытаюсь удалить reply.  Теперь исключение можно убрать. Я так оставил на всякий случай
Как я понял, установка replyWasDeleted=true происходит в слоте replyDestroyed. Если так то не забыли ли Вы взять мутекс (mtx) в этом слоте? И в любом случае replyWasDeleted надо проверять перед reply->abort
Записан
Страниц: [1] 2 3 ... 6   Вверх
  Печать  
 
Перейти в:  


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