#c #debugging #point-cloud-library #memory-alignment #eigen3
#c #отладка #точка-облако-библиотека #выравнивание памяти #eigen3
Вопрос:
В последнее время я постоянно сталкиваюсь со следующей проблемой:
- У меня большая кодовая база, которая использует собственные и PCL (которая также использует собственные)
- Мне нужно использовать почти текущую собственную главную ветку и я не могу использовать стабильный выпуск из-за зависимости, требующей этого.
- Как PCL, так и другие зависимости в моем проекте используют векторные инструкции, поэтому я компилирую
-march=native
. - При выполнении некоторых действий, связанных с собственными типами (аффинные преобразования, просмотр облака точек), я иногда получаю ошибки сегментации или другие сбои в, казалось бы, бессмысленных местах, например, в
Eigen::Quaternionf
конструкторе. В другом случаеEIGEN_UNALIGNED_ASSERT
срабатывает, что приводит к этой странице, содержимое которой я наблюдаю повсюду в своем коде (насколько я знаю)
Я хочу быть хорошим гражданином, поэтому я пытаюсь воспроизвести проблему на минимальном примере для публикации в stackoverflow или в соответствующих трекерах проблем. Однако я неизменно терплю неудачу при воспроизведении сбоя при извлечении только бита, вызывающего проблему. Я предполагаю, что выравнивание памяти или ее отсутствие (и не уделяется особого внимания) также зависит от того, что было выделено до местоположения проблемы, поэтому окружающий код играет важную роль в возникновении проблемы.
Вопрос: Какие методы и инструменты я могу использовать для эффективного определения источника сбоев, связанных с выравниванием памяти, в C 14 в Linux и / или macOS?
Комментарии:
1. Может ли это быть проблемой выравнивания данных? У меня была эта проблема раньше, но я получил не ошибку сегментации, а ошибку AVX напрямую. Выровнены ли ваши данные на 32 бита?
2. я не уверен, как это выяснить, является частью моего вопроса. Предполагая, что в PCL нет ошибок в этом отношении, я бы так подумал, поскольку я использую только типы PCL, но иногда у меня возникает такая же проблема при манипулировании собственными матрицами и векторами 3×3 или 4×4.
3. Я бы настоятельно предположил, что в PCL почти нет ошибок 🙂
4. вы уверены, что правильно распределили данные?
5. Смещенные данные находятся в куче или в стеке? В описании указано, что он находится в стеке, поэтому включение стека вызовов и выравниваний в нем может помочь решить проблему.
Ответ №1:
Я бы настоятельно рекомендовал AddressSanitizer
. Во встроенном приложении у меня однажды было небольшое переполнение стека в буфере, которое имело побочные эффекты только тогда, когда стек был почти заполнен .Я, наконец, обнаружил переполнение стека, включив параметры этой команды в свой cmake (работает с gcc).Обратите fsanitize=alignment
внимание на ошибки во время выполнения, связанные с выравниванием, говорится в документации gcc об ASan:
Этот параметр позволяет проверять выравнивание указателей, когда они разыменованы, или когда ссылка привязана к недостаточно выровненному целевому объекту, или когда метод или конструктор вызывается для недостаточно выровненного объекта.
И это наиболее вероятные ошибки, когда вы имеете дело с пользовательским выравниванием
add_compile_options(
$<$<CONFIG:Debug>:-Og>
-fdiagnostics-color=always
-Wuninitialized
-fno-omit-frame-pointer
$<$<CONFIG:Debug>:-fsanitize=undefined>
$<$<CONFIG:Debug>:-fsanitize=address>
$<$<CONFIG:Debug>:-fsanitize=alignment>
$<$<CONFIG:Debug>:-fsanitize=bounds>
-fno-sanitize-recover
)
add_link_options(
$<$<CONFIG:Debug>:-fsanitize=undefined>
$<$<CONFIG:Debug>:-fsanitize=address>
$<$<CONFIG:Debug>:-fsanitize=alignment>
$<$<CONFIG:Debug>:-fsanitize=bounds>
)
Комментарии:
1. Можете ли вы уточнить, как это связано с проблемами выравнивания?
2. @oarfish Ой, я пропустил самый важный параметр, я только что отредактировал свой ответ
3. С clang это дает мне
clang: error: unsupported argument 'bound' to option 'fsanitize='
. Так что я думаю, только GCC.4. С gcc, по-видимому, этого
bounds
не должно бытьbound
.