段错误的愿意和调试方法
主要的原因:
- 访问了不存在的内存指针
- 访问系统保护的内存地址
- 方位只读的内存地
- 数组越界
- 栈溢出
主要查看,指针的问题是否出现错误使用
方法1. gdb直接调试
使用run命令直接报错,查看
方法2. 调试core文件,
当程序运行的过程中异常终止或崩溃,操作系统会将程序当时的内存状态记录下来,保存在一个文件中,这种行为就叫 core dump(核心转储)。
2.1 打开 core dump 功能
终端输入:
ulimit -c
如果输出 0,说明,core的文件大小为0,也即没有开启 core dump 功能
不限制 core dump 存储信息的大小,可以执行:
ulimit -c unlimited
限制 core dump 大小,可以执行(单位是 KB):
ulimit -c 1024
2.2 永久修改(可选)
以上指令只对当前终端有效,想要永久生效需要修改 “/etc/security/limits.conf” 文件,重启后生效
sudo vim /etc/security/limits.conf
gdb ./执行文件 ./core,结果告诉出错的位置,会生成当前目录下
2.3 修改 core 文件保存路径和命名(可选)
默认情况下,内核在 core dump 时所产生的 core 文件放在与该程序相同的目录中,并且文件名固定为 core
执行下面指令修改 core 文件路径:
echo /tmp/crash/core-%e-%t | sudo tee /proc/sys/kernel/core_pattern
其中 “/tmp/crash/core-%e-%t” 是 core dump 文件的保存路径和命名
注意:这里的 “/tmp/crash/” 目录如果不存在,程序崩溃时候不会自动创建 “/tmp/crash/” 目录,也就不会保存 core dump 文件了
参数表:
- %p - insert pid into filename 添加pid(进程id)
- %u - insert current uid into filename 添加当前uid(用户id)
- %g - insert current gid into filename 添加当前gid(用户组id)
- %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 添加导致产生core的命令名
2.4 程序添加 gdb 调试信息
catkin_make 编译:
catkin_make -DCMAKE_BUILD_TYPE=Debug
或者在 CMakelist.txt 文件前面添加以下代码
SET(CMAKE_BUILD_TYPE "Debug")
SET(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb")
SET(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")
当程序运行崩溃后,会在 “/tmp/crash/” 目录中产生 core dump 文件
2.5 执行这句话即可
gdb /devel/lib/xxx.so xxx-core
参考https://zhuanlan.zhihu.com/p/655272437
方法3. 反汇编定位
3.1 使用dmseg命令,定位出现段错误的输出信息的地址
demsg
即出现对应的段错误的指令指针对应的地址,记住这个地址
3.2 或者使用catchsegv定位错误地址
catchsegv ./可执行程序
3.3 反汇编进行查看
使用 objdump -S ./可执行程序>logdump
根据出错的段错误地址,确定出错的位置
总结:
- 出现段错误的时候,首先想一想段错误的定义,出现的原因
- 编程的时候,定义变量最好初始化
- 数组不越界使用
其他报错:
-
循环使用,出现段错误:查看你的频率和休眠时间是否对应;
-
double free问题:等待补充;
-
在使用ceres/g2o报错时,在cmakeList.txt,set(CMAKE_CXX_FLAGS “-std=c++11 -march=native -O3”) 可以参考https://blog.csdn.net/weixin_46120107/article/details/130663182
set(CMAKE_CXX_FLAGS "-std=c++11 -march=native -O3")
===>
native 就是相当于自检查cpu,
-march是gcc优化选项,
-Ox 这个参数只有在 cmake -DCMAKE_BUILD_TYPE=release时有效