RK3588 Linux板端推理时报错Segmentation fault解决办法

问题

最近在使用rk3588跑官方提供的yolov5模型demo,能够完成单张图片的目标检测,但是在运行视频流demo时,系统报错:

segmentation fault(core dumped)

此时没有再给出更多的报错信息,不太好debug,在网上阅读了一些博客现在整理一下。

解决

在Linux下遇到程序异常退出或者中止,操作系统通常会把程序当前的工作状况存储在一个名为core的文件中,其中包含了程序运行时的内存、寄存器和堆栈指针等信息,格式为ELF,这个过程叫做coredump,又称作核心转储。

生成core文件

因此需要找到报错时生成的core文件,首先先查看coredump是否生效:

$ ulimit -a
...
-c: core file size (blocks)         0
...

0表示core文件大小限制为0,不允许写入,所以无法生成core文件,需要修改为正数大小或unlimited才可使coredump生效。

通过以下命令取消生成core文件的内存大小限制:

ulimit -c unlimited

上面对core文件的操作仅对当前生效,若需要永久生效,则要将相应操作写入/etc/profile

修改core文件存储路径

core文件默认存储在程序的工作目录,可以通过命令cat /proc/sys/kernel/core_pattern查看。

找到文件/etc/sysctl.conf,通过vim打开文件:

sudo vim /etc/sysctl.conf

移动光标至文件末尾,按 i 键进入编辑模式,此时可以修改文本。
在文件末尾加入信息,可以指定core文件的存储路径:

kernel.core_pattern=/dumpdir/core_%e_%p_%t

附上core文件的参数信息:

%p - insert pid into filename  # 添加 pid 
%u - insert current uid into filename  # 添加当前 uid 
%g - insert current gid into filename  # 添加当前 gid 
%s - insert signal that caused the coredump into the filename  # 添加导致产生 core 的信号 
%t - insert UNIX time that the coredump occurred into filename  # 添加 core 文件生成时的 unix 时间 
%h - insert hostname where the coredump happened into filename  # 添加主机名 
%e - insert coredumping executable name into filename  # 添加命令名

按 esc 键,此时退出修改文本。
保存退出vim:

:wq

控制core文件的文件名中是否添加pid作为扩展:

echo "1" > /proc/sys/kernel/core_uses_pid  

这一步可能会报错Permission denied,这是因为重定向符号 “>” 和 “>>” 也是 bash 的命令。sudo 只是让 echo 命令具有了 root 权限,但是没有让 “>” 和 “>>” 命令也具有root 权限,所以 bash 会认为这两个命令都没有写入信息的权限。

所以这里可以利用 “sh -c” 命令,它可以让 bash 将一个字串作为完整的命令来执行,这样就可以将 sudo 的影响范围扩展到整条命令。

sudo sh -c ‘echo "1" > /proc/sys/kernel/core_uses_pid’

/proc/sys/kernel/core_uses_pid这个文件的值若为1,则无论是否配置%p,最后生成的core文件都会添加pid,可以用cat命令进行确认。

Ubuntu20.04下的异常状况

Ubuntu20.04系统下,执行完上述操作,会发现还是无法在指定目录生成core文件。查看core文件存储路径:

$ cat /proc/sys/kernel/core_pattern
|/usr/share/apport/apport %p %s %c %d %P %E

发现core文件存储路径并非自己设置的,而是由管道交给了一个apport的程序,通过查询可知其是Ubuntu官方为了自动收集错误,生成程序崩溃报告的一个服务,即apport.service。

关掉这个服务:

sudo service apport stop

使用sudo service apport start可以开启这个服务。

如果最后仍然没有生成core文件,同时报错时显示segmentation fault,可以在gcc/g++编译时增加-g选项:

例如:cc -O2 -Wall -Wextra -g -c -o test_VIDIOC_ENUMSTD.o test_VIDIOC_ENUMSTD.c

至此报错segmentation fault(core dumped) 且成功生成core文件。

利用core文件进行调试

进入rk3588开发板中的视频流demo所在的文件夹,使用gdb工具利用生成的core文件进行debug

gdb ./rknn_yolov5_video_demo core.3099 

这样就进入了 gdb core 调试模式。

追踪产生segmenttation fault的位置及代码函数调用情况:

(gdb) bt

就可以定位到代码具体的报错信息和位置。

我是在虚拟机上完成代码的交叉编译,再将可执行文件demo移到开发板中进行测试的,可以看到板子在运行demo没有找到对应的库,报错时显示的路径是对应的库在虚拟机中的路径,因此怀疑是交叉编译出的问题。目前考虑将编译过程移到开发板上进行。具体情况还有待更新。

退出:

(gdb) quit

参考链接:https://www.answerywj.com/2022/12/20/generate-and-usage-of-core-in-linux/#/%E4%BB%80%E4%B9%88%E6%98%AFcore%E6%96%87%E4%BB%B6

### 解决rknn_yolov8_pose_demo程序中的段错误 段错误通常是由于尝试访问未分配或不允许访问的内存区域引起的。对于`rknn_yolov8_pose_demo`程序,可以采取多种方法来诊断和修复此类问题。 #### 使用静态分析工具检测潜在缺陷 为了提高代码质量并减少运行错误的可能性,建议先利用静态分析工具扫描源码中存在的潜在风险点[^1]。这类工具有助于发现可能导致崩溃的具体位置以及提供改进建议。 #### 启用调试模式编译项目 确保以启用调试信息的方式重新构建应用程序,这有助于后续通过GDB等调试器更精确地定位故障发生处。通常情况下,在Makefile或其他构建配置文件中设置CFLAGS/CXXFLAGS参数加入-g选项即可实现此目的。 #### 运行监控与日志记录增强 增加详细的日志输出可以帮助理解程序执行流程直至出现问题前的状态变化情况;同考虑集成专门的日志管理解决方案以便更好地管理和检索这些数据。另外,借助像`rosmon`这样的ROS节点启动及监视守护进程能够有效捕获异常终止事件,并自动重启服务保持系统稳定性[^2]。 #### 应用动态分析技术排查具体原因 当怀疑存在复杂的逻辑错误或是难以重现的问题,则可引入基于LLM的语言模型辅助解释性故障定位手段。这种方法不仅限于简单的语法检查而是深入到语义层面去解析可能引发crash的原因所在。 ```bash gdb ./rknn_yolov8_pose_demo (gdb) run # 当遇到segmentation fault后查看回溯信息 (gdb) bt full ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值