使用C++加载MMDeploy自定义TensorRT插件时出现段错误求助
问题背景
已确认libmmdeploy_tensorrt_ops.so无问题,相同环境下Python加载该插件推理完全正常,但C++程序执行到nvinfer1::IExecutionContext* context = engine->createExecutionContext();时触发段错误。
环境
- Ubuntu 20.04
- CUDA 11.3
- TensorRT 8.5.1.7
- g++ 9.4
C++主程序代码
std::string pluginLibraryPath = "mylibpath/libmmdeploy_tensorrt_ops.so"; std::string engineFilePath = "myenginepath/cascade-rcnn/end2end.engine"; std::string imagePath = "myimagepath/1544580881017339287.jpg"; // Load the TensorRT engine nvinfer1::IRuntime* runtime = nvinfer1::createInferRuntime(gLogger); assert(runtime != nullptr); if (!runtime) { std::cerr << "Failed to create runtime" << std::endl; return -1; } void* plugin_handle = dlopen(pluginLibraryPath.c_str(), RTLD_LAZY); if (!plugin_handle) { std::cerr << "load plugin fail: " << dlerror() << std::endl; return false; } nvinfer1::IPluginRegistry* pluginRegistry = getPluginRegistry(); if (!pluginRegistry) { std::cerr << "regist plugin fail" << std::endl; return false; } // Load engine char *trtModelStream{ nullptr }; size_t size{ 0 }; std::ifstream engineFile(engineFilePath, std::ios::binary); if (engineFile.good()) { engineFile.seekg(0, engineFile.end); size = engineFile.tellg(); engineFile.seekg(0, engineFile.beg); trtModelStream = new char[size]; assert(trtModelStream); engineFile.read(trtModelStream, size); engineFile.close(); } nvinfer1::ICudaEngine* engine = runtime->deserializeCudaEngine(trtModelStream, size, nullptr); assert(engine != nullptr); nvinfer1::IExecutionContext* context = engine->createExecutionContext(); assert(context != nullptr);
常规日志输出
Loaded engine size: 148 MiB [MemUsageChange] 初始化cuBLAS/cuBLASLt:CPU +942,GPU +202,当前:CPU 1177,GPU 2007(MiB) [MemUsageChange] 初始化cuDNN:CPU +1,GPU +10,当前:CPU 1178,GPU 2017(MiB) [MemUsageChange] 引擎反序列化中TensorRT管理的内存分配:CPU +0,GPU +158,当前:CPU 0,GPU 158(MiB) [MemUsageChange] 初始化cuBLAS/cuBLASLt:CPU +1,GPU +8,当前:CPU 1182,GPU 2021(MiB) [MemUsageChange] 初始化cuDNN:CPU +0,GPU +8,当前:CPU 1182,GPU 2029(MiB) 段错误
调试日志
Thread 1 "main" 收到信号SIGSEGV,段错误。 0x00007fffd7663328 in ?? () from /lib/x86_64-linux-gnu/libgcc_s.so.1 ERROR: 无法获取寄存器:无此进程。 [切换到线程2 (Thread 0x7fffcdc77000 (LWP 97457))] [Thread 0x7fffcc810000 (LWP 97463) 已退出] [Thread 0x7fffcd476000 (LWP 97458) 已退出] [Thread 0x7fffcdc77000 (LWP 97457) 已退出] 程序因信号SIGSEGV(段错误)终止。
段错误发生在createExecutionContext()的内部调用:
IExecutionContext* createExecutionContext() noexcept { return mImpl->createExecutionContext(); }
解决建议
- 调整插件加载顺序:先加载插件,再创建TensorRT Runtime。TensorRT插件需要在Runtime初始化前完成注册,否则引擎反序列化时无法正确关联插件实现,后续创建Context会因符号缺失或不匹配崩溃。修改代码顺序:
// 先加载插件 void* plugin_handle = dlopen(pluginLibraryPath.c_str(), RTLD_NOW | RTLD_GLOBAL); if (!plugin_handle) { std::cerr << "load plugin fail: " << dlerror() << std::endl; return false; } // 再创建Runtime nvinfer1::IRuntime* runtime = nvinfer1::createInferRuntime(gLogger); - 修改dlopen参数:使用
RTLD_NOW | RTLD_GLOBAL替代RTLD_LAZY,确保插件的所有符号立即解析并全局可见,避免TensorRT在运行时无法找到插件的内部实现。 - 验证引擎兼容性:确认生成
.engine文件时使用的TensorRT、CUDA版本与当前C++环境完全一致,小版本差异可能导致序列化格式不兼容。 - 检查GCC ABI兼容性:确保编译C++程序的GCC版本(9.4)与编译TensorRT库、
libmmdeploy_tensorrt_ops.so时的GCC版本相同,ABI不兼容会导致函数调用时内存访问错误。 - 修复内存泄漏:在
engine反序列化完成后,及时释放trtModelStream:delete[] trtModelStream;
内容的提问来源于stack exchange,提问作者Xinhao
相关产品推荐
相关产品推荐

