调用TFLite C++ API的Invoke方法触发段错误问题求助
TFLite C++ API调用时process方法Invoke()触发段错误
问题现象
调用TFLite C++ API解释器时,构造函数中能成功加载模型并通过虚拟图像完成权重初始化,但在process方法中调用interpreter->Invoke()时触发Segmentation fault (core dumped)错误。将process中的代码移到构造函数则可正常运行,已确认process中能正常访问interpreter及输入输出张量详情,但Invoke()调用直接崩溃,无后续报错输出。
主cpp文件
#include "inference.hpp" #include <iostream> int main() { ObjectDetectionProcessor obj("/src/model.tflite"); obj.process(); return 0; }
对应的hpp文件
#include <opencv2/opencv.hpp> #include <fstream> #include <string> #include <vector> #include <memory> #include <iostream> #include "tensorflow/lite/interpreter.h" #include "tensorflow/lite/kernels/register.h" #include "tensorflow/lite/model.h" class ObjectDetectionProcessor { public: ObjectDetectionProcessor(const std::string& model_path) { auto model = tflite::FlatBufferModel::BuildFromFile(model_path.c_str()); if (!model) { std::cout << "Failed to mmap model " << model_path << std::endl; exit(-1); } tflite::InterpreterBuilder(*model, resolver)(&interpreter); if (!interpreter) { std::cout << "Failed to construct interpreter" << std::endl; exit(-1); } if (interpreter->AllocateTensors() != kTfLiteOk) { std::cout << "Failed to allocate tensors!" << std::endl; exit(-1); } int input_index = interpreter->inputs()[0]; input_tensor = interpreter->tensor(input_index); const uint input_width = input_tensor->dims->data[2]; const uint input_height = input_tensor->dims->data[1]; const uint input_channels = input_tensor->dims->data[3]; const uint input_type = input_tensor->type; // 获取量化参数 input_scale = input_tensor->params.scale; input_zero_point = input_tensor->params.zero_point; is_initialized = false; int cv_type = (input_type == kTfLiteFloat32) ? CV_32FC3 : CV_8UC3; // 根据张量类型调整OpenCV图像类型 // 创建指定尺寸和类型的全零虚拟图像 cv::Mat dummy_frame = cv::Mat::zeros(input_height, input_width, cv_type); // 将虚拟图像传入解释器完成模型预热 TfLiteTensor* input_data = interpreter->tensor(interpreter->inputs()[0]); std::memcpy(input_data->data.uint8, dummy_frame.ptr<uint8_t>(0), dummy_frame.total() * dummy_frame.elemSize()); if (interpreter->Invoke() != kTfLiteOk) { std::cout << "Failed to warm up model!" << std::endl; exit(-1); } int output_index = interpreter->outputs()[0]; output_tensor = interpreter->tensor(output_index); float* out_data = interpreter->typed_output_tensor<float>(0); is_initialized = true; } void process(){ if (!is_initialized) { std::cout << "Model not initialized!" << std::endl; return; } // 从文件读取图像 cv::Mat dummy_frame = cv::imread("/src/image.jpg", cv::IMREAD_COLOR); // 将图像缩放到模型输入尺寸 cv::resize(dummy_frame, dummy_frame, cv::Size(input_tensor->dims->data[2], input_tensor->dims->data[1])); dummy_frame.convertTo(dummy_frame, CV_8UC3); // 获取输入输出张量 TfLiteTensor* input_data = interpreter->tensor(interpreter->inputs()[0]); TfLiteTensor* output_data = interpreter->tensor(interpreter->outputs()[0]); std::memcpy(input_data->data.uint8, dummy_frame.ptr<uint8_t>(0), dummy_frame.total() * dummy_frame.elemSize()); // 执行推理 if (interpreter->Invoke() != kTfLiteOk) { std::cout << "Failed to invoke model!" << std::endl; return; } // 获取输出数据 float* boxes = interpreter->tensor(interpreter->outputs()[0])->data.f; float* classes = interpreter->tensor(interpreter->outputs()[1])->data.f; float* scores = interpreter->tensor(interpreter->outputs()[2])->data.f; } private: std::unique_ptr<tflite::FlatBufferModel> model; tflite::ops::builtin::BuiltinOpResolver resolver; std::unique_ptr<tflite::Interpreter> interpreter; TfLiteTensor* input_tensor = nullptr; TfLiteTensor* output_tensor = nullptr; float input_scale; int input_zero_point; bool is_initialized; };
编译命令
g++ -g -o out src/infer.cpp tensorflow/tensorflow/lite/delegates/external/external_delegate.cc -I/usr/local/tensorflow/include -L/usr/local/tensorflow/lib -ltensorflowlite -I/usr/local/include/opencv4/ -L/usr/local/lib/ -lopencv_core -lopencv_imgcodecs -lopencv_imgproc
GDB回溯信息
(gdb) backtrace #0 0x0000713a12be8ab9 in ?? () from /usr/local/lib/libtensorflowlite.so #1 0x0000713a1290aa7b in ?? () from /usr/local/lib/libtensorflowlite.so #2 0x0000713a12bf1474 in ?? () from /usr/local/lib/libtensorflowlite.so #3 0x0000713a12bf18ae in ?? () from /usr/local/lib/libtensorflowlite.so #4 0x0000713a12bd8a52 in ?? () from /usr/local/lib/libtensorflowlite.so #5 0x0000713a1297e730 in ?? () from /usr/local/lib/libtensorflowlite.so #6 0x0000713a1297f57e in ?? () from /usr/local/lib/libtensorflowlite.so #7 0x0000713a1298190b in ?? () from /usr/local/lib/libtensorflowlite.so #8 0x0000713a12982137 in TfLiteStatus tflite::ops::builtin::conv::EvalImpl<(tflite::ops::builtin::conv::KernelType)2, (TfLiteType)3>(TfLiteContext*, TfLiteNode*) () from /usr/local/lib/libtensorflowlite.so #9 0x0000713a129821fb in TfLiteStatus tflite::ops::builtin::conv::Eval<(tflite::ops::builtin::conv::KernelType)2>(TfLiteContext*, TfLiteNode*) () from /usr/local/lib/libtensorflowlite.so #10 0x0000713a12b8f519 in tflite::Subgraph::Invoke() () from /usr/local/lib/libtensorflowlite.so #11 0x0000713a12b9508c in tflite::Interpreter::Invoke() () from /usr/local/lib/libtensorflowlite.so #12 0x00006152b80498d9 in ObjectDetectionProcessor::process (this=0x7ffdf3118b20) at src/inference.hpp:226 #13 0x00006152b8047aaf in main () at src/infer.cpp:12
调试信息
构造函数中调试输出:
(gdb) p interpreter $2 = std::unique_ptr<tflite::Interpreter> = {get() = 0x6152ecc21760} (gdb) p input_tensor $4 = (TfLiteTensor *) 0x6152ecc3aaa0 (gdb) p input_data $5 = (TfLiteTensor *) 0x6152ecc3aaa0
process方法中调试输出:
(gdb) p input_tensor $7 = (TfLiteTensor *) 0x6152ecc3aaa0 (gdb) p interpreter $8 = std::unique_ptr<tflite::Interpreter> = {get() = 0x6152ecc21760} (gdb) p input_data $9 = (TfLiteTensor *) 0x6152ecc3aaa0
问题原因与修复方案
核心问题
构造函数中创建的model是局部变量,类成员model未被赋值。当构造函数执行完毕后,局部model被销毁,而interpreter内部持有指向FlatBufferModel的引用,导致后续调用Invoke()时访问已释放的内存,触发段错误。
修复步骤
修正模型所有权:将构造函数中的局部
model赋值给类成员,确保模型在对象生命周期内保持有效:// 替换原构造函数中的auto model = ... model = tflite::FlatBufferModel::BuildFromFile(model_path.c_str());添加图像加载检查:
process方法中读取图像后,需检查是否加载成功,避免空矩阵导致的未定义行为:cv::Mat dummy_frame = cv::imread("/src/image.jpg", cv::IMREAD_COLOR); if (dummy_frame.empty()) { std::cout << "Failed to read image!" << std::endl; return; }
内容的提问来源于stack exchange,提问作者Maja
相关产品推荐
相关产品推荐

