Exemplo n.º 1
0
static GList *abrt_journal_extract_xorg_crashes(abrt_journal_t *journal)
{
    GList *crash_info_list = NULL;

    do
    {
        char *line = abrt_journal_get_log_line(journal);
        if (line == NULL)
            error_msg_and_die(_("Cannot read journal data."));

        char *p = skip_pfx(line);
        if (strcmp(p, XORG_SEARCH_STRING) == 0)
        {
            struct xorg_crash_info *crash_info = process_xorg_bt(&abrt_journal_get_next_log_line, journal);
            if (crash_info)
                crash_info_list = g_list_append(crash_info_list, crash_info);
            else
                log_warning(_("Failed to parse Backtrace from journal"));
        }
        free(line);
    }
    while (abrt_journal_next(journal) > 0);

    log("Found crashes: %d", g_list_length(crash_info_list));

    return crash_info_list;
}
Exemplo n.º 2
0
int main(int argc, char **argv)
{
    /* I18n */
    setlocale(LC_ALL, "");
#if ENABLE_NLS
    bindtextdomain(PACKAGE, LOCALEDIR);
    textdomain(PACKAGE);
#endif

    abrt_init(argv);

    /* Can't keep these strings/structs static: _() doesn't support that */
    const char *program_usage_string = _(
        "& [-vsoxm] [-d DIR]/[-D] [FILE]\n"
        "\n"
        "Extract Xorg crash from FILE (or standard input)"
    );
    /* Keep OPT_z enums and order of options below in sync! */
    struct options program_options[] = {
        OPT__VERBOSE(&g_verbose),
        OPT_BOOL(  's', NULL, NULL, _("Log to syslog")),
        OPT_BOOL(  'o', NULL, NULL, _("Print found crash data on standard output")),
        OPT_STRING('d', NULL, &debug_dumps_dir, "DIR", _("Create problem directory in DIR for every crash found")),
        OPT_BOOL(  'D', NULL, NULL, _("Same as -d DumpLocation, DumpLocation is specified in abrt.conf")),
        OPT_BOOL(  'x', NULL, NULL, _("Make the problem directory world readable")),
        OPT_BOOL(  'm', NULL, NULL, _("Print search string(s) to stdout and exit")),
        OPT_END()
    };
    unsigned opts = g_opts = parse_opts(argc, argv, program_options, program_usage_string);

    export_abrt_envvars(0);

    msg_prefix = g_progname;
    if ((opts & OPT_s) || getenv("ABRT_SYSLOG"))
    {
        logmode = LOGMODE_JOURNAL;
    }

    if (opts & OPT_m)
    {
        puts("Backtrace");
        return 0;
    }

    if (opts & OPT_D)
    {
        if (opts & OPT_d)
            show_usage_and_die(program_usage_string, program_options);
        load_abrt_conf();
        debug_dumps_dir = g_settings_dump_location;
        g_settings_dump_location = NULL;
        free_abrt_conf_data();
    }

    argv += optind;
    if (argv[0])
        xmove_fd(xopen(argv[0], O_RDONLY), STDIN_FILENO);

    char *line;
    while ((line = xmalloc_fgetline(stdin)) != NULL)
    {
        char *p = skip_pfx(line);
        if (strcmp(p, "Backtrace:") == 0)
        {
            free(line);
            g_bt_count++;
            process_xorg_bt();
            continue;
        }
        free(line);
    }

    /* If we are run by a log watcher, this delays log rescan
     * (because log watcher waits to us to terminate)
     * and possibly prevents dreaded "abrt storm".
     */
    if (opts & (OPT_d|OPT_D))
    {
        if (g_bt_count > MAX_DUMPED_DD_COUNT)
            sleep(g_bt_count - MAX_DUMPED_DD_COUNT);
    }

    return 0;
}
Exemplo n.º 3
0
/* Called after "Backtrace:" line was read.
 * Example (yes, stray newline before 'B' is real):
[ 86985.879]<space>
Backtrace:
[ 86985.880] 0: /usr/bin/Xorg (xorg_backtrace+0x2f) [0x462d8f]
[ 86985.880] 1: /usr/bin/Xorg (0x400000+0x67b56) [0x467b56]
[ 86985.880] 2: /lib64/libpthread.so.0 (0x30a5800000+0xf4f0) [0x30a580f4f0]
[ 86985.880] 3: /usr/lib64/xorg/modules/extensions/librecord.so (0x7ff6c225e000+0x26c3) [0x7ff6c22606c3]
[ 86985.880] 4: /usr/bin/Xorg (_CallCallbacks+0x3c) [0x43820c]
[ 86985.880] 5: /usr/bin/Xorg (WriteToClient+0x1f5) [0x466315]
[ 86985.880] 6: /usr/lib64/xorg/modules/extensions/libdri2.so (ProcDRI2WaitMSCReply+0x4f) [0x7ff6c1e4feef]
[ 86985.880] 7: /usr/lib64/xorg/modules/extensions/libdri2.so (DRI2WaitMSCComplete+0x52) [0x7ff6c1e4e6d2]
[ 86985.880] 8: /usr/lib64/xorg/modules/drivers/intel_drv.so (0x7ff6c1bfb000+0x25ae4) [0x7ff6c1c20ae4]
[ 86985.880] 9: /usr/lib64/libdrm.so.2 (drmHandleEvent+0xa3) [0x376b407513]
[ 86985.880] 10: /usr/bin/Xorg (WakeupHandler+0x6b) [0x4379db]
[ 86985.880] 11: /usr/bin/Xorg (WaitForSomething+0x1a9) [0x460289]
[ 86985.880] 12: /usr/bin/Xorg (0x400000+0x3379a) [0x43379a]
[ 86985.880] 13: /usr/bin/Xorg (0x400000+0x22dc5) [0x422dc5]
[ 86985.880] 14: /lib64/libc.so.6 (__libc_start_main+0xed) [0x30a542169d]
[ 86985.880] 15: /usr/bin/Xorg (0x400000+0x230b1) [0x4230b1]
[ 86985.880] Segmentation fault at address 0x7ff6bf09e010
 */
static void process_xorg_bt(void)
{
    char *reason = NULL;
    char *exe = NULL;
    GList *list = NULL;
    unsigned cnt = 0;
    char *line;
    while ((line = xmalloc_fgetline(stdin)) != NULL)
    {
        char *p = skip_pfx(line);

        /* xorg-server-1.12.0/os/osinit.c:
         * if (sip->si_code == SI_USER) {
         *     ErrorF("Recieved signal %d sent by process %ld, uid %ld\n",
         *             ^^^^^^^^ yes, typo here! Can't grep for this word! :(
         *            signo, (long) sip->si_pid, (long) sip->si_uid);
         * } else {
         *     switch (signo) {
         *         case SIGSEGV:
         *         case SIGBUS:
         *         case SIGILL:
         *         case SIGFPE:
         *             ErrorF("%s at address %p\n", strsignal(signo), sip->si_addr);
         */
        if (*p < '0' || *p > '9')
        {
            if (strstr(p, " at address ") || strstr(p, " sent by process "))
            {
                overlapping_strcpy(line, p);
                reason = line;
                line = NULL;
            }
            /* TODO: Other cases when we have useful reason string? */
            break;
        }

        errno = 0;
        char *end;
        IGNORE_RESULT(strtoul(p, &end, 10));
        if (errno || end == p || *end != ':')
            break;

        /* This looks like bt line */

        /* Guess Xorg server's executable name from it */
        if (!exe)
        {
            char *filename = skip_whitespace(end + 1);
            char *filename_end = skip_non_whitespace(filename);
            char sv = *filename_end;
            *filename_end = '\0';
            /* Does it look like "[/usr]/[s]bin/Xfoo"? */
            if (strstr(filename, "bin/X"))
                exe = xstrdup(filename);
            *filename_end = sv;
        }

        /* Save it to list */
        overlapping_strcpy(line, p);
        list = g_list_prepend(list, line);
        line = NULL;
        if (++cnt > 255) /* prevent ridiculously large bts */
            break;
    }
    free(line);

    if (list)
    {
        list = g_list_reverse(list);
        char *bt = list2lines(list); /* frees list */
        if (g_opts & OPT_o)
            printf("%s%s%s\n", bt, reason ? reason : "", reason ? "\n" : "");
        if (g_opts & (OPT_d|OPT_D))
            if (g_bt_count <= MAX_DUMPED_DD_COUNT)
                save_bt_to_dump_dir(bt, exe, reason ? reason : "Xorg server crashed");
        free(bt);
    }
    free(reason);
    free(exe);
}