Пятилетний баг убит ?!
От: кубик  
Дата: 12.09.20 15:14
Оценка:
Друзья, подскажите, можно ли так делать ?

it — итератор мультимапа. В процессе перебора элементов выясняется что текущее значение it указывает на элемент который надо освободить и убрать из мульмапа.
я делаю:

delete it->second <- Тут освобождается объект типа А
потом делаю it = my_multimap.erase(it);

Так можно ? Я замучан багом Это единственное подозрительное место!
В принципе все работает, но иногда, очень редко в конце работы после тотальной итерации уничтожения счетчик объектов указывает что парочка объектов типа А еще жива.
Re: Пятилетний баг убит ?!
От: watchmaker  
Дата: 12.09.20 15:59
Оценка: 6 (1) +6 -1
Здравствуйте, кубик, Вы писали:

К>it — итератор мультимапа. В процессе перебора элементов выясняется что текущее значение it указывает на элемент который надо освободить и убрать из мульмапа.

К>я делаю:

К>delete it->second <- Тут освобождается объект типа А

К>потом делаю it = my_multimap.erase(it);

К>Так можно ?


Если у тебя там сырой указатель, который последним указывает на конкретный экземпляр типа A (то есть, если вся мультимапа имеет какой-то такой тип: std::multi_map<key_type, A*>), то можно и нужно.
Другое дело, что откуда там вообще взялся delete и сырой указатель в 2020-м году?! Использование delete не должно выходить за пределы реализации библиотек по управлению памятью.
То есть почему у тебя изначально не std::multi_map<key_type, std::unique_ptr<A>>, например? Тогда и явный delete не нужен, и за удалением сам unique_ptr проследит и не забудет его сделать.
Re: Пятилетний баг убит ?!
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 12.09.20 16:56
Оценка: 6 (1) +1
Здравствуйте, кубик, Вы писали:

К>it — итератор мультимапа. В процессе перебора элементов выясняется что текущее значение it указывает на элемент который надо освободить и убрать из мульмапа.

К>я делаю:
К>delete it->second <- Тут освобождается объект типа А
К>потом делаю it = my_multimap.erase(it);

Если тип значения в мапе это голый указатель — это нормально, но тогда подозрительно само использование голого указателя (проблемно ситуациями с потерей при вылетающих исключениях).
Если что-то другое, то erase() должно вызвать удаление (сюда включается какой-то объектный тип напрямую и варианты типа unique_ptr, shared_ptr).
Само же присвоение типа it = my_multimap.erase(it) не имеет явной проблемы.

К>Так можно ? Я замучан багом Это единственное подозрительное место!

К>В принципе все работает, но иногда, очень редко в конце работы после тотальной итерации уничтожения счетчик объектов указывает что парочка объектов типа А еще жива.

Там нет параллельного доступа из разных ниток?
The God is real, unless declared integer.
Re: Пятилетний баг убит ?!
От: ArtDenis Россия  
Дата: 12.09.20 17:06
Оценка: +2
Здравствуйте, кубик, Вы писали:

К>Друзья, подскажите, можно ли так делать ?


Интересно, меня одного интересует, почему у пост так называется?
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re[2]: Пятилетний баг убит ?!
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 12.09.20 19:09
Оценка: :)
Здравствуйте, ArtDenis, Вы писали:

AD>Интересно, меня одного интересует, почему у пост так называется?


Видимо, автор надеется, что сам по себе исчезнет баг в его программе, который он ловит уже 5 лет.
Re: Пятилетний баг убит ?!
От: кубик  
Дата: 13.09.20 03:52
Оценка:
Всес спасибо за ответы.
Попутал ночью после многонедельного дебага.
Естественно так можно делать.. просто думать не начто, уже дебагбриков навтыкал.
Приложение было написано много лет назад старинными мастерами и работало отлично. После этого на протяжении многих лет засиралось велосипедами и костылями.
Теперь я должен победить все известные баги.

netch, Да, тут многониточность, но именно этот мультимэп обёрнут в rw локи. Если оберну только в W локи боюсь баг зароется глубже ... хотя .. чего мне еще боятся ..
Re[2]: Пятилетний баг убит ?!
От: bkat  
Дата: 14.09.20 06:45
Оценка:
Здравствуйте, кубик, Вы писали:

К>netch, Да, тут многониточность, но именно этот мультимэп обёрнут в rw локи. Если оберну только в W локи боюсь баг зароется глубже ... хотя .. чего мне еще боятся ..


Ну тогда проблема скорей всего не в мультимэпе а в том как объекты используются из разных потоков.
Может быть те объекты, которые надо удалить, уже "убиты" каким-нибудь образом при использовании из разных потоков.
Re[2]: Пятилетний баг убит ?!
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 14.09.20 09:08
Оценка: 6 (1) +1
Здравствуйте, кубик, Вы писали:

К>Приложение было написано много лет назад старинными мастерами и работало отлично. После этого на протяжении многих лет засиралось велосипедами и костылями.


Обожаю такие вещи.

К>Теперь я должен победить все известные баги.


Накачивай код ассертами.

Обнуляй указатели после delete.

Переводи динамические объекты на счетчики ссылок (но здесь нужно уметь с ними работать).
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Отредактировано 14.09.2020 9:32 DDDX . Предыдущая версия .
Re[2]: Пятилетний баг убит ?!
От: AleksandrN Россия  
Дата: 14.09.20 11:41
Оценка: 6 (1)
Здравствуйте, кубик, Вы писали:

К>Попутал ночью после многонедельного дебага.

К>Естественно так можно делать.. просто думать не начто, уже дебагбриков навтыкал.

Пробовал использовать valgrind (если пишешь под Linux) или CRT (если пишешь под Windows)? Если пробовал, что они пишут?
Отредактировано 14.09.2020 11:51 AleksandrN . Предыдущая версия .
Re: Пятилетний баг убит ?!
От: кубик  
Дата: 16.09.20 03:50
Оценка: :)
Друзья, баг нашелся!
Проблемма была в некачественном использовании rw-локов. Они кастомные и никто не озабочивался проверять returned value. Иногда они не лочили....
Начал проверять что б после каждого инсерта в мультимап size() должен увеличиваться на 1, ну и обнаружилось несоответствие.

watchmaker, спасибо, все переделано на boost::shared_ptr!
Re[3]: Пятилетний баг убит ?!
От: ArtDenis Россия  
Дата: 16.09.20 16:57
Оценка: 8 (1)
Здравствуйте, AleksandrN, Вы писали:

AN>Пробовал использовать valgrind (если пишешь под Linux) или CRT (если пишешь под Windows)? Если пробовал, что они пишут?


valgrind посоветовал в тему, а вот CRT тут немного сбоку.
Для винды есть кастрированный аналог valgrind — DrMemory https://drmemory.org/ Запускает твоё приложение в своей виртуальной машине (но с jit-компиляцией), старается полностью контролировать обращения к памяти.
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Отредактировано 16.09.2020 16:58 ArtDenis . Предыдущая версия .
Re[2]: Пятилетний баг убит ?!
От: AlexGin Беларусь  
Дата: 17.09.20 08:40
Оценка: +1
Здравствуйте, кубик, Вы писали:

К>watchmaker, спасибо, все переделано на boost::shared_ptr!


А почему же не на std::shared_ptr ?
Я в последние годы — уже как-то и отвык от замечательного boost-а...
Re[3]: Пятилетний баг убит ?!
От: ononim  
Дата: 17.09.20 11:51
Оценка: 8 (1)
gflags:
Как много веселых ребят, и все делают велосипед...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.