У меня есть heisenbug, который встречается так редко, что его невозможно воспроизвести ни в одной среде, он не работает впечатляюще, и я не знаю, как его диагностировать.
Ошибка связана с использованием памяти.
Коррупция не вписывается в определенные четыре категории коррупции.
Инструмент показывает, что это не так:
- Неинициализированная память (она была ранее выделена)
- Использование не принадлежащей памяти (она была выделена потоком и принадлежала потоку)
- Переполнение буфера (проход пограничных проверок)
- Неисправное управление памятью кучи (это не утечка, вся память освобождается и защищается нулем)
Я говорю это с некоторой уверенностью, потому что, хотя я не могу воспроизвести это, ведение журнала и инструментарий в средах с более высокими транзакциями показывают, что вышеописанное не происходит.
Я компилирую gcc c11 без оптимизации, Wall, другие минимальные флаги.
ASAN, электрическая изгородь, адская шкура, memcheck, cppcheck не находят проблем.
Управление кучей, кажется, хорошо работает с распределителем пула, проверкой границ, стражей коррупции.
Абсолютно нет юнит-тестов
Проблема в первую очередь проявляется, когда очень редко поврежден массив, установлены недопустимые границы, есть только 50 элементов, но количество элементов искажается, и мы получаем <0 или> 50. Дампы ядра показывают это. Определив, откуда исходит эта привязка массива и проверив правильное значение, мы можем предотвратить эту проблему, но затем проблема переносится в другое место. Так как это влияет только на одного клиента и один тип транзакции, который указывает мне что-то, связанное с этим клиентом или транзакцией Но это дерево не принесло плодов.
Из-за того, как часто это происходит, я не могу исключить:
- Повреждение еще одного потока
- Некоторые условия гонки данных
- Состояние резьбы
- Программирование ошибок записи на место не должно.
Я не могу запустить любой из вышеперечисленных инструментов (ASAN, электрический забор, ...) в среде, которая имитирует условия, которые вызывают это. Но я не могу воспроизвести его в любой среде, в которой я могу запустить эти инструменты.
Мои единственные мысли были бы:
- Создавайте глубокие копии или сериализуйте эти объекты и объединяйте проверки по всей базе кода. (грязно, может быть невозможно из-за ограничений памяти)
- Игнорировать проблему (неравномерное воздействие на одного клиента означает, что я не могу этого сделать)
- Продолжайте играть в пинг-понг и сделайте кодовую базу еще более уродливой со всеми этими проверками ошибок в поисках повреждений.
- Переписать все это на $ Language (не совсем вариант)
- Попробуйте новый распределитель пула или распределителя арены, чтобы увидеть, есть ли неизвестная ошибка в нашей пользовательской.
Я ищу новые подходы к этому, которые я не рассматривал. Способы автоматизации этого, лучший инструмент для решения подобных проблем. Как вы подтверждаете, что объект не изменился за вашей спиной?