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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Поиск краша  (Прочитано 13135 раз)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« : Август 13, 2016, 10:55 »

Добрый день

Не самый плохой, но достаточно мерзкий случай: вылетает раз в 2-3 дня, когда уже успеваю забыть о нем.  Подробности

1)
Цитировать
Нужен код т.т.п.
Увы, это "не транспортабельно"

2) Краш происходит всегда в одном месте, на выходе из большого (неск сотен строк) статического метода писаного  не мной. Отладчик показывает что летит на деструкторе ~std::string - верить этому необязательно. Ну конечно просмотрел все используемые string, окружил их проверками, но зацепиться за что-то не удалось. Полезные symbolic breakpoint (часто с их помощью удается найти повторное удаление и.т.п.) в этот раз молчат

3) Пытался зациклить ф-цию (с одним и тем же входом и разными) чтобы спровоцировать вылет - нет, и полчаса работает, не летит.

Что можно предпринять?

Спасибо
Записан
Bepec
Гость
« Ответ #1 : Август 13, 2016, 11:14 »

Покряхтев, можно натыкать логов много, от слова "дофига". И после очередного краха смотреть по логам где точно произошёл вылет.
Но и это не гарантирует результат, ибо память может портиться где нить в первом часу, а вылет произойдёт во втором Веселый
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #2 : Август 13, 2016, 13:03 »

У вас поломка, скорее всего далеко не в этом месте. Просто так везёт, что перенаправляет в деструктор строки. Я бы поискал объекты, которые могли бы рядом с этой строкой в стэке стоять. Быть может запись за пределами массива происходит. Вообще, valgrind в помощь.
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #3 : Август 13, 2016, 13:09 »

Расход памяти проверить стоит.
У нас была с этим проблема - вылетало раз в 2-3 недели.
Выяснилось, что при определенных условиях просто не хватало памяти.
Да, еще очень помогают вещи вроде breakpad и crashrpt.

https://chromium.googlesource.com/breakpad/breakpad/

http://crashrpt.sourceforge.net/
« Последнее редактирование: Август 13, 2016, 13:13 от Racheengel » Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
_Bers
Бывалый
*****
Offline Offline

Сообщений: 486


Просмотр профиля
« Ответ #4 : Август 13, 2016, 15:25 »

Что можно предпринять?

1.
отладчики умеют брякаццо на факт изменения значения по адресу.

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

ну а дальше нужно пасти - кто меняет.
почему, и на каком основании.

то есть смотрим стек вызовов.
может быть кто-то из соседнего потока накосячил?

2.
техника отладки называется "хвостик".

смысл идеи в том, что бы выявить факт пробоя памяти.
для этого нужно подвинуть аварийный объект в сторонку:
Код:
int main()
{
    std::string ololo;
}

Код:
int main()
{
    int border1[255];
    std::string ololo;
    int border2[255];
}

если после этого баг c деструктором перестанет воспроизводится,
значит действительно пробой памяти.

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

строка выживает.
но скорее всего краш будет где-то дальше
(а может и не будет)

3.
дебажный велосипед.
в отдельном потоке состояние строки постоянно мониторится.
идет проверка: находится ли строка в консистентном состоянии,
или уже нет.

если уже в неконсистентном состоянии (содержит запрещенные символы, size слишком большой, etc),
то исполнение уходит на ветку кода, где стоит обычная бряка.
ну а дальше см пункт 1.

===========================================


вам в любом случае нужно зафиксировать факт изменения строки,
после которого она становится в неконсистентном состоянии.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Август 13, 2016, 15:43 »

вы знаете, какой объект у вас слетает.
К сожалению - пока нет

отладчики умеют брякаццо на факт изменения значения по адресу.
...
значит можете поставить бряку на его изменение.
Пока эти попитки ни к чему не привели - отладчик (gdb) просто вешается намертво 

смысл идеи в том, что бы выявить факт пробоя памяти.
для этого нужно подвинуть аварийный объект в сторонку:
Да, реагирует на изменения в коде. Вот уже неск дней нету после того как я добавил тестовую печать по if

дебажный велосипед.
в отдельном потоке состояние строки постоянно мониторится.
идет проверка: находится ли строка в консистентном состоянии,
или уже нет.
Строка (если это строка, пока не факт) - одна из локальных переменных, которых в ф-ции десятка полтора, многие контейнеры. Т.е. возможно и строка - но не та что в ф-ции, а член класса одного из эл-тов контейнера.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #6 : Август 13, 2016, 16:00 »

Довольно-таки странно, что до сих пор не прогнали через valgrind.
Записан

Qt 5.11/4.8.7 (X11/Win)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #7 : Август 13, 2016, 16:53 »

Довольно-таки странно, что до сих пор не прогнали через valgrind.
Он на OSX не очень - захлебывается при выделениях 500 метров и выше. Да и что там хотим увидеть - "разрушен блок памяти <адрес>"? Это мне и так бы сообщили в gdb, но в данном случае этого нет.
Записан
_Bers
Бывалый
*****
Offline Offline

Сообщений: 486


Просмотр профиля
« Ответ #8 : Август 13, 2016, 17:02 »

Да и что там хотим увидеть - "разрушен блок памяти <адрес>"? Это мне и так бы сообщили в gdb, но в данном случае этого нет.

зная адрес пробитого блока,
можно с точностью установить что за объект был подбит.
зная этот объект, можно поставить бряку на его изменение.
и отловить момент этого изменения.
станет видно кто именно постарался.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #9 : Август 13, 2016, 17:57 »

зная адрес пробитого блока,
можно с точностью установить что за объект был подбит.
зная этот объект, можно поставить бряку на его изменение.
и отловить момент этого изменения.
станет видно кто именно постарался.
Убрал все тестовые печати - и вылет довольно быстро объявился. Пришел к выводу что да, испорчена строка, локальная переменная в ф-ции. Хмм... ну и как на нее поставить "бряку"? Адреса-то я не имею до входа в ф-цию. Опять налепил тестовых печатей - и опять вылет не появляется...
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #10 : Август 13, 2016, 18:36 »

А дебажный вывод где стоит? до проблемной строки или после?
Если "до" строки воткнуть какой-нибудь безвредный ничонеделающий мусор вместо дебага - эффект тот же?
Я бы все же попробовал брекпадом - хотя не знаю, как он на макаке себя вести будет, но на винде нам эта тулза пару раз хорошо помогла.
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
_Bers
Бывалый
*****
Offline Offline

Сообщений: 486


Просмотр профиля
« Ответ #11 : Август 13, 2016, 20:07 »

Убрал все тестовые печати - и вылет довольно быстро объявился. Пришел к выводу что да, испорчена строка, локальная переменная в ф-ции. Хмм... ну и как на нее поставить "бряку"? Адреса-то я не имею до входа в ф-цию. Опять налепил тестовых печатей - и опять вылет не появляется...
[/quote]

лично я в вижуал студии сделал бы так:
в пошаговой отладки докатился бы до отлаживаемой функции,
и брякнулся бы где нибудь в самом начале.

далее:
Debug -> New Breakpoint -> New Data Breakpoint

в открывшемся диалоге вбил адрес охраняемого объекта:
&myVariable

после чего как только произойдет изменение содержимого адреса отлаживаемого объекта,
сработает бряк.


насчет вас не знаю.
я не телепат.

Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #12 : Август 14, 2016, 10:59 »

Вот она, сучка

Код
C++ (Qt)
char line[8192];
std::string baseName;   // эта переменная иногда убита
...
 
while(!file.eof() && file.good())
{
file.getline(line, 8192, '\n');
 
// remove any trailing \r
if (line[strlen(line) - 1] == '\r')
line[strlen(line) - 1] = '\0';
 
// ignore blank lines
if (strlen(line) == 0)
continue;
 
 
Исправил так
Код
C++ (Qt)
while(!file.eof() && file.good())
{
file.getline(line, 8192, '\n');
size_t sLen = strlen(line);
 
// remove any trailing \r
if (sLen && line[sLen - 1] == '\r')
line[sLen - 1] = '\0';
 
// ignore blank lines
if (strlen(line) == 0)
continue;
 
 
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #13 : Август 14, 2016, 13:46 »

Вот она, сучка
Да уж, такой код иначе и не назовёшь.
Записан

Qt 5.11/4.8.7 (X11/Win)
qate
Супер
******
Offline Offline

Сообщений: 1177


Просмотр профиля
« Ответ #14 : Август 14, 2016, 18:45 »

Вот она, сучка

И зачем при наличии qt использовать сишные споособы работы ?
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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