стек вызовов показывает SIGBUS, что это значит

Мой стек вызовов показывает следующее:

 --- called from signal handler with signal 10 (SIGBUS) ---
 001301b8 allocate__t24__default_alloc_template2b0i0Ui (20, 20, 309940, 36, fc55
1a00, 0) + a4
 0011dcb8 __nw__Q2t12basic_string3ZcZt18string_char_traits1ZcZt24__default_alloc
_template2b0i0_3RepUiUi (10, 10, 7773e8, 0, 0, 0) + 14
 0011dcf8 create__Q2t12basic_string3ZcZt18string_char_traits1ZcZt24__default_all
oc_template2b0i0_3RepUi (a, a, 7773e8, a, 0, 0) + 24
 0011e0bc replace__t12basic_string3ZcZt18string_char_traits1ZcZt24__default_allo
c_template2b0i0UiUiPCcUi (fbcff5c0, 0, ffffffff, fcbf55e2, a, 80808080) + 114
 00133ef0 assign__t12basic_string3ZcZt18string_char_traits1ZcZt24__default_alloc
_template2b0i0PCcUi (fbcff5c0, fcbf55e2, a, ffffffff, ffffffff, 20) + 24
 00132c78 assign__t12basic_string3ZcZt18string_char_traits1ZcZt24__default_alloc
_template2b0i0PCc (fbcff5c0, fcbf55e2, 15b0, 15d0, 16f0, 0) + 24
 0012f970 __t12basic_string3ZcZt18string_char_traits1ZcZt24__default_alloc_templ
ate2b0i0PCc (fbcff5c0, fcbf55e2, fcbf55d8, fbcff70e, 10, e00) + 28
 001f7e0c getFiles__7ListDirb (fbcff8e4, 0, 241000, 0, 4e61a0, ff11f478) + 144
. . .

Означает ли это, что сбой выделения означает, что слишком много памяти занято? Как я могу проверить/отследить увеличение и уменьшение использования памяти, чтобы выяснить, в чем заключается проблема в таких случаях? Могу ли я переопределить allocate__t24__default_alloc_template2b0i0Ui, т.е. __default_alloc_template<false, 0>::allocate(unsigned int), чтобы он вызывал пользовательский вызов выделения?


person Dr. Debasish Jana    schedule 25.08.2017    source источник
comment
Как и в случае почти любого сбоя, вы должны использовать отладчик, чтобы поймать его, и подниматься по стеку вызовов, пока не доберетесь до своего кода, где вы проверяете все задействованные переменные, чтобы убедиться, что они верны. Всегда полезно знать, где происходит сбой в вашем коде. Я также рекомендую вам прочитать Как отлаживать небольшие программы Эрик Липперт.   -  person Some programmer dude    schedule 25.08.2017
comment
Эта проблема возникает после обработки большого объема данных, может ли это быть из-за нераспределенной памяти?   -  person Dr. Debasish Jana    schedule 25.08.2017
comment
Вы можете узнать больше об ошибках шины.   -  person Some programmer dude    schedule 25.08.2017
comment
Это означает, что у вас есть ошибка в вашем коде.   -  person Sam Varshavchik    schedule 25.08.2017
comment
И если вы используете Solaris на SPARC, SIGBUS почти наверняка вызвано неправильным доступом к памяти. Это может быть вызвано повреждением кучи, которое обычно обнаруживается кодом libc в разделе malloc()/free()/ et al, переполнением стека, приводящим к повреждению адреса возврата на недопустимый адрес таким образом, что SIGBUS вместо SIGSEGV (редко, но бывает) или просто нарушение строгого алиасинга в собственном коде.   -  person Andrew Henle    schedule 25.08.2017


Ответы (1)


стек вызовов показывает SIGBUS, что это значит

Вероятно, было бы полезно показать верхнюю часть стека вызовов, чтобы мы могли проверить выравнивание указателей. Также было бы полезно знать платформу и инструкцию, вызвавшую ошибку SIGBUS.

Мой опыт SIGBUS часто связан с невыровненными данными. Прежде чем спуститься в кроличью нору, попробуйте добавить -xmemalign=4i или -xmemalign=8i к CFLAGS и CXXFLAGS.

Кажется, я припоминаю, что у Sparc есть инструкция, которая может более эффективно работать с более широкими данными, но очень чувствительна к выравниванию. Если вы преобразуете uint8_t* в uint32_t* или uint64_t*, то этот буфер на самом деле необходимо выровнять, потому что SunCC будет генерировать более эффективное перемещение по умолчанию. Это строгое нарушение алиасинга, о котором говорит Андре. Sun не похож на x86, и он также будет SIGBUS, если вы сжульничаете.

См. также B.2.111 -xmemalign=ab в руководстве Sun. Есть также много хороших результатов для Google "-xmemalign=4i". Загвоздка в том, что пока вы не столкнетесь с проблемой и не доберетесь до ее сути, вы не знаете, что вам нужно искать.

(Я провел месяцы, пытаясь найти один сбой на Sparc во время самопроверки, и это произошло из-за грязного приведения и более широкой инструкции по перемещению. -xmemalign=4i исправил это для меня).

person jww    schedule 26.08.2017
comment
Обратите внимание, что вы должны исправить проблему выравнивания памяти, а не использовать обходной путь с флагом компилятора, если это критически важный для производительности код, поскольку выравнивание существует по уважительной причине. - person cb88; 31.08.2017
comment
@ cb88 - да, согласен. Для нас это было вызвано общедоступным кодом, который приводил массив 32-битных слов к 64-битному указателю на слово. Я не хотел переписывать подпрограмму, которая была кодом SHA-1. Но в глубине души я знаю, что код неверный :( - person jww; 31.08.2017
comment
Интересно также услышать о реальных примерах этого... кажется странным делать приведение массива к указателю другого типа... поскольку массивы уже эффективно являются указателями. - person cb88; 31.08.2017