Как я могу отлаживать проблемы выравнивания памяти (AVX), когда они не воспроизводятся в минимальном контексте?

#c #debugging #point-cloud-library #memory-alignment #eigen3

#c #отладка #точка-облако-библиотека #выравнивание памяти #eigen3

Вопрос:

В последнее время я постоянно сталкиваюсь со следующей проблемой:

  1. У меня большая кодовая база, которая использует собственные и PCL (которая также использует собственные)
  2. Мне нужно использовать почти текущую собственную главную ветку и я не могу использовать стабильный выпуск из-за зависимости, требующей этого.
  3. Как PCL, так и другие зависимости в моем проекте используют векторные инструкции, поэтому я компилирую -march=native .
  4. При выполнении некоторых действий, связанных с собственными типами (аффинные преобразования, просмотр облака точек), я иногда получаю ошибки сегментации или другие сбои в, казалось бы, бессмысленных местах, например, в 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 .