当前位置:   article > 正文

RK3588 Linux板端推理时报错Segmentation fault解决办法_rknn segmentation fault怎么解决

rknn segmentation fault怎么解决

问题

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

segmentation fault(core dumped)
  • 1

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

解决

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

生成core文件

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

$ ulimit -a
...
-c: core file size (blocks)         0
...
  • 1
  • 2
  • 3
  • 4

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

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

ulimit -c unlimited
  • 1

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

修改core文件存储路径

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

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

sudo vim /etc/sysctl.conf
  • 1

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

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

附上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  # 添加命令名
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

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

:wq
  • 1

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

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

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

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

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

/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
  • 1
  • 2

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

关掉这个服务:

sudo service apport stop
  • 1

使用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 
  • 1

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

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

(gdb) bt
  • 1

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

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

退出:

(gdb) quit
  • 1

参考链接: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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/运维做开发/article/detail/854445
推荐阅读
相关标签
  

闽ICP备14008679号