Обработка нулевых указателей в AIX с помощью GCC C - PullRequest
7 голосов
/ 24 января 2012

У нас есть код, написанный на C, который иногда не очень хорошо обрабатывает нулевые указатели.

Код был изначально написан на Solaris, и такие указатели вызывают ошибку сегментации. Не идеально, но лучше, чем пахать.

Наш опыт показывает, что если вы читаете из нулевого указателя в AIX, вы получаете 0. Если вы используете компилятор xlc , вы можете добавить опцию -qcheck=all для перехвата этих указателей. Но мы используем gcc (и хотим продолжать использовать этот компилятор). gcc предоставляет такую ​​возможность?

Ответы [ 2 ]

6 голосов
/ 24 января 2012

Предоставляет ли gcc такую ​​опцию?

Я смущенно отвечаю на вопрос нет, это не .Хотя я не могу сослаться на отсутствие информации, касающейся проверок gcc и NULL времени выполнения.

Проблема, с которой вы сталкиваетесь, заключается в том, что вы пытаетесь сделать неопределенное поведение немного более определенным вплохо написанная программа.

Я рекомендую вам прикусить пулю и либо переключиться на xlc, либо вручную добавить NULL проверки в код, пока не будет найдено и удалено плохое поведение.

Рассмотрим:

  • Создание макроса для нулевой проверки указателя
  • Добавление этого макроса после назначения указателя
  • Добавление этого макроса в записьточка функций, принимающих указатели

По мере удаления ошибок вы можете начать удалять эти проверки.

3 голосов
/ 24 января 2012
  1. Пожалуйста, сделайте нам одолжение и добавьте правильные NULL чеки к своему коду. Вы не только получите небольшой прирост производительности, проверяя NULL только при необходимости, вместо того, чтобы компилятор выполнял проверку везде , но ваш код будет более переносимым на другие платформы.

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

  2. AIX использует концепцию NULL-страницы. По существу, NULL (то есть виртуальный адрес 0x0) сопоставляется с местоположением, которое содержит целую группу нулей. Это позволяет код манипуляции со строкой e.t.c. продолжить, несмотря на обнаружение указателя NULL.

    Это противоречит большинству других Unix-подобных систем, но это не является нарушением стандарта C, который считает разыменование NULL неопределенной операцией . Однако, на мой взгляд, это ужасно сломано: оно берет приложение, которое сильно аварийно завершает работу, и превращает его в приложение, которое молча игнорирует ошибки программирования, что может привести к совершенно неправильным результатам.

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

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

Итог: Не думаю, что вы можете избежать добавления явных NULL проверок.

К сожалению, теперь мы подошли к основному вопросу: Куда следует добавлять проверки NULL? . Я полагаю, что компилятор может добавить такие проверки без разбора, если вы добавите явную проверку при обнаружении проблемы.

К сожалению, в AIX поддержка Valgrind отсутствует. Если у вас есть деньги, возможно, вы захотите взглянуть на IBM Rational Purify Plus для AIX - он может отловить такие ошибки.

Возможно также использовать xlc в тестирующей системе и gcc для всего остального, но, к сожалению, они не полностью совместимы.

...