当内存对齐问题 (AVX) 无法在最小上下文中重现时,如何调试它们?

oar*_*ish 5 c++ debugging memory-alignment point-cloud-library eigen3

我最近总是遇到以下问题:

  1. 我有一个大型代码库,它使用EigenPCL(也使用Eigen
  2. 我需要使用几乎最新的 Eigen master 分支,并且由于依赖项需要它而无法使用稳定版本。
  3. 我的项目中的 PCL 和其他依赖项都使用向量指令,因此我使用-march=native.
  4. 当运行一些涉及特征类型(仿射变换、点云查看)的东西时,我有时会在看似无意义的位置(例如在构造函数中)出现分段错误或其他崩溃Eigen::Quaternionf。在其他情况下,会EIGEN_UNALIGNED_ASSERT触发 ,这会导致此页面,我在代码中随处观察到其内容(据我所知)

我想成为一个好公民,所以我尝试在一个最小的示例上重现该问题,并将其发布在 stackoverflow 或相关问题跟踪器中。然而,当我只提取触发问题的位时,我总是无法重现崩溃。我的猜测是,内存是否对齐(并且不需要特别注意)也取决于问题位置之前分配的内容,因此周围的代码有助于触发问题。

问题:我可以使用哪些技术和工具来有效确定 Linux 和/或 macOS 上的 C+14 中内存对齐相关崩溃的根源?

Spy*_*tos 3

我强烈推荐AddressSanitizer。在嵌入式应用程序上,我曾经在缓冲区上出现过一个小的堆栈溢出,只有当堆栈接近满时才会产生副作用。我最终通过在我的 cmake 上包含此命令选项(与 gcc 一起使用)发现了堆栈溢出。注意查找fsanitize=alignment运行时与对齐相关的错误,关于 ASan 的 gcc 文档说:

当取消引用指针时,或者当引用绑定到未充分对齐的目标时,或者在未充分对齐的对象上调用方法或构造函数时,此选项允许检查指针的对齐情况。

当您处理自定义对齐时,这些是最可能出现的错误

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>
)


Run Code Online (Sandbox Code Playgroud)