Как отловить ошибки выравнивания данных на x86 (он же SIGBUS на Sparc) - PullRequest
15 голосов
/ 18 декабря 2009

Можно ли как-то отловить ошибки выравнивания данных даже на i386? Может быть, установив конкретный реестр машин для i386 или что-то в этом роде.

На Solaris-Sparc я получаю SIGBUS в этом случае, но на i386 все хорошо.

Окружающая среда:

  • 32-битное приложение
  • Ubuntu Karmic
  • gcc / g ++ v4.4.1

EDIT : Вот почему я спрашиваю это:

  • наше приложение падает на Sol-Sparc с SIGBUS. Для отладки я бы попытался получить аналогичное поведение на нашей платформе i386.
  • наша машина Sol-sparc работает очень медленно, поэтому компиляция и отладка занимают там много времени. И наша машина i386 невероятно быстра (8 ядер, память 32G).
  • Даже на платформах i386 затраты на устранение ошибок при выравнивании данных снижаются. И поэтому я хотел бы исправить ошибки выравнивания данных, где это возможно.

Ответы [ 6 ]

9 голосов
/ 18 декабря 2009

Тем временем я нашел документ по процессору Intel, посвященный этой теме.

См. Руководство разработчика программного обеспечения для архитектур Intel® 64 и IA-32 .

Кажется, трудно собрать все эти вещи вместе. Однако это не звучит так, как будто это абсолютно невозможно. Интересная глава 4.10.5 Проверка выравнивания

РЕДАКТИРОВАТЬ (некоторые сжатые материалы из упомянутого документа):

стр. 5-60

Interrupt 17 Alignment Check Exception (#AC)

to enable alignment checking, the following conditions must be true:

AM flag is set(bit 18 of control regisster CR0)
AC flag is set (bit 18 of the EFLAGS)
The CPL is 3 (protected mode or virtual-8086 mode).

дополнительно - в 14.8.2.6 - упоминаются ошибки контроллера памяти . Я не знаю, если это то же самое, только другими словами:

table 14-11, Encoding of MMM and CCCC Sub-Fields
Address/Command Error  AC  011
4 голосов
/ 19 декабря 2009

Чтобы подробнее остановиться на ответе Вокухила-Олибы, рассмотрев нить " SOF Mis-aligned pointers on x86. ", кажется, что gcc может генерировать код с неправильным доступом к памяти. AFAIK, у вас нет никакого контроля над этим.

Включение проверок выравнивания в скомпилированном коде gcc было бы плохой идеей. Вы рискуете получить ошибки SIGBUS для хорошего C кода.

Отредактировано: извините за это

3 голосов
/ 19 декабря 2009

Intel очень хорошо поддерживает невыровненные нагрузки. Если бы мне пришлось обнаруживать такие нагрузки на платформе Intel, я думаю, что мне пришлось бы изменить valgrind, чтобы рассматривать невыровненные нагрузки как ошибки. Такая модификация не тривиальна, но valgrind был разработан с учетом того, что пользователи могут создавать новые «инструменты». Я думаю, что простая модификация инструмента memcheck обнаружит ваши не выровненные ссылки. И сообщение об ошибке действительно очень приятно.

3 голосов
/ 18 декабря 2009

Я нашел очень простое решение на SOF! См .: Неправильные указатели на x86 .

int main(int argc, char **argv)
{
# if defined i386
    /* EDIT: enable AC check */
    asm("pushf; "
    "orl $(1<<18), (%esp); "
    "popf;");
# endif

    char d[] = "12345678";  /* yep! - causes SIGBUS even on Linux-i386 */
    return 0;
}

Но я должен признаться, что я не понимаю, почему назначение

char d [] = "12345678";

предполагается неправильно выровненным?

EDIT:

на машине SPARC SIGBUS отсутствует в строке назначения char d [] .

1 голос
/ 27 мая 2017

Спустя много лет: если ваш gcc / clang достаточно новый (GCC 4.9, clang 3.3?), Вы можете создать свой код с помощью неопределенного дезинфицирующего средства поведения (-fsanitize=undefined), чтобы получать предупреждения о неправильном доступе к данным платформа (но имейте в виду, что разные платформы имеют разные требования к выравниванию, разные компиляторы будут выбирать разные макеты и т. д.). Подробнее см. https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html и https://developers.redhat.com/blog/2014/10/16/gcc-undefined-behavior-sanitizer-ubsan/.

0 голосов
/ 18 декабря 2009

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

Редактировать: очень рад быть ошибочным.

...