Linux下SegmentFault(double free)分析方法(四)coredump文件

Linux下SegmentFault(double free)分析方法(四)coredump文件

一、coredump简介

1、coredump文件是什么?

core dump又叫核心转储, 当程序运行过程中发生异常, 程序异常退出时,由操作系统把程序当前的内存状况存储在一个core文件中, 叫core dump.(linux中如果内存越界会收到SIGSEGV信号,然后就会core dump)在程序运行的过程中,尤其是在程序运行过程中,并没有gdb、valgrind等工具和程序一起运行,所以在程序中自动产生相关的调试,便于事后进行原因分析,尤其是我们不知道程序什么异常退出的时候,这种方式就比较适合,可以将程序当时的栈信息保存起来,便于我们进行分析。

2、什么情况下生成coredump文件

当程序收到特定的信号时会产生相关的coredump文件主要是以下几种

Signal Action Comment
SIGQUIT Core Quit from keyboard
SIGILL Core Illegal Instruction
SIGABRT Core Abort signal from abort
SIGSEGV Core Invalid memory reference
SIGTRAP Core Trace/breakpoint trap

这东西不详细展开,可以参考APUE 第十章有关信号的部分

二、如何产生core文件并且进行相关配置

1、利用ulimit命令临时开启coredump开关

该方法只对当前shell起作用

root@ubuntu:~# 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) 3682
max locked memory       (kbytes, -l) 64
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) 3682
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited
root@ubuntu:~# ulimit -c unlimited
root@ubuntu:~# ulimit -a
core file size          (blocks, -c) unlimited
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 3682
max locked memory       (kbytes, -l) 64
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) 3682
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited
root@ubuntu:~# 
2、修改limits.conf 配置文件永久起作用

limits.conf 可能因平台差异而路径不同,应该根据具体情况进行更改,并且Ubuntu的root用户一定要在
域下指定用户名

root@ubuntu:~# vim /etc/security/limits.conf 
  1 # /etc/security/limits.conf
  2 #
  3 #Each line describes a limit for a user in the form:
  4 #
  5 #<domain>        <type>  <item>  <value>
  6 #
  7 #Where:
  8 #<domain> can be:
  9 #        - a user name
 10 #        - a group name, with @group syntax
 11 #        - the wildcard *, for default entry
 12 #        - the wildcard %, can be also used with %group syntax,
 13 #                 for maxlogin limit
 14 #        - NOTE: group and wildcard limits are not applied to root.
 15 #          To apply a limit to the root user, <domain> must be
 16 #          the literal username root.
 17 #
 18 #<type> can have the two values:
 19 #        - "soft" for enforcing the soft limits
 20 #        - "hard" for enforcing hard limits
 21 #
 22 #<item> can be one of the following:
 23 #        - core - limits the core file size (KB)
 24 #        - data - max data size (KB)
 25 #        - fsize - maximum filesize (KB)
 26 #        - memlock - max locked-in-memory address space (KB)
 27 #        - nofile - max number of open files
 28 #        - rss - max resident set size (KB)
 29 #        - stack - max stack size (KB)
 30 #        - cpu - max CPU time (MIN)
 31 #        - nproc - max number of processes
 32 #        - as - address space limit (KB)
 33 #        - maxlogins - max number of logins for this user
 34 #        - maxsyslogins - max number of logins on the system
 35 #        - priority - the priority to run user process with
 36 #        - locks - max number of file locks the user can hold
 37 #        - sigpending - max number of pending signals
 38 #        - msgqueue - max memory used by POSIX message queues (bytes)
 39 #        - nice - max nice priority allowed to raise to values: [-20, 19]
 40 #        - rtprio - max realtime priority
 41 #        - chroot - change root to directory (Debian-specific)
 42 #
 43 #<domain>      <type>  <item>         <value>
 44 #
 45 
 46  *               soft    core            unlimited
 47 #root            hard    core            100000
 48 #*               hard    rss             10000
 49 #@student        hard    nproc           20
 50 #@faculty        soft    nproc           20
 51 #@faculty        hard    nproc           50
 52 #ftp             hard    nproc           0
 53 #ftp             -       chroot          /ftp
 54 #@student        -       maxlogins       4
 55 
 56 # End of file
"/etc/security/limits.conf" 56L, 2158C written   
3、开启及启动执行命令(只适合当前用户)

在 ~/.bashrc的最后加入:
ulimit -c unlimited(一劳永逸)

4、使用Linux的系统调用
root@ubuntu:~# man getrlimit
GETRLIMIT(2)                                        Linux Programmer's Manual                                       GETRLIMIT(2)

NAME
       getrlimit, setrlimit, prlimit - get/set resource limits

SYNOPSIS
       #include <sys/time.h>
       #include <sys/resource.h>

       int getrlimit(int resource, struct rlimit *rlim);
       int setrlimit(int resource, const struct rlimit *rlim);
       省略后面内容

可以通过man手册或者 apue 第七章相关内容进行学习,以下是实例程序

//coredump_config.cpp
#include "coredump_config.h"
int SetCoreFileSize(void)
{
    struct rlimit rlmt;
    if (getrlimit(RLIMIT_CORE, &rlmt) == -1) {
        return -1; 
    }   
    printf("Before set rlimit CORE dump current is:%d, max is:%d\n", 
    				(int)rlmt.rlim_cur, (int)rlmt.rlim_max);
    rlmt.rlim_cur = (rlim_t)CORE_SIZE;
    rlmt.rlim_max  = (rlim_t)CORE_SIZE;
    if (setrlimit(RLIMIT_CORE, &rlmt) == -1) {
        return -1; 
    }   
    if (getrlimit(RLIMIT_CORE, &rlmt) == -1) {
        return -1; 
    }   
    printf("After set rlimit CORE dump current is:%d, max is:%d\n", 
    						(int)rlmt.rlim_cur, (int)rlmt.rlim_max);
    return 0;
}

int SetCoreFilePath(void)
{
	system("echo 1 > /proc/sys/kernel/core_uses_pid");	
	system("echo /tmp/corefile-%e-%p-%t > /proc/sys/kernel/core_pattern");	
}

//coredump_config.h
#include <unistd.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <stdio.h>
#define CORE_SIZE 1024 * 1024 * 500
int SetCoreFileSize(void);
int SetCoreFilePath(void);

在自己程序启动的开始位置分别调用

SetCoreFileSize();
SetCoreFilePath();

即可

5、配置coredump文件生成的目录以及名称
  • 默认生成的 core 文件保存在可执行文件所在的目录下,文件名就为 core。
  • 通过修改
/proc/sys/kernel/core_uses_pid

文件可以让生成 core 文件名是否自动加上 pid 号。
例如

echo 1 > /proc/sys/kernel/core_uses_pid

,生成的 core 文件名将会变成 core.pid,其中 pid 表示该进程的 PID。

扫描二维码关注公众号,回复: 9279720 查看本文章
  • 通过修改
/proc/sys/kernel/core_pattern

来控制生成 core 文件保存的位置以及文件名格式。
例如可以用

echo "/tmp/corefile-%e-%p-%t" > /proc/sys/kernel/core_pattern
设置生成的 core 文件保存在 “/tmp/corefile” 目录下,文件名格式为 “core-命令名-pid-时间戳”。
6、总结

coredump文资料
man 5 core
或者http://man7.org/linux/man-pages/man5/core.5.html

三、如何使用core文件

利用coredump查看栈信息
gdb program core

root@ubuntu:/Deepinfar/FlyInCoding/c++/vs/double_free# gdb double_free_main corefile-double_free_mai-1695-1551199336
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
Copyright (C) 2016 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 "i686-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 double_free_main...done.

warning: core file may not match specified executable file.
[New LWP 1695]
Core was generated by `./double_free_main'.
Program terminated with signal SIGABRT, Aborted.
#0  0xb7776c31 in __kernel_vsyscall ()
(gdb) bt
#0  0xb7776c31 in __kernel_vsyscall ()
#1  0xb7441ea9 in __GI_raise (sig=6) at ../sysdeps/unix/sysv/linux/raise.c:54
#2  0xb7443407 in __GI_abort () at abort.c:89
#3  0xb747d37c in __libc_message (do_abort=2, fmt=0xb7575e54 "*** Error in `%s': %s: 0x%s ***\n")
    at ../sysdeps/posix/libc_fatal.c:175
#4  0xb74832f7 in malloc_printerr (action=<optimized out>, str=0xb7575f94 "double free or corruption (fasttop)", 
    ptr=<optimized out>, ar_ptr=0xb75c8780 <main_arena>) at malloc.c:5006
#5  0xb7483c31 in _int_free (av=0xb75c8780 <main_arena>, p=<optimized out>, have_lock=0) at malloc.c:3867
#6  0xb7657d88 in operator delete(void*) () from /usr/lib/i386-linux-gnu/libstdc++.so.6
#7  0x0804966d in __gnu_cxx::new_allocator<unsigned char>::deallocate (this=0xbfe92018, __p=0x9575a10 "")
    at /usr/include/c++/4.8/ext/new_allocator.h:110
#8  0x08049163 in std::_Vector_base<unsigned char, std::allocator<unsigned char> >::_M_deallocate (this=0xbfe92018, 
    __p=0x9575a10 "", __n=4) at /usr/include/c++/4.8/bits/stl_vector.h:174
#9  0x080492cf in std::_Vector_base<unsigned char, std::allocator<unsigned char> >::~_Vector_base (this=0xbfe92018, 
    __in_chrg=<optimized out>) at /usr/include/c++/4.8/bits/stl_vector.h:160
#10 0x08048eda in std::vector<unsigned char, std::allocator<unsigned char> >::~vector (this=0xbfe92018, __in_chrg=<optimized out>)
    at /usr/include/c++/4.8/bits/stl_vector.h:416
#11 0x08048adc in MyTest2 () at double_free_main.cpp:61
#12 0x08048b18 in main () at double_free_main.cpp:67
(gdb) thread 
[Current thread is 1 (LWP 1695)]
(gdb) 

通过查看栈信息可以程序出问题的地方。

发布了67 篇原创文章 · 获赞 15 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/wanxuexiang/article/details/88382733