Russian Qt Forum

Qt => Общие вопросы => Тема начата: vbi от Март 21, 2012, 10:52



Название: Странная ошибка SIG SEGV
Отправлено: vbi от Март 21, 2012, 10:52
Пока приложение работает (при запуске создает 32 потока с QNetworkAccessManager и каждый менеджер постоянно делает запросы и возвращает QNetworkReply), время от времени появляется ошибка "Segmentation fault" с одним и тем же бектрейсом:

(http://s019.radikal.ru/i634/1203/56/3aec948d3dd7.png)

Приложение может проработать сутки, и ошибка не появится, а может проработать 1 час и появится эта ошибка. Бьюсь над ней месяц не могу ничего придумать. Много раз и код переписывал.
Главное ни одного из моих классов в бектрейсе нет, так что где искать проблему - не знаю :(
Кто поможет?
Благодарю наперед!


Название: Re: Странная ошибка SIG SEGV
Отправлено: vbi от Март 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(); }
...


Название: Re: Странная ошибка SIG SEGV
Отправлено: Пантер от Март 21, 2012, 11:10
Код показывай.


Название: Re: Странная ошибка SIG SEGV
Отправлено: mutineer от Март 21, 2012, 11:11
Возможно ты где-то портишь память


Название: Re: Странная ошибка SIG SEGV
Отправлено: vbi от Март 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();


Название: Re: Странная ошибка SIG SEGV
Отправлено: mutineer от Март 21, 2012, 11:28
сразу вопрос не совсем в тему: а разве эти методы кидают какие-нить исключения?
Код:
reply->abort();
reply->deleteLater();


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


Название: Re: Странная ошибка SIG SEGV
Отправлено: mutineer от Март 21, 2012, 11:38
а можно делать как все и просто обнулять reply...

Ну а по поводу топика: по приведенному коду ничего сказать не могу


Название: Re: Странная ошибка SIG SEGV
Отправлено: vbi от Март 21, 2012, 11:39
там еще куча кода. Еще у меня есть QWebView, который время от времени загружает страницы. Он грузит страницы, потом ищутся ссылки на такой странице и для каждой ссылки запускается поток, описанный выше.


Название: Re: Странная ошибка SIG SEGV
Отправлено: V1KT0P от Март 21, 2012, 11:44
там еще куча кода. Еще у меня есть QWebView, который время от времени загружает страницы. Он грузит страницы, потом ищутся ссылки на такой странице и для каждой ссылки запускается поток, описанный выше.
Попробуй писать лог, в начале каждой функции выводи сообщение о том что функция начала свое выполнение, а в конце о том что закончила. Если повезет найдешь в какой функции ошибка возникает.


Название: Re: Странная ошибка SIG SEGV
Отправлено: mutineer от Март 21, 2012, 11:45
Попробуй писать лог, в начале каждой функции выводи сообщение о том что функция начала свое выполнение, а в конце о том что закончила. Если повезет найдешь в какой функции ошибка возникает.
бектрейс намекает что не повезет


Название: Re: Странная ошибка SIG SEGV
Отправлено: mutineer от Март 21, 2012, 11:46
какая версия Qt, какая ось?


Название: Re: Странная ошибка SIG SEGV
Отправлено: Igors от Март 21, 2012, 11:47
Не вижу где replyWasDeleted устанавливается в true. Если deleteLater успеет проскочить - обращение к удаленному объекту. В любом случае включить печати в конструкторе/деструкторе и посмотреть на вылете


Название: Re: Странная ошибка SIG SEGV
Отправлено: V1KT0P от Март 21, 2012, 11:52
Попробуй писать лог, в начале каждой функции выводи сообщение о том что функция начала свое выполнение, а в конце о том что закончила. Если повезет найдешь в какой функции ошибка возникает.
бектрейс намекает что не повезет
Можно же унаследоваться от QNetworkAccessManager и туда понапихать проверок с выводом параметров.


Название: Re: Странная ошибка SIG SEGV
Отправлено: Igors от Март 21, 2012, 12:11
Но потом я повесил слот
Код:
connect(reply,SIGNAL(destroyed()),this,SLOT(replyDestroyed()));
на удаление reply где меняется переменная replyWasDeleted
и проверяю ее. Если она истина, то не пытаюсь удалить reply.  Теперь исключение можно убрать. Я так оставил на всякий случай
Как я понял, установка replyWasDeleted=true происходит в слоте replyDestroyed. Если так то не забыли ли Вы взять мутекс (mtx) в этом слоте? И в любом случае replyWasDeleted надо проверять перед reply->abort


Название: Re: Странная ошибка SIG SEGV
Отправлено: vbi от Март 21, 2012, 12:12
какая версия Qt, какая ось?
4.8.0 Windows 7


Название: Re: Странная ошибка SIG SEGV
Отправлено: vbi от Март 21, 2012, 12:14
Не вижу где replyWasDeleted устанавливается в true. Если deleteLater успеет проскочить - обращение к удаленному объекту. В любом случае включить печати в конструкторе/деструкторе и посмотреть на вылете

Код:
connect(reply,SIGNAL(destroyed()),this,SLOT(replyDestroyed()));

а в replyDestroyed() есть строчка:
Код:
replyWasDeleted = true;


Название: Re: Странная ошибка SIG SEGV
Отправлено: vbi от Март 21, 2012, 12:18
Но потом я повесил слот
Код:
connect(reply,SIGNAL(destroyed()),this,SLOT(replyDestroyed()));
на удаление reply где меняется переменная replyWasDeleted
и проверяю ее. Если она истина, то не пытаюсь удалить reply.  Теперь исключение можно убрать. Я так оставил на всякий случай
Как я понял, установка replyWasDeleted=true происходит в слоте replyDestroyed. Если так то не забыли ли Вы взять мутекс (mtx) в этом слоте? И в любом случае replyWasDeleted надо проверять перед reply->abort


Стоп. Сейчас, когда я добавил connect(reply,SIGNAL(destroyed()),this,SLOT(replyDestroyed())); и там устанавливаю переменную, а перед удалением reply проверяю ее, то все работает нормально, исключений не возникает при удалении reply. В коде try можно убрать. Я ж говорю я его просто забыл убрать. В этом участке кода проблем нет.
Проблема тут в (смотрите мое первое сообщение + бектрейс)


Название: Re: Странная ошибка SIG SEGV
Отправлено: vbi от Март 21, 2012, 12:19
Попробуй писать лог, в начале каждой функции выводи сообщение о том что функция начала свое выполнение, а в конце о том что закончила. Если повезет найдешь в какой функции ошибка возникает.
бектрейс намекает что не повезет
Можно же унаследоваться от QNetworkAccessManager и туда понапихать проверок с выводом параметров.
V1KT0P, спасибо за советы, попробую  :)!


Название: Re: Странная ошибка SIG SEGV
Отправлено: Igors от Март 21, 2012, 12:35
Стоп. Сейчас, когда я добавил connect(reply,SIGNAL(destroyed()),this,SLOT(replyDestroyed())); и там устанавливаю переменную, а перед удалением reply проверяю ее, то все работает нормально, исключений не возникает при удалении reply. В коде try можно убрать. Я ж говорю я его просто забыл убрать. В этом участке кода проблем нет.
Проблема тут в (смотрите мое первое сообщение + бектрейс)
Там у Вас еще один abort и deleteLater. И вообще: вызываете reply->read, откуда известно что reply не удален?


Название: Re: Странная ошибка SIG SEGV
Отправлено: vbi от Март 21, 2012, 12:44
Стоп. Сейчас, когда я добавил connect(reply,SIGNAL(destroyed()),this,SLOT(replyDestroyed())); и там устанавливаю переменную, а перед удалением reply проверяю ее, то все работает нормально, исключений не возникает при удалении reply. В коде try можно убрать. Я ж говорю я его просто забыл убрать. В этом участке кода проблем нет.
Проблема тут в (смотрите мое первое сообщение + бектрейс)
Там у Вас еще один abort и deleteLater. И вообще: вызываете reply->read, откуда известно что reply не удален?
Дело в том, что reply иногда уже был удален только в одной процедуре, та что на таймере висит и запускается если Reply так и не пришел. А там reply->read нету. Хотя может таймер срабатывает после той процедуры, которая получает QNetworkReply. Я ведь поток не удаляю, а снимаю мутекс и использую снова. Надо будет проверить. Спасибо.


Название: Re: Странная ошибка SIG SEGV
Отправлено: Alex Custov от Март 21, 2012, 17:04
После выполнения
Код:
reply = manager->get(QNetworkRequest(QUrl(sDomain,QUrl::TolerantMode)));
reply потом каким-то образом иногда становится удаленным, т. е. объекта не существует. Тогда кидало ошибку.

А reply при этом точно != 0? Ты вообще не делаешь проверку на 0 ни после get, ни в слоте checkSiteFinished, что плохо.


Название: Re: Странная ошибка SIG SEGV
Отправлено: vbi от Март 21, 2012, 21:10
А reply всегда равено 0 если объект не создан (или удален)?
Кстате запускал не удаляя reply вообще, закоментировав данные строки - та же ошибка, не пропала. Я так понимаю судя по бектрейсу отправляется какое-то сообщение о аутентификации и почему-то падает на QString'е


Название: Re: Странная ошибка SIG SEGV
Отправлено: vbi от Март 23, 2012, 12:42
Пробовал дебаги выводить - все равно не могу найти в чем проблема.
Ладно, потратил время. Вырвал кусок программы, скомпилил, подправил. Протестил - тоже получает эту ошибку.

Вообщем вот, пинайте: bibyte.net/testThreads.zip (http://bibyte.net/testThreads.zip)

За неудаление объектов и лишние сигналы слоты прошу не бить :)
Запускаете проект. Нажимаете на форме кнопку "тестировать потоки". Ждете. Со временем выведется ошибка. Может через 15 минут, а может через 6 часов...

Может по коду подскажете ткнете в ошибку  ::)


Название: Re: Странная ошибка SIG SEGV
Отправлено: vbi от Март 23, 2012, 13:20
Хотя на протяжении 20 минут у меня полюбому выскакивает


Название: Re: Странная ошибка SIG SEGV
Отправлено: Bepec от Март 23, 2012, 14:30
Могу вас обрадовать - ваш проект валится изза мутексов :) ровно 32 штуки анлоков :)

dj
Код:
void VBCheckURLThread::runChecking()
{
    mtx.unlock();  <<<<<<<<<<<<<<<<<<<<<=========== Что за ??? :)
    if(!sManagerWasCreated)
    {
        manager = new QNetworkAccessManager(); // тут утечки памяти
        sManagerWasCreated = true;
    }
    connect(manager, SIGNAL(finished(QNetworkReply*)),this, SLOT(checkSiteFinished(QNetworkReply*)));   // тут утечки памяти
    connect(manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)),this, SLOT(checkAuthenticationRequired(QNetworkReply*,QAuthenticator*)));
    replyWasDeleted = false;
    reply = manager->get(QNetworkRequest(QUrl(sDomain,QUrl::TolerantMode)));                    //// qDebug()<<"4";   // тут утечки памяти
    connect(reply,SIGNAL(destroyed()),this,SLOT(replyDestroyed()));
    emit startTimer(30000);
}

Извиняюсь конечно, мб я недостаточно терпеливый, но ваша программа посылает 32 запроса и спит... Как боярин мордой в стогу. Попытавшись разобраться с архитектурой - плюнул. Возможно это нерабочий пример и я поспешил вам помогать?


Название: Re: Странная ошибка SIG SEGV
Отправлено: V1KT0P от Март 23, 2012, 14:49
Извиняюсь конечно, мб я недостаточно терпеливый, но ваша программа посылает 32 запроса и спит... Как боярин мордой в стогу. Попытавшись разобраться с архитектурой - плюнул. Возможно это нерабочий пример и я поспешил вам помогать?
Я тоже попытался запустить. После нажатия кнопки на экране появляются несколько десятков рантайм ошибок. Я испугался, закрыл и больше не хочу его запускать.


Название: Re: Странная ошибка SIG SEGV
Отправлено: Bepec от Март 23, 2012, 14:55
Виктор там мутекс анлок надо закомментить :) Я в куске кода привёл его с "<<<<<<<<====== Что за?"

Хотя в принципе ничего не измениться. Нифига не работает :D


Название: Re: Странная ошибка SIG SEGV
Отправлено: vbi от Март 23, 2012, 15:52
Хм.. а как вы узнали что здесь валится?

Просто после запуска процедуры "runChecking()" выполнение всередине класса "VBCheckURLThread" попадает либо в "checkSiteFinished" либо в "checkWork()" (либо QNetworkAccessManager вернет reply, либо сработает таймер на превышении времени). Каждая из этих процедур замыкает мютекс mtx. Какая первая замкнет - та и выполнится. потом мютекс не размыкается а добавляется в стек в классе "mainwondow". Когда этот объект понадобится, он достается из стека опять и снова запускается процедура "runChecking()", которая и размыкает ранее замкнутый мютекс.

Переписал код:



Код:
void VBCheckURLThread::runChecking()
{
    //mtx.unlock(); /////////////////////////////////////// - ЗАКОМЕНТИРОВАЛ
    if(!sManagerWasCreated)
    {
 
  ...
}

void VBCheckURLThread::checkWork()
{
 ...
    offNode();
    mtx.unlock(); ////////////////////////////////////// ДОБАВИЛ ++++++++
}

void VBCheckURLThread::checkSiteFinished(QNetworkReply* localReply)
{
  ...
        offNode();
        mtx.unlock(); ////////////////////////////////////// ДОБАВИЛ перед RETURN ++++++++
        return;
  ...
    offNode();
    mtx.unlock(); ////////////////////////////////////// ДОБАВИЛ ++++++++
}

что дает тот же результат, только не пытается размыкать мютекс сначала.

После запуска через пару минут - та же самая ошибка :((( (спасибо за попытку)

Перезалил архив проекта с изменениями: http://bibyte.net/testThreads.zip (http://bibyte.net/testThreads.zip)


Название: Re: Странная ошибка SIG SEGV
Отправлено: vbi от Март 23, 2012, 15:56
если тот мутекс закоментировать - то программа будет спать после 32 ответов. Если его убрать - тогда ниже надо добавить (см. выше, или скачайте проект наново, я обновил).


Название: Re: Странная ошибка SIG SEGV
Отправлено: vbi от Март 23, 2012, 16:00
программа создает поток отправляет запрос. Если созданных потоков меньше 32, то создает опять и т. д. потоки возвращают ответ и не удаляются а запихаются в стек. Потом программа смотрит - есть в стеке потоков и меньше 32 еще не вернули ответ - берет из стека поток и снова отправляет запрос и т. д.


Название: Re: Странная ошибка SIG SEGV
Отправлено: Bepec от Март 23, 2012, 18:08
Первое впечатление если чесно отвратное. Надо же других так неуважать, чтобы такую подлость с самого начала творить :) (это не обвинение, это не оскорбление, ежели обидел - извиняюсь)

Я узнал, что программа там валится просто - ОНА ВАЛИТСЯ С ПЕРВОГО ЖЕ ЗАПУСКА :)
32!!! окна критичных ошибок и полтора десятка предупреждений о том, что мутекс нужно сначала залочить, а потом разлочить.

Соответственно тут и появилась диллема:
Если не комментить - валится с самого начала.

Если комментить - не посылает более 32.

PS я понял логику вашей программы, не понял реализацию, переделывать вашу программу лень (тем более со стеком).

PPS счас скачаю возможно ваш новый проект и попытаюсь запустить...



Название: Re: Странная ошибка SIG SEGV
Отправлено: vbi от Март 23, 2012, 18:15
Спасибо за критику!

"окна критичных ошибок и полтора десятка предупреждений о том, что мутекс нужно сначала залочить, а потом разлочить" - Почему у меня окна и предупреждения не валятся вообще, даже варнингов нет? Чем вы пользуетесь? У меня стандартный QT Creator из стандартного набора QTSDK.


Название: Re: Странная ошибка SIG SEGV
Отправлено: vbi от Март 23, 2012, 18:16
Скачайте проект еще раз пожалуйста. Там та строчка закоментирована, и сделано чтоб мутекс потом разлочивался, и счетчик проходит за 32


Название: Re: Странная ошибка SIG SEGV
Отправлено: Bepec от Март 23, 2012, 19:32
Я бы задумался, если б у меня только было. А так и у Виктора она тож валилась ;) Я использую VS2008 + Qt Addin.

Скачиваю


Название: Re: Странная ошибка SIG SEGV
Отправлено: Bepec от Март 23, 2012, 20:55
Скачал запустил. Пожалел что нет второго компа - твоя прога мой i3 жрёт как мартышка семечки.
Завтра протестю. А то даже музыка заглючивает :)


Название: Re: Странная ошибка SIG SEGV
Отправлено: vbi от Март 24, 2012, 11:07
Я собираю на MinGW. Под линуксом собирал. У меня не выдавало ошибок и варнингов на счет анлука мютекса. Да прога жрет все свободные ресурсы. Я для потоков пытаюсь и приритет ставить низкий (QThread::LowPriority) перед запуском. Вроде не должно все остальное глючить.
У меня, например, когда фильм смотрю, вроде нормально (HP Compaq 6720s 1,6 Core2Duo, 3 Gb RAM).

Цитировать
Скачал запустил. Пожалел что нет второго компа - твоя прога мой i3 жрёт как мартышка семечки.
Завтра протестю. А то даже музыка заглючивает Улыбающийся

Буду прееееемного благодарен!!!!!  :) :) :) Надежда только на Вас...


Название: Re: Странная ошибка SIG SEGV
Отправлено: Bepec от Март 25, 2012, 11:29
В принципе тебя можно радовать - ты в своей программе портишь память :) Где - незнаю, это ты сам должен найти :)

Проблема вылета - при парсинге URL "http://' отбрасывается "http:" и идёт поиск "//"

Вот только в момент вызова ф-ции QString.indexOf() у строки из 2 (двух) слешей из-за испорченной памяти длина где то "-1655874695" рандомно :) Собственно там и выпадает программа в осадок.

Мой тебе совет - перепиши программу. (поиск порчи памяти это оочень сложное дело)

И да - советую (но не настаиваю), использовать наследование от QThread и создать 1 класс который будет отвечать за нужные тебе действия ;) И уж точно он не будет жрать 90% процессорного времени моего компа :D

update: ради достоверности ещё пару раз дождался вылетов - ты портишь память. В самых разных местах. И конечно же иногда это проскакивает, иногда рушит программу.

Порча памяти - это запись данных в некорректный участок памяти. К примеру в 26 элемент массива с 10 элементами.


Название: Re: Странная ошибка SIG SEGV
Отправлено: vbi от Март 25, 2012, 13:34
Спасибо! Попробую разобратся. Вы очень помогли!


Название: Re: Странная ошибка SIG SEGV
Отправлено: vbi от Март 29, 2012, 11:54
Мне переписывать программу сложно. Я итак ее пол года переписывал уже. А теперь опять переписывать. Там столько всего...

А как вы длинну измеряли? sizeOf()?


Название: Re: Странная ошибка SIG SEGV
Отправлено: mutineer от Март 29, 2012, 12:03
int QString::length () const


Название: Re: Странная ошибка SIG SEGV
Отправлено: Bepec от Март 29, 2012, 12:12
У вас там портится память. То есть любое поле может измениться на любое значение.

Наиболее часто у меня вылетало именно при размере строки, но были и ошибки обращения по указателю (оказывался сдвинут в неипические дали).

Порчу памяти невозможно предотвратить заплаткой, ибо она может испортить и заплатку ;)  Её нужно вычислить и убрать.

Да, длину я не вычислял - просто прошёл по стеку вызовов перед вылетом, смотрел данные внутри QString класса.


Название: Re: Странная ошибка SIG SEGV
Отправлено: V1KT0P от Март 29, 2012, 13:59
Мне переписывать программу сложно. Я итак ее пол года переписывал уже. А теперь опять переписывать. Там столько всего...

А как вы длинну измеряли? sizeOf()?

Как я тебя понима. Сам вот переписал программу и все круто, но при переписывании использовал только один поток. В релизе решил поставить 4 потока, так она зараза падает, хотя я везде синхронизируюсь через boost::asio::strand =).

добавлено:
Кстати а никто не в курсе, может valgrind может помочь выявить то место где происходит порча памяти? Valgrind же по сути виртуальная машина, тоесть может по ходу работы отслеживать кто и куда пишет а когда упадет просто посмотреть кто последний писал в затертую память.


Название: Re: Странная ошибка SIG SEGV
Отправлено: Bepec от Март 29, 2012, 14:24
Синхронизация тут не поможет.

Насчёт валгринда незнаю, но вроде в некоторых IDE есть возможность ставить условие на обращение к участку памяти.

PS хотя поиск порчи памяти дело неблагодаааарное.


Название: Re: Странная ошибка SIG SEGV
Отправлено: vbi от Март 29, 2012, 17:33
Я собирал программу под линуксом, тестировал валгриндом, но таких проблем там не было, программа не вылетала ниразу. Правда с валгриндом программа наааааамного медленне работает. Может завтра попробую поставлю на целый день, и посмотрим. А так все утечки, которые показывал валгринд я устранил)


Название: Re: Странная ошибка SIG SEGV
Отправлено: Bepec от Март 29, 2012, 20:49
Утечка - течёт память. Программа подскальзывается, но работает.

Порча памяти - программа летит с обрыва в армагеддец ядерный.

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

Под той же студией или Creator'ом порча может быть незаметной. Ей не происходит, ибо IDE поддерживает программу. А вот запускаешь в релизе и усё. Через секунду/час/месяц/год ваша программа разорвёт чьи либо планы своим Exception.

PS Вот ни за что, ни за что не поверю, что с незакомменченным unlock'ом ваша программа работала. Это противоречит всему, что является аксиомами про мутексы ;)


Название: Re: Странная ошибка SIG SEGV
Отправлено: vbi от Март 30, 2012, 01:14
Может и так. Я релиз давно уже не собирал, по крайней мере с тех пор как мютекс поставил... Вот почему бектрейс не показывает в каком именно месте программы вызывается ексцепшн? Потому что это не в коде программы а в коде самого QT (кстате я ставил QT с исходниками, но вместо исходника в бектрейсе отображается почему-то дизасемблер бинарника..) какой-то евент - событие от QNetworkAccessManager в котором уже что-то нарушено. Как я мог испортить что - то в QNetworkAccessManager. Я ставил проверку на передаваемую ссылку и отбрасывал плохие ссылки, но всеравно ошибку получаю.


Название: Re: Странная ошибка SIG SEGV
Отправлено: V1KT0P от Март 30, 2012, 01:22
Может и так. Я релиз давно уже не собирал, по крайней мере с тех пор как мютекс поставил... Вот почему бектрейс не показывает в каком именно месте программы вызывается ексцепшн? Потому что это не в коде программы а в коде самого QT (кстате я ставил QT с исходниками, но вместо исходника в бектрейсе отображается почему-то дизасемблер бинарника..) какой-то евент - событие от QNetworkAccessManager в котором уже что-то нарушено. Как я мог испортить что - то в QNetworkAccessManager. Я ставил проверку на передаваемую ссылку и отбрасывал плохие ссылки, но всеравно ошибку получаю.
Тебе же сказали ты портишь память, и эта память может оказаться чем угодно. В данном случае портится память в QNetworkAccessManager вроде как. У меня вообще веселье, прога падает а в бэктрейсе всего одна строчка и та указывает на кукую-то функцию в msvcr =). Если не найду где ошибка придется отказаться от многопоточности =(.


Название: Re: Странная ошибка SIG SEGV
Отправлено: Bepec от Март 30, 2012, 07:07
Виктор я бы вам посоветовал разобрать ваши потоки. По отдельности. На тестовом проекте.

Мне лично помогало, когда задаёшь все необходимые для работы параметры и тестируешь. Так за день/пару часов вы уже локализуете поток, который совершает порчу.

А далее уже карандаш, бумажку (ну или в моём случае отладчик) и погнал разбирать.

А не показывает тебе сырцы неизвестно почему. Я ведь даже незнаю какая у тебя IDE?


Название: Re: Странная ошибка SIG SEGV
Отправлено: mutineer от Март 30, 2012, 10:09
Не показывает сорцы скорее всего потому, что для запуска используются не дебажные версии Qt либ


Название: Re: Странная ошибка SIG SEGV
Отправлено: V1KT0P от Март 30, 2012, 12:53
Виктор я бы вам посоветовал разобрать ваши потоки. По отдельности. На тестовом проекте.

Мне лично помогало, когда задаёшь все необходимые для работы параметры и тестируешь. Так за день/пару часов вы уже локализуете поток, который совершает порчу.

А далее уже карандаш, бумажку (ну или в моём случае отладчик) и погнал разбирать.

А не показывает тебе сырцы неизвестно почему. Я ведь даже незнаю какая у тебя IDE?
QtCreator, Qt не используется. Использую boost и boost::asio. Все потоки синхронизируются через boost::asio::strand. Добавляются потоки, которые сразу же выполняют boost::asio::io_service::run. Либы я точно дебажные добавляю с приставкой -d. При одном потоке все нормально, при двух и более падает =(.


Название: Re: Странная ошибка SIG SEGV
Отправлено: Bepec от Март 30, 2012, 14:09
Попробуй по одному потоку потестить ;)


Название: Re: Странная ошибка SIG SEGV
Отправлено: vbi от Апрель 01, 2012, 20:42
Заметил странную особенность. Как Вы заметили этот фрагмент программы, который я выложил парсит каталог DMOZ. Но если его переписать таким образом, чтоб он парсил другой сайт (например Яндекс) - данная ошибка ни разу не наблюдалась. По крайней мере количество возвращенных результатов было около 150 000 и было остановлено вручную.


Название: Re: Странная ошибка SIG SEGV
Отправлено: Bepec от Апрель 02, 2012, 07:07
Ты портишь память в программе. В любом месте. Возможно даже в потоке :) А может быть в конструкторах. Памяти это без разницы :)

PS короче - мб у тебя порча там и была, но это уже ты решай :)


Название: Re: Странная ошибка SIG SEGV
Отправлено: V1KT0P от Апрель 02, 2012, 08:34
Виктор я бы вам посоветовал разобрать ваши потоки. По отдельности. На тестовом проекте.

Мне лично помогало, когда задаёшь все необходимые для работы параметры и тестируешь. Так за день/пару часов вы уже локализуете поток, который совершает порчу.
Ахаха, я локализовал порчу. Портит все вот эта функция:
Код
C++ (Qt)
void Connection::generateString(string *generateString)
{
   stringstream generatedString;
   time_facet *pfacet = new time_facet("%d-%b-%Y %H:%M:%S");
   generatedString.imbue(locale(locale::classic(), pfacet));
   generatedString << setprecision(8) << "INSERT INTO SOME_TABLE VALUES ( 0, " << static_cast<uint32_t>(m_session.id) << ", '"
                   << boost::posix_time::from_time_t(m_session.timeStamp) << "', "
                   << static_cast<uint32_t>(m_session.someValue) << ");";
   *generateString = generatedString.str();
}
Если в ней прописать:
Код
C++ (Qt)
*generateString = "Some text";
То все успешно работает. А так глючит. Сразу скажу что кушает эту строку IBASE. Так вот в многопоточности возникает какой-то глюк. Что я делаю не так?
Вот что в этой функции может портить память?!


Название: Re: Странная ошибка SIG SEGV
Отправлено: gogi от Апрель 02, 2012, 14:39
Виктор я бы вам посоветовал разобрать ваши потоки. По отдельности. На тестовом проекте.

Мне лично помогало, когда задаёшь все необходимые для работы параметры и тестируешь. Так за день/пару часов вы уже локализуете поток, который совершает порчу.
Ахаха, я локализовал порчу. Портит все вот эта функция:
Код
C++ (Qt)
void Connection::generateString(string *generateString)
{
   stringstream generatedString;
   time_facet *pfacet = new time_facet("%d-%b-%Y %H:%M:%S");
   generatedString.imbue(locale(locale::classic(), pfacet));
   generatedString << setprecision(8) << "INSERT INTO SOME_TABLE VALUES ( 0, " << static_cast<uint32_t>(m_session.id) << ", '"
                   << boost::posix_time::from_time_t(m_session.timeStamp) << "', "
                   << static_cast<uint32_t>(m_session.someValue) << ");";
   *generateString = generatedString.str();
}
Если в ней прописать:
Код
C++ (Qt)
*generateString = "Some text";
То все успешно работает. А так глючит. Сразу скажу что кушает эту строку IBASE. Так вот в многопоточности возникает какой-то глюк. Что я делаю не так?
Вот что в этой функции может портить память?!

Вангую, что у тебя наружу (в *generateString) передаётся локальный указатель (generatedString.str()).


Название: Re: Странная ошибка SIG SEGV
Отправлено: V1KT0P от Апрель 02, 2012, 14:47
Виктор я бы вам посоветовал разобрать ваши потоки. По отдельности. На тестовом проекте.

Мне лично помогало, когда задаёшь все необходимые для работы параметры и тестируешь. Так за день/пару часов вы уже локализуете поток, который совершает порчу.
Ахаха, я локализовал порчу. Портит все вот эта функция:
Код
C++ (Qt)
void Connection::generateString(string *generateString)
{
   stringstream generatedString;
   time_facet *pfacet = new time_facet("%d-%b-%Y %H:%M:%S");
   generatedString.imbue(locale(locale::classic(), pfacet));
   generatedString << setprecision(8) << "INSERT INTO SOME_TABLE VALUES ( 0, " << static_cast<uint32_t>(m_session.id) << ", '"
                   << boost::posix_time::from_time_t(m_session.timeStamp) << "', "
                   << static_cast<uint32_t>(m_session.someValue) << ");";
   *generateString = generatedString.str();
}
Если в ней прописать:
Код
C++ (Qt)
*generateString = "Some text";
То все успешно работает. А так глючит. Сразу скажу что кушает эту строку IBASE. Так вот в многопоточности возникает какой-то глюк. Что я делаю не так?
Вот что в этой функции может портить память?!

Вангую, что у тебя наружу (в *generateString) передаётся локальный указатель (generatedString.str()).
Вообще-то там просто копируется текст а не указатель.
А причина была в
Код
C++ (Qt)
boost::posix_time::from_time_t(m_session.timeStamp)
Заменил на:
Код
C++ (Qt)
sprintf(timestamp, "%02d-%s-%04d %02d:%02d:%02d", time->tm_mday, mon[time->tm_mon], 1900+time->tm_year,
           time->tm_hour, time->tm_min, time->tm_sec);
И все заработало.


Название: Re: Странная ошибка SIG SEGV
Отправлено: Alex Custov от Апрель 02, 2012, 15:43
То все успешно работает. А так глючит. Сразу скажу что кушает эту строку IBASE. Так вот в многопоточности возникает какой-то глюк. Что я делаю не так?
Вот что в этой функции может портить память?!

Если портится память, то программа может падать на совершенно нормальных участках и через много времени от того момента, как память испортилась.


Название: Re: Странная ошибка SIG SEGV
Отправлено: V1KT0P от Апрель 02, 2012, 16:12
То все успешно работает. А так глючит. Сразу скажу что кушает эту строку IBASE. Так вот в многопоточности возникает какой-то глюк. Что я делаю не так?
Вот что в этой функции может портить память?!

Если портится память, то программа может падать на совершенно нормальных участках и через много времени от того момента, как память испортилась.
Я уже много раз проверял перепроверял. Строку не куда не передавал, просто генерировал, при чес оставил только:
Код
C++ (Qt)
boost::posix_time::from_time_t(m_session.timeStamp)
Так вот при одном потоке эта строчка работает нормально, при нескольких потоках падает. Я уже начинаю бояться использовать все возможности буста, ибо это меня огорчает. Если память и портит то только эта строка, при использовании ее в stringstream.


Название: Re: Странная ошибка SIG SEGV
Отправлено: Alex Custov от Апрель 02, 2012, 17:19
Я уже много раз проверял перепроверял. Строку не куда не передавал, просто генерировал, при чес оставил только:
Код
C++ (Qt)
boost::posix_time::from_time_t(m_session.timeStamp)

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


Название: Re: Странная ошибка SIG SEGV
Отправлено: RealDuke от Апрель 10, 2012, 10:49
какая версия Qt, какая ось?
4.8.0 Windows 7
Если ещё актуально, прочитай мою тему http://www.prog.org.ru/index.php?topic=21566.msg149874;topicseen#new
Вдруг поможет, подсунь библиотеки от 4.7.4.


Название: Re: Странная ошибка SIG SEGV
Отправлено: Bepec от Апрель 10, 2012, 10:50
Ппц человек ;) проблему уже решили, а он пишет и пишет ;)


Название: Re: Странная ошибка SIG SEGV
Отправлено: vbi от Апрель 10, 2012, 14:58
Если честно, так и не решили. Так и не нашел где у меня память портится.
Цитировать
Проблема вылета - при парсинге URL "http://' отбрасывается "http:" и идёт поиск "//"

Вот только в момент вызова ф-ции QString.indexOf() у строки из 2 (двух) слешей из-за испорченной памяти длина где то "-1655874695" рандомно Улыбающийся Собственно там и выпадает программа в осадок.
Отлаживал, смотрел, так и не наткнулся ни на строку с двумя слешами. Проверял длинну .length() - всюду длинна была нормальной.


Название: Re: Странная ошибка SIG SEGV
Отправлено: Bepec от Апрель 10, 2012, 15:34
Вы хоть читаете, уважаемый vbi???

Где портится память зависит от системы/количества памяти/запущенных программ/использованной памяти и т.п.

На другом компьютере портиться будет, к примеру, размер какого-нибудь массива. На третьем будет портиться левая программа, и она будет умирать. На четвёртом система уйдёт в синий экран. На пятом в заголовке вашей программы изменится третья по счёту буква. На шестом испортится указатель this и прога упадёт ещё до запуска и т.п.

Потому порча памяти так и опасна - она не имеет чётко выраженной границы действия. На отдельно взятом компе она может повторятся. А на другом всё будет работать как часы. До того момента, как испортит ещё что-либо.

PS на моём компе и с моей конфигурацией чаще всего портится размер строки. И это ещё не значит, что если вставить туда проверку и продолжить программу дальше, память не будет представлять фарш из предсмертных воплей байтов.


Название: Re: Странная ошибка SIG SEGV
Отправлено: Alex Custov от Апрель 10, 2012, 16:01
На третьем будет портиться левая программа, и она будет умирать.

Кто, левая программа?


Название: Re: Странная ошибка SIG SEGV
Отправлено: V1KT0P от Апрель 10, 2012, 18:54
На третьем будет портиться левая программа, и она будет умирать.
FAIL. У каждой программы свое виртуальное пространство и чужое пространство вот так испортить нельзя.


Название: Re: Странная ошибка SIG SEGV
Отправлено: Bepec от Апрель 10, 2012, 20:08
Виктор ты в это 100% уверен?

Я лично ронял своей программой ворд/ексцель и иже с ними 2007.
Windows 7 уходит в синий экран частенько.

Нет, я знаю как раздаётся память ;)


Название: Re: Странная ошибка SIG SEGV
Отправлено: V1KT0P от Апрель 10, 2012, 20:38
Виктор ты в это 100% уверен?

Я лично ронял своей программой ворд/ексцель и иже с ними 2007.
Windows 7 уходит в синий экран частенько.

Нет, я знаю как раздаётся память ;)
Тогда набросай примерчик который валит что-то кроме себя.


Название: Re: Странная ошибка SIG SEGV
Отправлено: Bepec от Апрель 10, 2012, 20:55
Сорри ;)

Примерчик дать не могу, ибо у меня проект рабочий, коммерческий. Комплекс из примерно 20 модулей ;)


Название: Re: Странная ошибка SIG SEGV
Отправлено: V1KT0P от Апрель 10, 2012, 21:03
Сорри ;)

Примерчик дать не могу, ибо у меня проект рабочий, коммерческий. Комплекс из примерно 20 модулей ;)
Тогда расскажи как это должно получиться теоретически?
У каждого процесса виртуальное пространство. Оно разбито на страницы, те страницы что выделены указывают на какое-то пространство оперативной памяти, не что не выделены указывают куда-то в ноль или типа того. И если попытаться писать в невыделанные страницы то ОС скорее всего грохнет такое наглое приложение. Вот и получается что программа может писать только туда куда разрешили. Вот и спрашивается как она может записать в чужой процесс?
Ведь не зря же добавляли shared memory, ибо просто так обратиться к памяти чужого процесса не получится. Тут даже топик был о том что нельзя по указателю прочитать данные из чужого процесса.


Название: Re: Странная ошибка SIG SEGV
Отправлено: Bepec от Апрель 10, 2012, 23:03
Прочитать нельзя с другого приложения, но...

Но можно испоганить функции своего адресного пространства, соответственно вызвав целую серию сбоев и ошибок + вызов winApi функций с стрессовыми параметрами и прочим.

К сожалению в глубины сих действий я не лазил, но поступлю как еврей:

Как программа может убить систему в BSOD, если ей доступна только своя память? :)

PS Причём что она может убить и убивает - не обсуждается. Это есмь факт. 


Название: Re: Странная ошибка SIG SEGV
Отправлено: Igors от Апрель 11, 2012, 12:22
Ну вот, поймали Bepecа на неаккуратной фразе и рады  :)

Возвращаясь к теме: конечно критиковать легко, недостатки очевидны: архитектуры нет, есть просто "блюдо спагетти" (слот/сигнал это провоцирует/поощряет). А как надо было делать правильно? Я не могу сказать потому что далек от веба и др (и слава богу).


Название: Re: Странная ошибка SIG SEGV
Отправлено: Bepec от Апрель 11, 2012, 13:13
Ааа... меня поймали на правде! ;)

А по теме - не видел и не представляю пока себе программу в вебе, которая оперирует сразу 20+ потоками. Просто не вижу смысла и необходимости.

А так Igors пришёл и указал на то, что мы не замечали - архитектурку то надо пересмотреть ТС'су ;)


Название: Re: Странная ошибка SIG SEGV
Отправлено: Igors от Апрель 11, 2012, 13:47
А так Igors пришёл и указал на то, что мы не замечали - архитектурку то надо пересмотреть ТС'су ;)
Замечать-то замечали, но вот предлагать правильную почему-то не спешили. А давать указания автору темы (типа "ну ты персмотри") каждый может  :)


Название: Re: Странная ошибка SIG SEGV
Отправлено: V1KT0P от Апрель 11, 2012, 13:50
Если честно, так и не решили. Так и не нашел где у меня память портится.
Цитировать
Проблема вылета - при парсинге URL "http://' отбрасывается "http:" и идёт поиск "//"

Вот только в момент вызова ф-ции QString.indexOf() у строки из 2 (двух) слешей из-за испорченной памяти длина где то "-1655874695" рандомно Улыбающийся Собственно там и выпадает программа в осадок.
Отлаживал, смотрел, так и не наткнулся ни на строку с двумя слешами. Проверял длинну .length() - всюду длинна была нормальной.

Ты говорил что:
Заметил странную особенность. Как Вы заметили этот фрагмент программы, который я выложил парсит каталог DMOZ. Но если его переписать таким образом, чтоб он парсил другой сайт (например Яндекс) - данная ошибка ни разу не наблюдалась. По крайней мере количество возвращенных результатов было около 150 000 и было остановлено вручную.
Может при парсинге DMOZ для какой-то страницы запрашивает авторизацию, что приводит к падению? Логируй запросы и ответы, может что интересное прояснится.


Название: Re: Странная ошибка SIG SEGV
Отправлено: Bepec от Апрель 11, 2012, 13:53
Я бы всё же переписал поток. Всё равно он один, немного работы.

А так ещё бы советовал максимум 3-5 потоков ;) И того, взаимодействие отработать :)