Как устранить ошибку сегментации, вызванную оптимизацией компилятора g cc, при настройке centos dual compiler - PullRequest
0 голосов
/ 24 февраля 2020

У меня большой программный проект на C ++ с g cc. После добавления некоторого нового кода в репозиторий один из двоичных файлов начал получать Сегментационную ошибку на больших тестовых данных (без сегментальной ошибки на нескольких меньших тестовых входах). Я проверил на нескольких разных аппаратных средствах с двумя разными системами. Ubuntu 18 и Centos6. G CC проверено компилятором 6.3, 7.4 и 9.2. Бинарная сборка на Ubuntu всегда хороша, а на Centos всегда плоха (segfault). Операционная система создает проблемы:

uname -a
Linux hostname 3.10.0-957.27.2.el7.x86_64 #1 SMP Mon Jul 29 17:46:05 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux 

Мой Unbuntu имеет один компилятор, но в Cenos обычно используется старый g cc 4.8, и вдобавок к этому мы собираем 6.3, 7.4 или 9.2. Мой код C ++ был собран с различными версиями g cc и на разных аппаратных средствах, все получили segfault на

std::ostream& operator(ostream&, const string&);

, но из одного из нескольких случайных мест в моем коде. Я использовал опцию -O2 или -O3. При использовании опции -O0 бинарный файл не имеет проблем, но в несколько раз медленнее. Я пытаюсь сгенерировать производственный код, который должен быть быстрее.

Я знаю, что одно из решений - выяснить, какая строка кода вызывает эту ошибку сегментации, и я попробую позже. Мой вопрос заключается в том, есть ли какая-либо опция при создании компилятора g cc, которая может помочь решить эту проблему segfault?

Я последовал предложению (предоставьте в разделе комментариев ниже), включив полное предупреждение и обновив все зависимые библиотеки с предупреждением тоже (включая повышение). Похоже, это решило проблему. Я усвоил большой урок: любой код, который мы пишем, должен пройти pedanti c Wall. Кто-то должен написать ответ, чтобы помочь другим программистам.

1 Ответ

0 голосов
/ 25 марта 2020

Никто больше не ответил на этот вопрос. Я обобщу свой опыт здесь без каких-либо конкретных кодов. Сначала я протестировал на centos6, где исходный g cc был 4.8, и я собрал последний компилятор g cc 9.2 из gcc7.4. На этой машине двоичные сборки с компилятором 9.2 имеют ошибку сегментации только при использовании опций -O. Segfault всегда находится в std ostream & operator << (ostream &, const string &). После того, как я просмотрел весь свой код и всю библиотеку, использованную моим кодом, и удалил все предупреждения, ошибка сегментации исчезла. Я проверил около сотни входных файлов и все закончил программу со статусом выхода 0. Как ни странно, ошибка сегментации изначально возникает только в моей системе cento6. Мой Ubuntu18 работает нормально даже до удаления всех предупреждений компилятора и с опциями -O1-3. </p>

Недавно я сделал несколько небольших обновлений в моем коде, теперь я начал видеть ту же ошибку сегментации ТОЛЬКО на моем Ubuntu18 (с компилятором g cc 7.4). Оптимизация -g O1, O1, O2, O3 - все дало ошибку сегментации. -g O0 произвел код без проблем. Теперь Centos6 подходит для любой оптимизации.

Поскольку местоположение ошибки сегментации находится внутри стандартной библиотеки lib, отладочный прогон не показывает никакой полезной информации о том, где причина ошибки. Единственное оставшееся решение - закомментировать другой кусок кода, чтобы определить, какой фрагмент кода вызывает ошибку сегментации. Это оказывается полезным.

После прочтения 4 строк кода, вызвавших ошибку сегментации. Я сразу понял, какая строка вызвала проблему:

// samearray is array<int,4> somearray;
somearray[4]=someNumber;

Таким образом, сообщение возврата домой - это когда ошибка сегментации пытается ввести вас в заблуждение об «оптимизации компилятора», «разных операционных системах», «другом компиляторе». версии ", не поддавайтесь искушению и садитесь переваривать свой собственный код, комментируя куски за раз. Я до сих пор не знаю, почему выявление ошибки сегментации связано с опцией оптимизации компилятора. Надеюсь, мои страдания могут помочь другим.

...