2015-02-27 5 views
-3

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

Мы работаем над серверами Linux Linux и кодом в основном C++. Через bt в gdb я смог увидеть, где именно возникает проблема, что подводит меня к вопросу. Файл является автоматически сгенерированным, который не менялся годами. Разница в том, что мы обновили сторонний компонент gSOAP. Перед обновлением сторонней версии он работал нормально как на отладочном, так и на нет.

С флагом отладки проблема исчезает волшебно (для новичков, подобных мне). Я извиняюсь, но его не представляется возможным включить много кода, только строку, которая является:

/*------------------------------------------------------------. 
| yynewstate -- Push a new state, which is found in yystate. | 
`------------------------------------------------------------*/ 
yynewstate: 
    /* In all cases, when you get here, the value and location stacks 
    have just been pushed. So pushing a state here evens the stacks. */ 
    yyssp++; 

yysetstate: 
    *yyssp = yystate; <------------------ THIS LINE 

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

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

+1

Мы не знаем, на что указывает 'yyssp', или как большой буфер переполняется - если он был инициализирован вообще. Просто невозможно сказать, что происходит с этим маленьким кодом. –

+0

@Paul Я упоминаю, что я не могу включить больше кода, вопрос более общий, как программа может работать нормально при компиляции в режиме отладки и не запускаться при компиляции в обычном режиме. , конечно, вы не можете понять из этого кода, я хочу понять лес, а не дерево. – thahgr

+1

И есть бесконечное количество причин, которые могут произойти. Мы можем начать случайным образом воображать некоторые из них, но это не поможет. Каждая вещь из '#ifdef DEBUG' блокирует компиляторам, инициализирующим переменные для отладки, которые не инициализируются в оптимизированных сборках, в разные библиотеки отладки/выпуска, чтобы ... –

ответ

-3

Кто-то в моей команде нашел временное решение для этого, Это были флаги оптимизации, с которыми эта библиотека строится.
По умолчанию для нашей сборки было -O2 во время отладки этих изменений.

Создание библиотеки с помощью -O0 (изменение файла makefile) обеспечивает временное решение.

+0

Это не «решение», временное или иное. Ваш код _broken_ и все равно может сломаться в любой момент. На самом деле вы даже не притворились, что решили проблему «разрывов кода в сборках релизов», потому что все, что вы делаете сейчас, это _not make release builds_. Человеку в вашей команде нужно дать суровый разговор с ... –

+0

Извините, но это не исправление. Вы внимательно прочитали мой ответ, касаясь внесения изменений в код (генерируемый код или исходный код), и все начинает «работать»? Код не работает - все, что вы сделали, это изменить код, так что теперь ошибка переместилась где-то в другом месте. – PaulMcKenzie

4

Во-первых, имейте в виду, что вы используете C++, а не Java или любой другой язык, где работа вашей программы всегда предсказуема, даже проблемы времени выполнения предсказуемы.

В C++ вещи не предсказуемый, как на этих языках. Просто потому, что ваша оригинальная программа не менялась годами, это не значит, что программа была безошибочной. Вот как работает C++ - вы считаете, что у вас есть безошибочная программа, и на самом деле она не является безошибочной.

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

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

Одна вещь, которую вы должны не do - если вы делаете совершенно неактуальное изменение кода и магически работает ваша программа, не утверждайте, что проблема исправлена ​​или разрешена. Нет - проблема не исправлена ​​- вы либо замаскировали ее, либо ошибка переместилась в другую часть вашего кода, скрытую от вас. Каждое исправление, которое влечет за собой такие вещи: должно быть обоснованным как , почему исправление устраняет проблему.

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

+0

Программы Java не всегда предсказуемы. Темы были бы очевидным примером непредсказуемого поведения, но любая зависимость от внешних ресурсов может вызвать это; подумайте о файловых системах или сетевых подключениях. И давайте не будем забывать о местных методах и финализаторах. Дело в том, что только потому, что кто-то используется для Java, не следует предполагать, что этот человек не понимает выполнение недетерминированных программ. –

+1

Да, нити и внешние вещи, происходящие, - это одно. То, что я имею в виду, - это неопределенное поведение, присущее языку C++. Это не так с Java. Неопределенное поведение, как часть спецификации языка, не встречается на слишком многих других языках, кроме C и C++. – PaulMcKenzie

+0

@PaulMcKenzie, спасибо, что нашли время, чтобы написать широкий ответ, вы были полезны – thahgr