You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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();
}

解决建议

  1. 调整插件加载顺序:先加载插件,再创建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);
    
  2. 修改dlopen参数:使用RTLD_NOW | RTLD_GLOBAL替代RTLD_LAZY,确保插件的所有符号立即解析并全局可见,避免TensorRT在运行时无法找到插件的内部实现。
  3. 验证引擎兼容性:确认生成.engine文件时使用的TensorRT、CUDA版本与当前C++环境完全一致,小版本差异可能导致序列化格式不兼容。
  4. 检查GCC ABI兼容性:确保编译C++程序的GCC版本(9.4)与编译TensorRT库、libmmdeploy_tensorrt_ops.so时的GCC版本相同,ABI不兼容会导致函数调用时内存访问错误。
  5. 修复内存泄漏:在engine反序列化完成后,及时释放trtModelStream:
    delete[] trtModelStream;
    

内容的提问来源于stack exchange,提问作者Xinhao

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 08:28:10