segmentation fault 定位

我们在Linux下进行程序开发,如果程序代码不严谨,会经常遇到

segmentation fault
1
报错,这种报错的结果就是程序会直接挂掉,很难在程序里一下子定位到问题代码。

原因
segmentation fault 就是经常说的内存泄露/溢出: 当一个进程执行一个无效的内存引用,或发生断错误时,会触发 SIGSEGV信号,内核默认的动作就是 终止该进程。
这个最常见的就是,比如我们使用了 非法指针:


 1 #include <stdio.h>
 2 #include <string.h>
 3 
 4 int main(void)
 5 {
 6         char *str = "abcd123";
 7         char *p = NULL;
 8         char a;
 9 
10         p = strstr(str, "456");
11 
12         a = *p;
13 
14         return 0;
15 
16 }


上面的代码执行就会出现内存报错, 因为 p 为 NULL, 我们对 NULL的指针进行访问,势必会出错。
修改:

char *str = "abcd123";
char *p = NULL;
char a;
p = strstr(str, "456");
if(p != NULL){
  a = *p;
}

所以最关键的还是要编程严谨。

解决思路
使用gdb进行调试运行,这种方式需要一步步的定位,显然不是最优的。
使用 core 文件, linux 默认会为 SIGSEGV 故障生成 一个core文件,该文件记录了出错时的堆栈信息,通过gdb 程序 core 可以快速追踪到问题代码。不过我们在编译的时候,需要加上编译参数 -g
gcc -g a.c -o test
1
gdb 查看命令: bt 和 where

jsq@jsq:/opt/tmp/sigsegv-test$ gdb ./test core
GNU gdb (Ubuntu 8.1-0ubuntu3) 8.1.0.20180409-git
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./test...done.
[New LWP 5868]
Core was generated by `./test'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x0000561a6e023680 in main () at a.c:12
12        a = *p;
(gdb) bt
#0  0x0000561a6e023680 in main () at a.c:12
(gdb) where
#0  0x0000561a6e023680 in main () at a.c:12
(gdb) 

从上面的信息可以轻松的看到,问题定位到了 a.c 的第12行。

无法生成 core文件解决方法
core文件一般会在程序执行的当前目录下生成,如果无法生成,一般原因有两种:
1. linux 内核限制,需要通过 ulimit -c 去设置,通过ulimit -a可以查看是否有限制:

jsq@jsq:/opt/tmp/sigsegv-test$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 15071
max locked memory       (kbytes, -l) 16384
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 15071
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

上图中可以看到 core file size 的大小为0, 说明是禁止,我们可以通过-c 选项设置 大小,比如:

ulimit -c 1024
1
设置成1024
2. 当前程序在当前目录下没有“写”权限
这个之前遇到过,在一些硬件配置或者特殊路径下,core file不为0, 仍然不能生成core文件,这个时候就要考虑写权限的问题了(ls -l 查看),主要涉及到 程序用户和用户组权限,我们可以通过 chown和chrgp命令,来实现用户和用户组的设置,比如:

chown root test
chgrp root test
1
2
将test程序的用户和用户组都设置成 root权限。

小结
segmentation fault是内存异常故障,最快速的定位方法是追踪core文件,所以要设置linux环境下能够 运行生成 core文件。
————————————————

原文链接:https://blog.csdn.net/u012351051/article/details/114702516

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值