使用g++ -march=native -g编译AVX架构Intel CPU时触发SIGSEGV
GCC 14.2及更早版本AVX指令集环境下栈对齐错误导致SIGSEGV
结论
这是GCC的代码生成bug,和你的代码无关。核心依据:
- 仅在GCC搭配
-march=native/skylake/haswell -g(或无优化但启用AVX相关架构预设)时触发崩溃,Clang编译所有场景均正常 - 崩溃源于GCC生成的
vmovdqa指令访问了未按32字节对齐的栈地址,而AVX指令集要求该指令的操作数必须严格32字节对齐 -O3优化下问题消失,是因为优化逻辑消除了触发错误的栈操作代码
问题细节分析
崩溃点的汇编指令vmovdqa %ymm0,-0x40(%rbp)要求rbp-0x40必须是32字节对齐地址,但你的环境中rbp值为0x5fec10,计算后地址未满足对齐要求。
你的测试进一步锁定了问题范围:
-march=sandybridge -g编译正常:Sandybridge仅支持AVX1,栈对齐要求为16字节,vmovdqa在此模式下会被替换为兼容指令或降低对齐要求- 手动指定AVX2等独立指令集(
-mavx2 -mfma ... -g)编译正常:说明问题并非指令集本身,而是GCC在-march=skylake/haswell这类架构预设配置下的栈对齐处理逻辑错误 - 移除
-g但不添加优化时仍崩溃:排除调试信息的直接影响,确认是代码生成阶段的bug
解决建议
除了避免使用-march=native,还可以尝试以下方案:
- 替换架构预设为具体指令集:用
-mavx2 -mfma -mbmi -mbmi2 -mmovbe -mlzcnt -mpopcnt -mrdrnd -mf16c替代-march=skylake/haswell,你的测试已验证此方法有效 - 强制栈对齐编译选项:添加
-mstackrealign或-mpreferred-stack-boundary=5(数值5对应32字节对齐),强制GCC生成符合AVX要求的栈对齐代码 - 升级GCC版本:尝试使用GCC 15.x或更高版本,此类代码生成bug通常会在后续版本中修复
- 临时启用低级别优化:调试阶段可临时添加
-O1,既保留部分调试信息,又可能消除触发崩溃的栈操作逻辑
最小复现代码
#include <cstdint> #include <iostream> template<typename It> struct container_view { typedef typename It::reference reference; typedef std::remove_reference_t<reference> value_type; typedef const reference const_reference; constexpr container_view(It it, size_t s) noexcept : it(it), s(s) {} constexpr It begin() const noexcept { return it; } constexpr It end() const noexcept { return it + size(); } constexpr reference operator[](size_t i) noexcept { return *(it + i); } /// Size of container. constexpr size_t size() const noexcept { return s; } private: It it; size_t s; }; template<typename T, typename S = const size_t> struct shifted_vector { typedef std::remove_reference_t<T> vector_type; ///< The type of vector. T vec; ///< DenseVector of sequential non-zero elements. S offset; ///< Offset of first non-zero element. }; struct band_matrix_jump_iterator { typedef short value_type; typedef short* pointer; typedef short& reference; private: size_t b; // matrix's bandwidth size_t v; // matrix's column size_t e; // matrix's column's element's index. pointer p; // Pointer to current element. public: constexpr band_matrix_jump_iterator(pointer p, size_t b, size_t v, size_t e) noexcept : b{b}, v{v}, e{e}, p{p} {} constexpr band_matrix_jump_iterator &operator++() noexcept { ++e; ++p; return *this; } constexpr band_matrix_jump_iterator &operator+=(ptrdiff_t i) noexcept { e += i; p += i; return *this; } constexpr band_matrix_jump_iterator operator+(ptrdiff_t i) const noexcept { band_matrix_jump_iterator t(*this); t += i; return t; } constexpr reference operator*() const noexcept { return *p; } constexpr bool operator==(const band_matrix_jump_iterator &it) const noexcept { return e == it.e; } }; struct band_matrix { typedef short value_type; typedef value_type* pointer; constexpr size_t columns() const noexcept { return 10; } size_t b; pointer elements; //---------------------------------------------------------------- TYPEDEFS OF ITERATORS AND VECTORS typedef band_matrix_jump_iterator column_iterator; typedef shifted_vector<container_view<column_iterator>, const uint8_t> column_vector; //--------------------------------------------------------------------------- CONSTRUCTORS / ASSIGNS constexpr band_matrix(size_t b) : b{b}, elements(new value_type[10]) {} constexpr ~band_matrix() noexcept { delete[] elements; } //------------------------------------------ GET ROWS, COLUMNS, DIAGONAL AND CORRESPONDING ITERATORS /// Return a beginning iterator to column \c i vector. constexpr column_iterator column_begin(size_t i) noexcept { return column_iterator(elements + i, 0, i, 0); } /// Return a vector view of column \c i. constexpr column_vector column(size_t i) noexcept { return {typename column_vector::vector_type{column_begin(i), 1}, (uint8_t) i}; } }; using namespace std; int main() { band_matrix m(0); for (size_t i = 0; i < 10; ++i) m.elements[i] = i; // checking columns for (size_t i = 0; i < m.columns(); ++i) { auto v = m.column(i); cout << (int) v.offset << ": { "; for (auto i : v.vec) cout << i << " "; cout << "}\n"; } }
编译器版本信息
存在问题的GCC版本
Using built-in specs. COLLECT_GCC=g++ COLLECT_LTO_WRAPPER=C:/Program\ Files/mingw64/bin/../libexec/gcc/x86_64-w64-mingw32/14.2.0/lto-wrapper.exe OFFLOAD_TARGET_NAMES=nvptx-none Target: x86_64-w64-mingw32 Configured with: ../configure --prefix=/R/winlibs_staging_ucrt64/inst_gcc-14.2.0/share/gcc --build=x86_64-w64-mingw32 --host=x86_64-w64-mingw32 --enable-offload-targets=nvptx-none --with-pkgversion='MinGW-W64 x86_64-ucrt-posix-seh, built by Brecht Sanders, r2' --with-tune=generic --enable-checking=release --enable-threads=posix --disable-sjlj-exceptions --disable-libunwind-exceptions --disable-serial-configure --disable-bootstrap --enable-host-shared --enable-plugin --disable-default-ssp --disable-rpath --disable-libstdcxx-debug --disable-version-specific-runtime-libs --with-stabs --disable-symvers --enable-languages=c,c++,fortran,lto,objc,obj-c++ --disable-gold --disable-nls --disable-stage1-checking --disable-win32-registry --disable-multilib --enable-ld --enable-libquadmath --enable-libada --enable-libssp --enable-libstdcxx --enable-lto --enable-fully-dynamic-string --enable-libgomp --enable-graphite --enable-mingw-wildcard --enable-libstdcxx-time --enable-libstdcxx-pch --with-mpc=/c/Prog/winlibs_staging_ucrt/custombuilt64 --with-mpfr=/c/Prog/winlibs_staging_ucrt/custombuilt64 --with-gmp=/c/Prog/winlibs_staging_ucrt/custombuilt64 --with-isl=/c/Prog/winlibs_staging_ucrt/custombuilt64 --disable-libstdcxx-backtrace --enable-install-libiberty --enable-__cxa_atexit --without-included-gettext --with-diagnostics-color=auto --enable-clocale=generic --with-libiconv --with-system-zlib --with-build-sysroot=/R/winlibs_staging_ucrt64/gcc-14.2.0/build_mingw/mingw-w64 CFLAGS='-D__USE_MINGW_ANSI_STDIO=0 -I/c/Prog/winlibs_staging_ucrt/custombuilt64/include/libdl-win32 -march=nocona -msahf -mtune=generic -O2 -Wno-error=format' CXXFLAGS='-D__USE_MINGW_ANSI_STDIO=0 -Wno-int-conversion -march=nocona -msahf -mtune=generic -O2' LDFLAGS='-pthread -Wl,--no-insert-timestamp -Wl,--dynamicbase -Wl,--high-entropy-va -Wl,--nxcompat -Wl,--tsaware' LD=/c/Prog/winlibs_staging_ucrt/custombuilt64/share/binutils/bin/ld.exe Thread model: posix Supported LTO compression algorithms: zlib zstd gcc version 14.2.0 (MinGW-W64 x86_64-ucrt-posix-seh, built by Brecht Sanders, r2)
正常工作的Clang版本
(built by Brecht Sanders, r2) clang version 19.1.1 Target: x86_64-w64-windows-gnu Thread model: posix InstalledDir: C:/Program Files/mingw64/bin
内容的提问来源于stack exchange,提问作者Chameleon
相关产品推荐
相关产品推荐

