分享

core dump

 t涂鸦 2011-11-30

1. 在嵌入式系统中,有时core dump直接从串口打印出来,结合objdump查找ra和epa地址,运用栈回溯,可以找到程序出错的地方。

2. 在一般Linux系统中,默认是不会产生core dump文件的,通过ulimit -c来查看core dump文件的大小,一般开始是0,可以设置core文件大小,ulimit -c 1024(kbytes单位)或者ulimit -c unlimited。

3. core dump文件输出设置,一般默认是当前目录,可以在/proc/sys/kernel中找到core-user-pid,通过

echo "1" > /proc/sys/kernel/core-user-pid使core文件名加上pid号,还可以用

mkdir -p /root/corefile

echo "/root/corefile/core-%e-%p-%t" > /proc/sys/kernel/core-pattern控制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 添加命令名

4. 用gdb查看core文件:
下面我们可以在发生运行时信号引起的错误时发生core dump了.编译时加上-g
发生core dump之后, 用gdb进行查看core文件的内容, 以定位文件中引发core dump的行.
gdb [exec file] [core file]
如:
gdb ./test test.core
在进入gdb后, 用bt命令查看backtrace以检查发生程序运行到哪里, 来定位core dump的文件行.

5. 给个例子

test.c

 

void a()

{

   char *p = NULL;

   printf("%d/n", *p);

}

 

int main()

{

    a();

    return 0;

}

 

编译 gcc -g -o test test.c

运行 ./test

报segmentation fault(core dump)

gdb ./test test.core如果生成的是test.core.


开发过程中,当一个Linux程序异常退出时,我们可以通过core文件来分析它异常的详细原因。缺省情况下,Linux在程序异常时不产生core文件,要想让程序异常退出时产生core dump文件,需要使用ulimit命令更改coredump的设置:

ulimit -c unlimited 

上面的命令表示在程序异常时产生core dump文件,并且不对core dump文件的大小进行限制。

上述设置只是使能了core dump功能,缺省情况下,内核在coredump时所产生的core文件放在与该程序相同的目录中,并且文件名固定为core。很显然,如果有多个程序产生core文件,或者同一个程序多次崩溃,就会重复覆盖同一个core文件。

我们通过修改kernel的参数,可以指定内核所生成的coredump文件的文件名。例如,Easwy使用下面的命令使kernel生成名字为core.filename.pid格式的core dump文件:

echo 'core.%e.%p' > /proc/sys/kernel/core_pattern 

这样配置后,产生的core文件中将带有崩溃的程序名、以及它的进程ID。上面的%e%p会被替换成程序文件名以及进程ID。

可以在core_pattern模板中使用变量还很多,见下面的列表:

  • %% 单个%字符
  • %p 所dump进程的进程ID
  • %u 所dump进程的实际用户ID
  • %g 所dump进程的实际组ID
  • %s 导致本次core dump的信号
  • %t core dump的时间 (由1970年1月1日计起的秒数)
  • %h 主机名
  • %e 程序文件名

如果在上述文件名中包含目录分隔符”/“,那么所生成的core文件将会被放到指定的目录中。

需要说明的是,在内核中还有一个与coredump相关的设置,就是/proc/sys/kernel/core_uses_pid。如果这个文件的内容被配置成1,那么即使core_pattern中没有设置%p,最后生成的core dump文件名仍会加上进程ID。

对所生成的core dump进程分析,需要使用调试工具,例如GDB等。可以参见Easwy的其它文章。

原创文章,请阅读页脚的许可方式,转载请注明:转载自易水博客 [ http:///blog/ ]



http://blog.163.com/chujb_chen/blog/static/10571112011410112118895/

core dump 分析  

2011-05-10 11:21:18|  分类: 精品转载|字号 订阅

源地址:http://www./tech/core_dump_analysis.html
一、简介

core dump 又叫核心转储,当程序异常退出时(crashed),由操作系统把程序当前的内存状况存储在 core 文件中,叫 core dump。其中可能包括:处理机状态、进程状态、栈指针等调试信息。

二、coredump 文件生成

查看 coredump 文件路径
sysctl –A | grep kernel.core_pattern 或者 cat /proc/sys/kernel/core_pattern

指定 core dump 文件的生成路径和格式:

%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 添加命令名
例: core_pattern=/data/coredump/core_%e-%p-%t

查看 core dump 文件大小限制 ulimit -c
ulimit –c 4 设置允许生成的 coredump 文件最大为 4 K
ulimit –c unlimited 不限制 coredump 文件的大小
-S 设置软件资源限制
-H 设置硬件资源限制
导致生成 coredump 的信号
更多信号量默认处理方式,请查阅:http://www./doc/man-pages/online/pages/man7/signal.7.html

使用 install 替代 cp 更新 so 文件,预防 coredump

使用 gcore 命令,强制生成 core dump 文件

Linux 源码跟踪(源码版本:linux-2.6.38.4)
core dump 生成:

// kernel/signal.c
int get_signal_to_deliver(siginfo_t *info
            , struct k_sigaction *return_ka
            , struct pt_regs *regs
            , void *cookie)
//符合 SIG_KERNEL_COREDUMP_MASK 将调用 coredump 过程
// fs/exec.c
void do_coredump(long signr
            , int exit_code
            , struct pt_regs *regs)

core 文件写入核心代码:

//源码路径:arch/powerpc/platforms/cell/spufs/coredump.c
static int spufs_dump_write(struct file *file
                                , const void *addr
                                , int nr
                                , loff_t *foffset)
{
    unsigned long limit = rlimit(RLIMIT_CORE);
    ssize_t written;
    if (*foffset + nr > limit)
        return -EIO;
    written = file->;f_op->write(file, addr, nr, &file->f_pos);
    *foffset += written;
    if (written != nr)
        return -EIO;
    return 0;
}

从 第 9 行,可以看到,core dump 在写入之前,会做一个判断,如果 coredump 数据超过设置,将不会生成 coredump 文件。

三、core dump 文件信息

void do_coredump(long signr
        , int exit_code
        , struct pt_regs *regs) {
    struct core_state core_state; //
    struct core_name cn; //
    struct mm_struct *mm = current->mm; //
    struct linux_binfmt * binfmt; //
    const struct cred *old_cred; //
    struct cred *cred; //
    ......
    binfmt = mm->;binfmt; //取得当前程序加载器
    if (!binfmt || !binfmt->core_dump)
        goto fail;
    if (!__get_dumpable(cprm.mm_flags))
        goto fail;
    ......
}
// fs/binfmt_elf.c
static int fill_note_info(struct elfhdr *elf
        , int phdrs
        , struct elf_note_info *info
        , long signr
        , struct pt_regs *regs) {
    ......
    fill_prstatus(info->;prstatus, current, signr);
    elf_core_copy_regs(&info->prstatus->pr_reg, regs);
    fill_elf_header(elf, phdrs, ELF_ARCH, ELF_CORE_EFLAGS, ELF_OSABI);
    ......
    //try to dump fpu(浮点运算单元)
    elf_core_copy_task_fpregs(current, regs, info->fpu);
    ......
}

在 Linux 下,core dump 文件格式一般为 ELF。分析 core dump 文件信息,可以从 do_coredump 程序开始(内容太多,再补)。

四、定位问题

gdb 调试工具

附带参数 gdb –args you_prog prog_params
进程加载的 so 引发 coredump,需要计算 so 的加载地址。
系统参数 /proc/sys/kernel/random_va_space 为 1 ,表示随机 mmap 位置,增加 buffer 溢出攻击难度;另一方面,可能会影响调试, core 后重启, so 加载地址可能已经变化……
addr2line

valgrind (推荐使用)

valgrind –leak-check=full your_prog
五、参考资料

内存检查性能分析工具 http://www.
http:///binutils/docs-2.21/
http://www.
http://www./doc/man-pages/online/pages/man7/signal.7.html

问题:1. 生成的core   dump保存路径在哪里,怎么设置 

============================================== 
default   it 's   in   the   initial   directory   of   your   running   the   program


问题2.我的多线程程序在通过socket   连接同其它进程通讯,在对方进程退出或shutdown   时也几乎同时退出。可是我的程序没有输出任何在程序正常退出时肯定会显示的提示信息而直接退出,也没有产生   core   dump   文件,不知道这是什么原因。 请问哪位知道:   进程异常退出时   Unix   在什么情况下会不产生   core   dump   文件? 

产生   core   dump   文件,一般是程序异常中止(堆栈返回错误,内存访问出错...) 
是否产成core   dump文件,程序可以控制,产生的core   dump文件的大小,程序也可以控制,命令也可设置; 
需要root权限;

the   signal   "SIGPIPE "   ended   your   program.

我只知道有两种可能 
一种是产生core的一个信号被忽略了,进程收到信号就直接退出。 
另一种是文件可以产生,但没法写到硬盘上,空间不够,没有权限等等原因。

很多信号默认的处理就是退出

初学者大部分的原因都是访问了不该访问的内存,这里面绝大多数又是因为访问零地址或内存溢出




    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多