Что делает “BUS_ADRALN - Недопустимые ошибочные средства” выравнивания адреса?

Мы находимся на HPUX, и мой код находится в C++. Мы добираемся

BUS_ADRALN - Недопустимое выравнивание адреса

в нашем исполняемом файле на вызове функции. Что делает это ошибочное средство? Та же функция работает много раз затем внезапно свое предоставление дампа ядра. в GDB, когда я пытаюсь распечатать объектные значения, это говорит не в контексте. Какая-либо подсказка, где проверить?

5
задан Micha Wiedenmann 7 November 2018 в 12:06
поделиться

3 ответа

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

Проблема выравнивания данных возникает, когда адрес, на который указывает указатель, не «выровнен» должным образом. Например, некоторые архитектуры (например, старый Cray 2) требуют, чтобы любая попытка прочитать что-либо, кроме одного символа из памяти, происходила только через указатель, в котором последние 3 бита значения указателя равны 0. Если любой из последних 3 бита равны 1, аппаратное обеспечение сгенерирует ошибку выравнивания, которая приведет к проблеме, которую вы видите.

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

Проблемы выравнивания обычно вызываются проблемами того же типа. это может вызвать ошибку SEGFAULT или сегментацию. Обычно указатель не инициализируется. Но это может быть вызвано неправильным распределителем памяти, который не возвращает указатели с правильным выравниванием, или результатом арифметики указателя для указателя, когда он не правильного типа.

Системная реализация malloc и / или operator new почти наверняка верна, иначе ваша программа выйдет из строя намного раньше, чем это произойдет сейчас.Так что я думаю, что плохой распределитель памяти - наименее вероятное дерево, которое может взорваться. Я бы сначала проверил наличие неинициализированного указателя, а затем арифметику с плохим указателем.

В качестве примечания, архитектуры x86 и x86_64 не имеют никаких требований к согласованию. Но из-за того, как работают строки кеша, и по ряду других причин, часто для повышения производительности полезно выровнять данные по границе, размер которой равен сохраняемому типу данных (т. Е. 4-байтовая граница для 32-битного int).

11
ответ дан 18 December 2019 в 10:41
поделиться

На самом деле у HP-UX есть свой собственный отличный форум на ITRC, и некоторые сотрудники HP очень полезны. Я только что просмотрел ту же тему, о которой вы спрашиваете, и вот некоторые результаты. Например, аналогичная проблема была вызвана плохим входным параметром. Я настоятельно советую вам сначала прочитать ответы на аналогичный вопрос и, если необходимо, разместить свой вопрос там.

Кстати, вполне вероятно, что вас попросят выложить результаты этих gdb команд:

(gdb) bt
(gdb) info reg
(gdb) disas $pc-16*8 $pc+16*4
1
ответ дан 18 December 2019 в 10:41
поделиться

Большинство процессоров (не x86 и друзья... blacksheep of the family lol) требуют выравнивания доступа к определенным элементам на кратные байты. Например, если вы читаете целое число с адреса 0x04, то это нормально, но если вы попытаетесь сделать то же самое с адреса 0x03, то вызовете прерывание.

Это происходит потому, что проще реализовать аппаратные средства загрузки/сохранения, если они всегда кратны размеру данных, с которыми вы работаете.

Поскольку HP-UX работает только на RISC-процессорах, которые обычно имеют такие ограничения, вы должны видеть здесь -> http://en.wikipedia.org/wiki/Data_structure_alignment#RISC.

3
ответ дан 18 December 2019 в 10:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: