You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

CUDA+C++项目链接失败:undefined reference to `__cxa_call_terminate' 问题求助

CUDA+C++项目链接失败:undefined reference to `__cxa_call_terminate' 问题求助

首先,这个__cxa_call_terminate是GCC C++标准库的内部函数,专用于异常处理流程——当程序抛出的异常无法被捕获时,编译器生成的代码会调用它来触发std::terminate()。出现这个未定义引用错误,大概率是编译和链接阶段用了不同版本的GCC工具链,导致标准库符号不兼容,结合你的环境细节,我来拆解原因和解决方案:

可能的核心原因

你提到CMake用g++-13编译C代码,但看你的链接命令开头是/usr/bin/c++——这应该是系统默认的GCC14的编译器!编译C用g13生成的目标文件,依赖g13版本的libstdc++,但链接时用GCC14的链接器,它会优先找GCC14的libstdc++,而这两个版本的标准库符号可能存在差异,导致__cxa_call_terminate找不到。

另外还要注意:nvcc编译.cu文件时会调用主机编译器,如果这个主机编译器不是g13(比如用了系统默认的GCC14),那么.cu生成的目标文件也会和g13编译的C++文件产生符号不兼容问题。

具体解决方案

方案1:强制CMake全程使用g++-13(编译+链接)

最直接的办法是让CMake明确用g++-13作为C++编译器,而不是依赖系统默认的c++。你可以:

  • 在CMakeLists.txt开头添加:
set(CMAKE_CXX_COMPILER "/usr/bin/g++-13")
# 同时确保nvcc的主机编译器也是g++-13
set(CMAKE_CUDA_HOST_COMPILER "/usr/bin/g++-13")
  • 或者在执行cmake初始化时通过参数指定:
cmake .. -DCMAKE_CXX_COMPILER=g++-13 -DCMAKE_CUDA_HOST_COMPILER=g++-13

这样链接命令的开头就会变成/usr/bin/g++-13,确保编译和链接用的是同一个版本的GCC工具链,标准库完全匹配。

方案2:修复链接阶段的库搜索顺序

如果不想改CMake的编译器设置,也可以调整链接时的库路径优先级,让链接器先找到g++13的libstdc++
在CMakeLists.txt中给目标添加明确的库依赖和路径:

target_link_libraries(jacobiCudaGraphs PRIVATE
  -L/usr/lib/gcc/x86_64-linux-gnu/13
  stdc++
  # 你的其他CUDA库...
)

或者手动在链接命令中把-lstdc++放在目标文件之后,确保链接器从g++13的库中查找符号。

方案3:验证符号存在性(排查用)

可以先确认g++13的标准库里确实有这个符号:

nm -D /usr/lib/gcc/x86_64-linux-gnu/13/libstdc++.so.6 | grep __cxa_call_terminate

如果输出中有W __cxa_call_terminate,说明符号存在,问题就是链接时没找到这个库;如果没有,那可能是g++13的标准库安装不完整,需要重新安装libstdc++-13-dev包。

额外注意点

你提到之前能编译成功,现在失败,大概率是系统更新后默认GCC升级到14,而CMake配置没同步更新链接器版本——这个场景我之前帮朋友排查过好几次,都是编译器/链接器版本不匹配导致的符号缺失。

另外,CUDA 12.8对GCC13是兼容的(NV官方文档里CUDA12.x支持GCC9-14左右),所以只要确保nvcc和C++编译器用同一个版本的GCC,就不会有兼容性问题。

如果试了上面的方法还是不行,可以把CMakeLists.txt中关于C++和CUDA编译器的配置贴出来,我再帮你细化排查~

火山引擎 最新活动