注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Tsecer的回音岛

Tsecer的博客

 
 
 

日志

 
 

linux下coredump文件生成路径  

2012-07-29 18:32:03|  分类: Linux内核 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
一、coredump
coredump文件是linux系统下追溯问题故障的一个重要基本方法,它可以在程序内部出现不可恢复的异常的时候将当时的现场保存下来,从而可以完成之后的回溯性。
为了满足一些特殊的需求,系统需要能够知道这个文件生成的位置,事件的原因等信息。例如对于我虚拟机中使用的fedora core版本,如果系统出现程序崩溃,在下次启动的时候系统会提示说之前系统出现过程序崩溃,需要关注等信息。这其实并不是一个容易的过程,因为对于我们这些菜鸟很容易弄出一个程序崩溃问题,而崩溃的位置可能在任意地方,它怎么知道整个系统中什么地方出现了一次崩溃。
二、coredump如何处理
内核中格式化文件名的方法
首先是在int do_coredump(long signr, int exit_code, struct pt_regs * regs)中判断需要生成coredump文件
ispipe = format_corename(corename, core_pattern, signr);
    unlock_kernel();
     if (ispipe) {
        /* SIGPIPE can happen, but it's just never processed */
         if(call_usermodehelper_pipe(corename+1, NULL, NULL, &file)) {
             printk(KERN_INFO "Core dump to %s pipe failed\n",
                   corename);
             goto fail_unlock;
         }
     } else
         file = filp_open(corename,
                 O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag,
                 0600);

/* format_corename will inspect the pattern parameter, and output a
 * name into corename, which must have space for at least
 * CORENAME_MAX_SIZE bytes plus one byte for the zero terminator.
 */
static int format_corename(char *corename, const char *pattern, long signr)
{
    const char *pat_ptr = pattern;
    char *out_ptr = corename;
    char *const out_end = corename + CORENAME_MAX_SIZE;
    int rc;
    int pid_in_pattern = 0;
    int ispipe = 0;

    if (*pattern == '|')如果字符串的最开始是一个管道符号,那么设置管道标识
        ispipe = 1;

    /* Repeat as long as we have more pattern to process and more output
       space */
    while (*pat_ptr) {
        if (*pat_ptr != '%') {
            if (out_ptr == out_end)
                goto out;
            *out_ptr++ = *pat_ptr++;
        } else {
            switch (*++pat_ptr) {
            case 0: 该过程中对空白不做任何解释
                goto out;
            /* Double percent, output one percent */
            case '%':
                if (out_ptr == out_end)
                    goto out;
                *out_ptr++ = '%';
                break;
            /* pid */
            case 'p':
                pid_in_pattern = 1;
                rc = snprintf(out_ptr, out_end - out_ptr,
                          "%d", current->tgid);
                if (rc > out_end - out_ptr)
                    goto out;
                out_ptr += rc;
                break;
            /* uid */
            case 'u':
                rc = snprintf(out_ptr, out_end - out_ptr,
                          "%d", current->uid);
                if (rc > out_end - out_ptr)
                    goto out;
                out_ptr += rc;
                break;
            /* gid */
            case 'g':
                rc = snprintf(out_ptr, out_end - out_ptr,
                          "%d", current->gid);
                if (rc > out_end - out_ptr)
                    goto out;
                out_ptr += rc;
                break;
            /* signal that caused the coredump */
            case 's':
                rc = snprintf(out_ptr, out_end - out_ptr,
                          "%ld", signr);
                if (rc > out_end - out_ptr)
                    goto out;
                out_ptr += rc;
                break;
            /* UNIX time of coredump */
            case 't': {
                struct timeval tv;
                do_gettimeofday(&tv);
                rc = snprintf(out_ptr, out_end - out_ptr,
                          "%lu", tv.tv_sec);
                if (rc > out_end - out_ptr)
                    goto out;
                out_ptr += rc;
                break;
            }
            /* hostname */
            case 'h':
                down_read(&uts_sem);
                rc = snprintf(out_ptr, out_end - out_ptr,
                          "%s", utsname()->nodename);
                up_read(&uts_sem);
                if (rc > out_end - out_ptr)
                    goto out;
                out_ptr += rc;
                break;
            /* executable */
            case 'e':
                rc = snprintf(out_ptr, out_end - out_ptr,
                          "%s", current->comm);可执行文件名字,整个comm最多16字符
                if (rc > out_end - out_ptr)
                    goto out;
                out_ptr += rc;
                break;
            default:
                break;
            }
            ++pat_ptr;
        }
    }
    /* Backward compatibility with core_uses_pid:
     *
     * If core_pattern does not include a %p (as is the default)
     * and core_uses_pid is set, then .%pid will be appended to
     * the filename. Do not do this for piped commands. */
    if (!ispipe && !pid_in_pattern
            && (core_uses_pid || atomic_read(&current->mm->mm_users) != 1)) {
        rc = snprintf(out_ptr, out_end - out_ptr,
                  ".%d", current->tgid);
        if (rc > out_end - out_ptr)
            goto out;
        out_ptr += rc;
    }
out:
    *out_ptr = 0;
    return ispipe;
}
三、管道命令的创建
int call_usermodehelper_pipe(char *path, char **argv, char **envp,
                 struct file **filp)
{
    DECLARE_COMPLETION(done);
    struct subprocess_info sub_info = {
        .work        = __WORK_INITIALIZER(sub_info.work,
                             __call_usermodehelper),
        .complete    = &done,
        .path        = path,
        .argv        = argv,
        .envp        = envp,
        .retval        = 0,
    };
    struct file *f;

    if (!khelper_wq)
        return -EBUSY;

    if (path[0] == '\0')
        return 0;

    f = create_write_pipe();
    if (IS_ERR(f))
        return PTR_ERR(f);
    *filp = f;

    f = create_read_pipe(f);
    if (IS_ERR(f)) {
        free_write_pipe(*filp);
        return PTR_ERR(f);
    }
    sub_info.stdin = f;

    queue_work(khelper_wq, &sub_info.work);
    wait_for_completion(&done);
    return sub_info.retval;
}
四、fedora core上的例子
[tsecer@Harry coredump]$ uname -a
Linux Harry 2.6.31.5-127.fc12.i686.PAE #1 SMP Sat Nov 7 21:25:57 EST 2009 i686 athlon i386 GNU/Linux

[tsecer@Harry coredump]$ cat /proc/sys/kernel/core_pattern
|/usr/libexec/hookCCpp /var/cache/abrt %p %s %u

[tsecer@Harry coredump]$ cat coredump.c
int main()
{
    *(int*)0 = 0;
}

[tsecer@Harry coredump]$ gcc coredump.c -o coredump.c.exe
[tsecer@Harry coredump]$ ./coredump.c.exe
Segmentation fault (core dumped)

[tsecer@Harry coredump]$ ll 虽然提示生成了core dump文件,但是在当前文件夹下并没有coredump文件
total 12
-rw-rw-r--. 1 tsecer tsecer   30 2012-07-29 17:26 coredump.c
-rwxrwxr-x. 1 tsecer tsecer 4838 2012-07-29 18:25 coredump.c.exe

[tsecer@Harry coredump]$ ll /var/cache/abrt
total 104
-rw-r--r--. 1 root   root   6144 2012-07-29 18:25 abrt-db
drwx------. 2 gdm    gdm    4096 2011-03-12 09:45 ccpp-1299894333-1266
drwx------. 2 gdm    gdm    4096 2011-03-12 10:33 ccpp-1299897205-1302
drwx------. 2 root   root   4096 2011-09-24 18:25 ccpp-1316859916-13999
drwx------. 2 gdm    gdm    4096 2011-10-01 09:47 ccpp-1317433641-1540
drwx------. 2 tsecer tsecer 4096 2011-10-02 17:12 ccpp-1317546758-28993
drwx------. 2 tsecer tsecer 4096 2011-10-02 17:15 ccpp-1317546928-29142
drwx------. 2 tsecer tsecer 4096 2011-10-02 18:26 ccpp-1317551183-5107
drwx------. 2 gdm    gdm    4096 2011-11-12 20:26 ccpp-1321100781-1557
drwx------. 2 tsecer tsecer 4096 2011-11-25 22:48 ccpp-1322232531-5914
drwx------. 2 gdm    gdm    4096 2011-12-08 22:42 ccpp-1323355358-1551
drwx------. 2 root   root   4096 2011-12-23 21:54 ccpp-1324648467-19219
drwx------. 2 root   root   4096 2012-01-21 22:59 ccpp-1327157948-25413
drwx------. 2 tsecer tsecer 4096 2012-02-25 23:22 ccpp-1330183343-25295
drwx------. 2 tsecer tsecer 4096 2012-05-10 23:53 ccpp-1336665223-598
drwx------. 2 gdm    gdm    4096 2012-07-29 18:23 ccpp-1343557418-1572
drwx------. 2 root   root   4096 2011-10-03 10:45 kerneloops-1317609923-1
drwx------. 2 root   root   4096 2011-12-21 22:08 kerneloops-1324476476-1
drwx------. 2 root   root   4096 2011-12-24 18:48 kerneloops-1324723694-1
drwx------. 2 root   root   4096 2012-04-19 20:35 kerneloops-1334838946-1
drwx------. 2 root   root   4096 2012-04-19 21:06 kerneloops-1334840813-1
drwx------. 2 root   root   4096 2012-05-14 21:52 kerneloops-1337003561-1
drwx------. 2 root   root   4096 2012-05-14 22:12 kerneloops-1337004730-1
drwx------. 2 root   root   4096 2012-07-29 01:49 kerneloops-1343497795-1
drwx------. 2 root   root   4096 2012-07-29 18:25 kerneloops-1343557511-1
[tsecer@Harry coredump]$
五、内核中各个参数的说明
linux-2.6.21\Documentation\sysctl\kernel.txt
core_pattern:
core_pattern is used to specify a core dumpfile pattern name. . max length 128 characters; default value is "core" . core_pattern is used as a pattern template for the output filename; certain string patterns (beginning with '%') are substituted with
  their actual values. . backward compatibility with core_uses_pid: If core_pattern does not include "%p" (default does not)
    and core_uses_pid is set, then .PID will be appended to
    the filename. . corename format specifiers: %<NUL>    '%' is dropped
    %%    output one '%'
    %p    pid
    %u    uid
    %g    gid
    %s    signal number
    %t    UNIX time of dump
    %h    hostname
    %e    executable filename
    %<OTHER> both are dropped . If the first character of the pattern is a '|', the kernel will treat the rest of the pattern as a command to run.  The core dump will be written to the standard input of that program instead of to a file.
  评论这张
 
阅读(2736)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017