[PATCH] allow python crashes without traceback (bz#578969)
by Miroslav Lichvar
---
src/hooks/abrt_exception_handler.py.in | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/hooks/abrt_exception_handler.py.in b/src/hooks/abrt_exception_handler.py.in
index e9d2e87..daa4e2e 100644
--- a/src/hooks/abrt_exception_handler.py.in
+++ b/src/hooks/abrt_exception_handler.py.in
@@ -138,11 +138,11 @@ def handleMyException((etype, value, tb)):
text += "".join(elist)
trace = tb
- while trace.tb_next:
- trace = trace.tb_next
- frame = trace.tb_frame
- text += ("\nLocal variables in innermost frame:\n")
try:
+ while trace.tb_next:
+ trace = trace.tb_next
+ frame = trace.tb_frame
+ text += ("\nLocal variables in innermost frame:\n")
for (key, val) in frame.f_locals.items():
text += "%s: %s\n" % (key, repr(val))
except:
--
1.7.6.4
12 years, 6 months
add some information to python tracebacks' reports
by Vratislav Podzimek
These two patches add some information to reports of python tracebacks. They are not supposed to be pushed in
this state but should show how the API should be changed to handle this kind of info.
--
Vratislav Podzimek
12 years, 6 months
[PATCH] wizard: disable only button box when event is run (trac#352)
by Miroslav Lichvar
---
src/gui-wizard-gtk/wizard.c | 23 ++++++++++++++---------
1 files changed, 14 insertions(+), 9 deletions(-)
diff --git a/src/gui-wizard-gtk/wizard.c b/src/gui-wizard-gtk/wizard.c
index decb5ee..df45598 100644
--- a/src/gui-wizard-gtk/wizard.c
+++ b/src/gui-wizard-gtk/wizard.c
@@ -90,6 +90,8 @@ static GtkWidget *g_top_most_window;
static GtkLabel *g_active_lbl;
static GtkProgressBar *g_active_pb;
+static GtkBox *g_box_assist_nav;
+
enum
{
/* Note: need to update types in
@@ -1595,7 +1597,7 @@ static gboolean consume_cmd_output(GIOChannel *source, GIOCondition condition, g
pb_pulse = false;
/* Enable (un-gray out) navigation buttons */
- gtk_widget_set_sensitive(GTK_WIDGET(g_assistant), true);
+ gtk_widget_set_sensitive(GTK_WIDGET(g_box_assist_nav), true);
/*g_source_remove(evd->event_source_id);*/
close(evd->fd);
@@ -1730,7 +1732,7 @@ static void start_event_run(const char *event_name,
free(msg);
/* Disable (gray out) navigation buttons */
- gtk_widget_set_sensitive(GTK_WIDGET(g_assistant), false);
+ gtk_widget_set_sensitive(GTK_WIDGET(g_box_assist_nav), false);
}
@@ -2457,16 +2459,19 @@ static void add_pages()
if (config_btn)
g_signal_connect(G_OBJECT(config_btn), "clicked", G_CALLBACK(on_show_event_list_cb), NULL);
- /* Add "Close" button */
GtkWidget *w;
+
+ /* Align "Close" button to left */
+ w = gtk_alignment_new(0.0, 0.0, 1.0, 1.0);
+ gtk_assistant_add_action_widget(g_assistant, w);
+ /* Keep pointer to the button box so we can set sensitivity later */
+ g_box_assist_nav = GTK_BOX(gtk_widget_get_parent(w));
+ gtk_box_set_child_packing(g_box_assist_nav, w, TRUE, FALSE, 0, GTK_PACK_END);
+ gtk_widget_show(w);
+
+ /* Add "Close" button */
if (!not_reportable)
{
- /* Align the "Close" button to left */
- w = gtk_alignment_new(0.0, 0.0, 1.0, 1.0);
- gtk_assistant_add_action_widget(g_assistant, w);
- gtk_box_set_child_packing(GTK_BOX(gtk_widget_get_parent(w)), w, TRUE, FALSE, 0, GTK_PACK_END);
- gtk_widget_show(w);
-
w = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
g_signal_connect(w, "clicked", G_CALLBACK(gtk_main_quit), NULL);
gtk_widget_show(w);
--
1.7.6.4
12 years, 7 months
[PATCH-abrt 1/2] testsuite for koops_extract_version
by Nikola Pajkovsky
Signed-off-by: Nikola Pajkovsky <npajkovs(a)redhat.com>
---
.gitignore | 9 +-
Makefile.am | 2 +-
configure.ac | 7 +
examples/oops-kernel-3.x.x | 43 +++++
src/include/libabrt.h | 6 +
src/lib/kernel.c | 366 +++++++++++++++++++++++++++++++++++++++++
src/plugins/abrt-dump-oops.c | 369 +-----------------------------------------
tests/Makefile.am | 54 ++++++
tests/atlocal.in | 15 ++
tests/koops-parser.at | 46 ++++++
tests/local.at | 27 +++
tests/testsuite.at | 4 +
12 files changed, 577 insertions(+), 371 deletions(-)
create mode 100644 examples/oops-kernel-3.x.x
create mode 100644 tests/Makefile.am
create mode 100644 tests/atlocal.in
create mode 100644 tests/koops-parser.at
create mode 100644 tests/local.at
create mode 100644 tests/testsuite.at
diff --git a/.gitignore b/.gitignore
index d0df191..8ae0534 100644
--- a/.gitignore
+++ b/.gitignore
@@ -64,9 +64,6 @@ libtool
ltmain.sh
py-compile
stamp-h1
-tests/atconfig
-tests/atlocal
-tests/package.m4
# pc files
src/btparser/btparser.pc
@@ -114,6 +111,12 @@ src/gui-wizard-gtk/wizard_glade.c
# generated man pages
*.[1,5,8]
+# generated files form testsuite
+testsuite*
+tests/atconfig
+tests/atlocal
+tests/package.m4
+
# if you want to enable them, be aware of that 'git clean -df' won't clean them
# and you have to do it *manually*
# x86_64/
diff --git a/Makefile.am b/Makefile.am
index 87b6fcb..95c748e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,5 +1,5 @@
ACLOCAL_AMFLAGS = -I m4
-SUBDIRS = src po icons
+SUBDIRS = src po icons tests
DISTCHECK_CONFIGURE_FLAGS = \
--with-systemdsystemunitdir=$$dc_install_base/$(systemdsystemunitdir)
diff --git a/configure.ac b/configure.ac
index 8debc2d..9eb44b6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -96,6 +96,13 @@ AC_SUBST(PLUGINS_CONF_DIR)
AC_SUBST(EVENTS_CONF_DIR)
AC_SUBST(EVENTS_DIR)
+# Initialize the test suite.
+AC_CONFIG_TESTDIR(tests)
+AC_CONFIG_FILES([tests/Makefile tests/atlocal])
+AM_MISSING_PROG([AUTOM4TE], [autom4te])
+# Needed by tests/atlocal.in.
+AC_SUBST([O0CFLAGS], [`echo $CFLAGS | sed 's/-O[[0-9]] *//'`])
+
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([
diff --git a/examples/oops-kernel-3.x.x b/examples/oops-kernel-3.x.x
new file mode 100644
index 0000000..1b37c5b
--- /dev/null
+++ b/examples/oops-kernel-3.x.x
@@ -0,0 +1,43 @@
+[ 3.908169] ------------[ cut here ]------------
+[ 3.910024] WARNING: at lib/dma-debug.c:800 check_unmap+0x9c/0x67f()
+[ 3.911885] firewire_ohci 0000:05:00.0: DMA-API: device driver tries to free an invalid DMA memory address
+[ 3.913793] Modules linked in: firewire_ohci(+) firewire_core crc_itu_t radeon ttm drm_kms_helper drm i2c_algo_bit i2c_core
+[ 3.915780] Pid: 202, comm: modprobe Not tainted 3.0.0-3.fc16.i686.PAE #1
+[ 3.917715] Call Trace:
+[ 3.919632] [<c04463d4>] warn_slowpath_common+0x7c/0x91
+[ 3.921557] [<c05fcc7a>] ? check_unmap+0x9c/0x67f
+[ 3.923467] [<c05fcc7a>] ? check_unmap+0x9c/0x67f
+[ 3.925335] [<c0446474>] warn_slowpath_fmt+0x33/0x35
+[ 3.927176] [<c05fcc7a>] check_unmap+0x9c/0x67f
+[ 3.929010] [<c05eeba4>] ? trace_hardirqs_on_thunk+0xc/0x10
+[ 3.930844] [<c05eebb4>] ? trace_hardirqs_off_thunk+0xc/0x10
+[ 3.932659] [<c084f3bd>] ? restore_all+0xf/0xf
+[ 3.934464] [<c04400d8>] ? rt_mutex_setprio+0xb2/0xf6
+[ 3.936274] [<c04464a1>] ? arch_local_irq_restore+0x5/0xb
+[ 3.938083] [<c05fd2b9>] debug_dma_free_coherent+0x5c/0x64
+[ 3.939895] [<f7a755ee>] dma_free_coherent+0x6a/0x8f [firewire_ohci]
+[ 3.941714] [<f7a77c9e>] ohci_enable+0x3c2/0x439 [firewire_ohci]
+[ 3.943524] [<f7a4d7c4>] fw_card_add+0x45/0x71 [firewire_core]
+[ 3.945331] [<f7a78e8d>] pci_probe+0x377/0x4a1 [firewire_ohci]
+[ 3.947126] [<c084f0f5>] ? _raw_spin_unlock_irqrestore+0x44/0x48
+[ 3.948933] [<c0605db8>] pci_device_probe+0x62/0xab
+[ 3.950733] [<c06a838e>] driver_probe_device+0x129/0x208
+[ 3.952528] [<c084dc54>] ? mutex_lock_nested+0x43/0x49
+[ 3.954328] [<c06a84bc>] __driver_attach+0x4f/0x6b
+[ 3.956104] [<c06a757f>] bus_for_each_dev+0x42/0x6b
+[ 3.957862] [<c06a7fc1>] driver_attach+0x1f/0x23
+[ 3.959613] [<c06a846d>] ? driver_probe_device+0x208/0x208
+[ 3.961355] [<c06a7c47>] bus_add_driver+0xcd/0x214
+[ 3.963071] [<c06a8902>] driver_register+0x84/0xe3
+[ 3.964779] [<c05f2e2b>] ? __raw_spin_lock_init+0x2d/0x4e
+[ 3.966479] [<c0606530>] __pci_register_driver+0x4f/0xab
+[ 3.968145] [<f7a39000>] ? 0xf7a38fff
+[ 3.969805] [<f7a39000>] ? 0xf7a38fff
+[ 3.971436] [<f7a39017>] fw_ohci_init+0x17/0x1000 [firewire_ohci]
+[ 3.973060] [<c04030a2>] do_one_initcall+0x8c/0x146
+[ 3.974685] [<c04296cf>] ? set_memory_nx+0x38/0x3a
+[ 3.976312] [<f7a39000>] ? 0xf7a38fff
+[ 3.977936] [<f7a39000>] ? 0xf7a38fff
+[ 3.979535] [<c047cea1>] sys_init_module+0x14b9/0x16dd
+[ 3.981135] [<c085525f>] sysenter_do_call+0x12/0x38
+[ 3.982726] ---[ end trace 50b7d6497bc6b1f4 ]---
diff --git a/src/include/libabrt.h b/src/include/libabrt.h
index 197e903..c902660 100644
--- a/src/include/libabrt.h
+++ b/src/include/libabrt.h
@@ -64,6 +64,12 @@ int daemon_is_ok();
#define kernel_tainted_short abrt_kernel_tainted_short
char *kernel_tainted_short(const char *kernel_bt);
+#define koops_extract_version abrt_koops_extract_version
+char *koops_extract_version(const char *linepointer);
+
+#define koops_extract_oopses abrt_koops_extract_oopses
+void koops_extract_oopses(GList **oops_list, char *buffer, size_t buflen);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/lib/kernel.c b/src/lib/kernel.c
index 0e96b05..7c77202 100644
--- a/src/lib/kernel.c
+++ b/src/lib/kernel.c
@@ -144,3 +144,369 @@ GList *kernel_tainted_long(unsigned tainted)
return tnt;
}
#endif
+
+/*
+ * extract_version tries to find the kernel version in given data
+ */
+char *koops_extract_version(const char *linepointer)
+{
+ if (strstr(linepointer, "Pid")
+ || strstr(linepointer, "comm")
+ || strstr(linepointer, "CPU")
+ || strstr(linepointer, "REGS")
+ || strstr(linepointer, "EFLAGS")
+ ) {
+ char* start;
+ char* end;
+
+ start = strstr((char*)linepointer, "2.6.");
+ if (start)
+ {
+ end = strchr(start, ')');
+ if (!end)
+ end = strchrnul(start, ' ');
+ return xstrndup(start, end-start);
+ }
+ }
+
+ return NULL;
+}
+
+/* npajkovs: remove 2 lines func; it's used only once!*/
+static void queue_oops(GList **vec, const char *data, const char *version)
+{
+ char *ver_data = xasprintf("%s\n%s", version, data);
+ *vec = g_list_append(*vec, ver_data);
+}
+
+/*
+ * extract_oops tries to find oops signatures in a log
+ */
+struct line_info {
+ char *ptr;
+ char level;
+};
+
+static void record_oops(GList **oops_list, struct line_info* lines_info, int oopsstart, int oopsend)
+{
+ int q;
+ int len;
+ int rv = 1;
+
+ len = 2;
+ for (q = oopsstart; q <= oopsend; q++)
+ len += strlen(lines_info[q].ptr) + 1;
+
+ /* too short oopses are invalid */
+ if (len > 100)
+ {
+ char *oops = (char*)xzalloc(len);
+ char *dst = oops;
+ char *version = NULL;
+ for (q = oopsstart; q <= oopsend; q++)
+ {
+ if (!version)
+ version = koops_extract_version(lines_info[q].ptr);
+ if (lines_info[q].ptr[0])
+ {
+ dst = stpcpy(dst, lines_info[q].ptr);
+ dst = stpcpy(dst, "\n");
+ }
+ }
+ if ((dst - oops) > 100)
+ queue_oops(oops_list, oops, version ? version : "undefined");
+ else
+ /* too short oopses are invalid */
+ rv = 0;
+ free(oops);
+ free(version);
+ }
+
+ VERB3 if (rv == 0) log("Dropped oops: too short");
+}
+
+void koops_extract_oopses(GList **oops_list, char *buffer, size_t buflen)
+{
+ char *c;
+ int linecount = 0;
+ int lines_info_size = 0;
+ struct line_info *lines_info = NULL;
+
+ /* Split buffer into lines */
+
+ if (buflen != 0)
+ buffer[buflen - 1] = '\n'; /* the buffer usually ends with \n, but let's make sure */
+ c = buffer;
+ while (c < buffer + buflen)
+ {
+ char linelevel;
+ char *c9;
+ char *colon;
+
+ linecount++;
+ c9 = (char*)memchr(c, '\n', buffer + buflen - c); /* a \n will always be found */
+ assert(c9);
+ *c9 = '\0'; /* turn the \n into a string termination */
+ if (c9 == c)
+ goto next_line;
+
+ /* Is it a syslog file (/var/log/messages or similar)?
+ * Even though _usually_ it looks like "Nov 19 12:34:38 localhost kernel: xxx",
+ * some users run syslog in non-C locale:
+ * "2010-02-22T09:24:08.156534-08:00 gnu-4 gnome-session[2048]: blah blah"
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ !!!
+ * We detect it by checking for N:NN:NN pattern in first 15 chars
+ * (and this still is not good enough... false positive: "pci 0000:15:00.0: PME# disabled")
+ */
+ colon = strchr(c, ':');
+ if (colon && colon > c && colon < c + 15
+ && isdigit(colon[-1]) /* N:... */
+ && isdigit(colon[1]) /* ...N:NN:... */
+ && isdigit(colon[2])
+ && colon[3] == ':'
+ && isdigit(colon[4]) /* ...N:NN:NN... */
+ && isdigit(colon[5])
+ ) {
+ /* It's syslog file, not a bare dmesg */
+
+ /* Skip non-kernel lines */
+ char *kernel_str = strstr(c, "kernel: ");
+ if (!kernel_str)
+ {
+ /* if we see our own marker:
+ * "hostname abrt: Kerneloops: Reported 1 kernel oopses to Abrt"
+ * we know we submitted everything upto here already */
+ if (strstr(c, "kernel oopses to Abrt"))
+ {
+ VERB3 log("Found our marker at line %d", linecount);
+ free(lines_info);
+ lines_info = NULL;
+ lines_info_size = 0;
+ list_free_with_free(*oops_list);
+ *oops_list = NULL;
+ }
+ goto next_line;
+ }
+ c = kernel_str + sizeof("kernel: ")-1;
+ }
+
+ linelevel = 0;
+ /* store and remove kernel log level */
+ if (*c == '<' && c[1] && c[2] == '>')
+ {
+ linelevel = c[1];
+ c += 3;
+ }
+ /* remove jiffies time stamp counter if present */
+ if (*c == '[')
+ {
+ char *c2 = strchr(c, '.');
+ char *c3 = strchr(c, ']');
+ if (c2 && c3 && (c2 < c3) && (c3-c) < 14 && (c2-c) < 8)
+ {
+ c = c3 + 1;
+ if (*c == ' ')
+ c++;
+ }
+ }
+ if ((lines_info_size & 0xfff) == 0)
+ {
+ lines_info = xrealloc(lines_info, (lines_info_size + 0x1000) * sizeof(lines_info[0]));
+ }
+ lines_info[lines_info_size].ptr = c;
+ lines_info[lines_info_size].level = linelevel;
+ lines_info_size++;
+next_line:
+ c = c9 + 1;
+ }
+
+ /* Analyze lines */
+
+ int i;
+ char prevlevel = 0;
+ int oopsstart = -1;
+ int inbacktrace = 0;
+
+ i = 0;
+ while (i < lines_info_size)
+ {
+ char *curline = lines_info[i].ptr;
+
+ if (curline == NULL)
+ {
+ i++;
+ continue;
+ }
+ while (*curline == ' ')
+ curline++;
+
+ if (oopsstart < 0)
+ {
+ /* Find start-of-oops markers */
+ /* In some comparisons, we skip 1st letter, to avoid dealing with
+ * changes in capitalization in kernel. For example, I see that
+ * current kernel git (at 2011-01-01) has both "kernel BUG at ..."
+ * and "Kernel BUG at ..." messages, and I don't want to change
+ * the code below whenever kernel is changed to use "K" (or "k")
+ * uniformly.
+ */
+ if (strstr(curline, /*g*/ "eneral protection fault:"))
+ oopsstart = i;
+ else if (strstr(curline, "BUG:"))
+ oopsstart = i;
+ else if (strstr(curline, /*k*/ "ernel BUG at"))
+ oopsstart = i;
+ else if (strstr(curline, "do_IRQ: stack overflow:"))
+ oopsstart = i;
+ else if (strstr(curline, "RTNL: assertion failed"))
+ oopsstart = i;
+ else if (strstr(curline, /*e*/ "eek! page_mapcount(page) went negative!"))
+ oopsstart = i;
+ else if (strstr(curline, /*n*/ "ear stack overflow (cur:"))
+ oopsstart = i;
+ else if (strstr(curline, /*d*/ "ouble fault:"))
+ oopsstart = i;
+ else if (strstr(curline, /*b*/ "adness at"))
+ oopsstart = i;
+ else if (strstr(curline, "NETDEV WATCHDOG"))
+ oopsstart = i;
+ else if (strstr(curline, "WARNING: at ")) /* WARN_ON() generated message */
+ oopsstart = i;
+ else if (strstr(curline, /*u*/ "nable to handle kernel"))
+ oopsstart = i;
+ else if (strstr(curline, /*s*/ "ysctl table check failed"))
+ oopsstart = i;
+ else if (strstr(curline, "INFO: possible recursive locking detected"))
+ oopsstart = i;
+ // Not needed: "--[ cut here ]--" is always followed
+ // by "Badness at", "kernel BUG at", or "WARNING: at" string
+ //else if (strstr(curline, "------------[ cut here ]------------"))
+ // oopsstart = i;
+ else if (strstr(curline, "list_del corruption"))
+ oopsstart = i;
+ else if (strstr(curline, "list_add corruption"))
+ oopsstart = i;
+
+ if (i >= 3 && strstr(curline, "Oops:"))
+ oopsstart = i-3;
+
+ if (oopsstart >= 0)
+ {
+ /* debug information */
+ VERB3 {
+ log("Found oops at line %d: '%s'", oopsstart, lines_info[oopsstart].ptr);
+ if (oopsstart != i)
+ log("Trigger line is %d: '%s'", i, c);
+ }
+ /* try to find the end marker */
+ int i2 = i + 1;
+ while (i2 < lines_info_size && i2 < (i+50))
+ {
+ if (strstr(lines_info[i2].ptr, "---[ end trace"))
+ {
+ inbacktrace = 1;
+ i = i2;
+ break;
+ }
+ i2++;
+ }
+ }
+ }
+
+ /* Are we entering a call trace part? */
+ /* a call trace starts with "Call Trace:" or with the " [<.......>] function+0xFF/0xAA" pattern */
+ if (oopsstart >= 0 && !inbacktrace)
+ {
+ if (strstr(curline, "Call Trace:"))
+ inbacktrace = 1;
+ else
+ if (strnlen(curline, 9) > 8
+ && curline[0] == '[' && curline[1] == '<'
+ && strstr(curline, ">]")
+ && strstr(curline, "+0x")
+ && strstr(curline, "/0x")
+ ) {
+ inbacktrace = 1;
+ }
+ }
+
+ /* Are we at the end of an oops? */
+ else if (oopsstart >= 0 && inbacktrace)
+ {
+ int oopsend = INT_MAX;
+
+ /* line needs to start with " [" or have "] [" if it is still a call trace */
+ /* example: "[<ffffffffa006c156>] radeon_get_ring_head+0x16/0x41 [radeon]" */
+ if (curline[0] != '['
+ && !strstr(curline, "] [")
+ && !strstr(curline, "--- Exception")
+ && !strstr(curline, "LR =")
+ && !strstr(curline, "<#DF>")
+ && !strstr(curline, "<IRQ>")
+ && !strstr(curline, "<EOI>")
+ && !strstr(curline, "<<EOE>>")
+ && strncmp(curline, "Code: ", 6) != 0
+ && strncmp(curline, "RIP ", 4) != 0
+ && strncmp(curline, "RSP ", 4) != 0
+ ) {
+ oopsend = i-1; /* not a call trace line */
+ }
+ /* oops lines are always more than 8 chars long */
+ else if (strnlen(curline, 8) < 8)
+ oopsend = i-1;
+ /* single oopses are of the same loglevel */
+ else if (lines_info[i].level != prevlevel)
+ oopsend = i-1;
+ else if (strstr(curline, "Instruction dump:"))
+ oopsend = i;
+ /* if a new oops starts, this one has ended */
+ else if (strstr(curline, "WARNING: at ") && oopsstart != i) /* WARN_ON() generated message */
+ oopsend = i-1;
+ else if (strstr(curline, "Unable to handle") && oopsstart != i)
+ oopsend = i-1;
+ /* kernel end-of-oops marker (not including marker itself) */
+ else if (strstr(curline, "---[ end trace"))
+ oopsend = i-1;
+
+ if (oopsend <= i)
+ {
+ VERB3 log("End of oops at line %d (%d): '%s'", oopsend, i, lines_info[oopsend].ptr);
+ record_oops(oops_list, lines_info, oopsstart, oopsend);
+ oopsstart = -1;
+ inbacktrace = 0;
+ }
+ }
+
+ prevlevel = lines_info[i].level;
+ i++;
+
+ if (oopsstart >= 0)
+ {
+ /* Do we have a suspiciously long oops? Cancel it */
+ if (i-oopsstart > 60)
+ {
+ inbacktrace = 0;
+ oopsstart = -1;
+ VERB3 log("Dropped oops, too long");
+ continue;
+ }
+ if (!inbacktrace && i-oopsstart > 40)
+ {
+ /*inbacktrace = 0; - already is */
+ oopsstart = -1;
+ VERB3 log("Dropped oops, too long");
+ continue;
+ }
+ }
+ } /* while (i < lines_info_size) */
+
+ /* process last oops if we have one */
+ if (oopsstart >= 0 && inbacktrace)
+ {
+ int oopsend = i-1;
+ VERB3 log("End of oops at line %d (end of file): '%s'", oopsend, lines_info[oopsend].ptr);
+ record_oops(oops_list, lines_info, oopsstart, oopsend);
+ }
+
+ free(lines_info);
+}
diff --git a/src/plugins/abrt-dump-oops.c b/src/plugins/abrt-dump-oops.c
index 81c41a1..17b7d05 100644
--- a/src/plugins/abrt-dump-oops.c
+++ b/src/plugins/abrt-dump-oops.c
@@ -25,371 +25,6 @@
static bool world_readable_dump = false;
static const char *debug_dumps_dir = ".";
-static void queue_oops(GList **vec, const char *data, const char *version)
-{
- char *ver_data = xasprintf("%s\n%s", version, data);
- *vec = g_list_append(*vec, ver_data);
-}
-
-/*
- * extract_version tries to find the kernel version in given data
- */
-static char *extract_version(const char *linepointer)
-{
- if (strstr(linepointer, "Pid")
- || strstr(linepointer, "comm")
- || strstr(linepointer, "CPU")
- || strstr(linepointer, "REGS")
- || strstr(linepointer, "EFLAGS")
- ) {
- char* start;
- char* end;
-
- start = strstr((char*)linepointer, "2.6.");
- if (start)
- {
- end = strchr(start, ')');
- if (!end)
- end = strchrnul(start, ' ');
- return xstrndup(start, end-start);
- }
- }
-
- return NULL;
-}
-
-/*
- * extract_oops tries to find oops signatures in a log
- */
-struct line_info {
- char *ptr;
- char level;
-};
-
-static void record_oops(GList **oops_list, struct line_info* lines_info, int oopsstart, int oopsend)
-{
- int q;
- int len;
- int rv = 1;
-
- len = 2;
- for (q = oopsstart; q <= oopsend; q++)
- len += strlen(lines_info[q].ptr) + 1;
-
- /* too short oopses are invalid */
- if (len > 100)
- {
- char *oops = (char*)xzalloc(len);
- char *dst = oops;
- char *version = NULL;
- for (q = oopsstart; q <= oopsend; q++)
- {
- if (!version)
- version = extract_version(lines_info[q].ptr);
- if (lines_info[q].ptr[0])
- {
- dst = stpcpy(dst, lines_info[q].ptr);
- dst = stpcpy(dst, "\n");
- }
- }
- if ((dst - oops) > 100)
- queue_oops(oops_list, oops, version ? version : "undefined");
- else
- /* too short oopses are invalid */
- rv = 0;
- free(oops);
- free(version);
- }
-
- VERB3 if (rv == 0) log("Dropped oops: too short");
-}
-
-static void extract_oopses(GList **oops_list, char *buffer, size_t buflen)
-{
- char *c;
- int linecount = 0;
- int lines_info_size = 0;
- struct line_info *lines_info = NULL;
-
- /* Split buffer into lines */
-
- if (buflen != 0)
- buffer[buflen - 1] = '\n'; /* the buffer usually ends with \n, but let's make sure */
- c = buffer;
- while (c < buffer + buflen)
- {
- char linelevel;
- char *c9;
- char *colon;
-
- linecount++;
- c9 = (char*)memchr(c, '\n', buffer + buflen - c); /* a \n will always be found */
- assert(c9);
- *c9 = '\0'; /* turn the \n into a string termination */
- if (c9 == c)
- goto next_line;
-
- /* Is it a syslog file (/var/log/messages or similar)?
- * Even though _usually_ it looks like "Nov 19 12:34:38 localhost kernel: xxx",
- * some users run syslog in non-C locale:
- * "2010-02-22T09:24:08.156534-08:00 gnu-4 gnome-session[2048]: blah blah"
- * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ !!!
- * We detect it by checking for N:NN:NN pattern in first 15 chars
- * (and this still is not good enough... false positive: "pci 0000:15:00.0: PME# disabled")
- */
- colon = strchr(c, ':');
- if (colon && colon > c && colon < c + 15
- && isdigit(colon[-1]) /* N:... */
- && isdigit(colon[1]) /* ...N:NN:... */
- && isdigit(colon[2])
- && colon[3] == ':'
- && isdigit(colon[4]) /* ...N:NN:NN... */
- && isdigit(colon[5])
- ) {
- /* It's syslog file, not a bare dmesg */
-
- /* Skip non-kernel lines */
- char *kernel_str = strstr(c, "kernel: ");
- if (!kernel_str)
- {
- /* if we see our own marker:
- * "hostname abrt: Kerneloops: Reported 1 kernel oopses to Abrt"
- * we know we submitted everything upto here already */
- if (strstr(c, "kernel oopses to Abrt"))
- {
- VERB3 log("Found our marker at line %d", linecount);
- free(lines_info);
- lines_info = NULL;
- lines_info_size = 0;
- list_free_with_free(*oops_list);
- *oops_list = NULL;
- }
- goto next_line;
- }
- c = kernel_str + sizeof("kernel: ")-1;
- }
-
- linelevel = 0;
- /* store and remove kernel log level */
- if (*c == '<' && c[1] && c[2] == '>')
- {
- linelevel = c[1];
- c += 3;
- }
- /* remove jiffies time stamp counter if present */
- if (*c == '[')
- {
- char *c2 = strchr(c, '.');
- char *c3 = strchr(c, ']');
- if (c2 && c3 && (c2 < c3) && (c3-c) < 14 && (c2-c) < 8)
- {
- c = c3 + 1;
- if (*c == ' ')
- c++;
- }
- }
- if ((lines_info_size & 0xfff) == 0)
- {
- lines_info = xrealloc(lines_info, (lines_info_size + 0x1000) * sizeof(lines_info[0]));
- }
- lines_info[lines_info_size].ptr = c;
- lines_info[lines_info_size].level = linelevel;
- lines_info_size++;
-next_line:
- c = c9 + 1;
- }
-
- /* Analyze lines */
-
- int i;
- char prevlevel = 0;
- int oopsstart = -1;
- int inbacktrace = 0;
-
- i = 0;
- while (i < lines_info_size)
- {
- char *curline = lines_info[i].ptr;
-
- if (curline == NULL)
- {
- i++;
- continue;
- }
- while (*curline == ' ')
- curline++;
-
- if (oopsstart < 0)
- {
- /* Find start-of-oops markers */
- /* In some comparisons, we skip 1st letter, to avoid dealing with
- * changes in capitalization in kernel. For example, I see that
- * current kernel git (at 2011-01-01) has both "kernel BUG at ..."
- * and "Kernel BUG at ..." messages, and I don't want to change
- * the code below whenever kernel is changed to use "K" (or "k")
- * uniformly.
- */
- if (strstr(curline, /*g*/ "eneral protection fault:"))
- oopsstart = i;
- else if (strstr(curline, "BUG:"))
- oopsstart = i;
- else if (strstr(curline, /*k*/ "ernel BUG at"))
- oopsstart = i;
- else if (strstr(curline, "do_IRQ: stack overflow:"))
- oopsstart = i;
- else if (strstr(curline, "RTNL: assertion failed"))
- oopsstart = i;
- else if (strstr(curline, /*e*/ "eek! page_mapcount(page) went negative!"))
- oopsstart = i;
- else if (strstr(curline, /*n*/ "ear stack overflow (cur:"))
- oopsstart = i;
- else if (strstr(curline, /*d*/ "ouble fault:"))
- oopsstart = i;
- else if (strstr(curline, /*b*/ "adness at"))
- oopsstart = i;
- else if (strstr(curline, "NETDEV WATCHDOG"))
- oopsstart = i;
- else if (strstr(curline, "WARNING: at ")) /* WARN_ON() generated message */
- oopsstart = i;
- else if (strstr(curline, /*u*/ "nable to handle kernel"))
- oopsstart = i;
- else if (strstr(curline, /*s*/ "ysctl table check failed"))
- oopsstart = i;
- else if (strstr(curline, "INFO: possible recursive locking detected"))
- oopsstart = i;
- // Not needed: "--[ cut here ]--" is always followed
- // by "Badness at", "kernel BUG at", or "WARNING: at" string
- //else if (strstr(curline, "------------[ cut here ]------------"))
- // oopsstart = i;
- else if (strstr(curline, "list_del corruption"))
- oopsstart = i;
- else if (strstr(curline, "list_add corruption"))
- oopsstart = i;
-
- if (i >= 3 && strstr(curline, "Oops:"))
- oopsstart = i-3;
-
- if (oopsstart >= 0)
- {
- /* debug information */
- VERB3 {
- log("Found oops at line %d: '%s'", oopsstart, lines_info[oopsstart].ptr);
- if (oopsstart != i)
- log("Trigger line is %d: '%s'", i, c);
- }
- /* try to find the end marker */
- int i2 = i + 1;
- while (i2 < lines_info_size && i2 < (i+50))
- {
- if (strstr(lines_info[i2].ptr, "---[ end trace"))
- {
- inbacktrace = 1;
- i = i2;
- break;
- }
- i2++;
- }
- }
- }
-
- /* Are we entering a call trace part? */
- /* a call trace starts with "Call Trace:" or with the " [<.......>] function+0xFF/0xAA" pattern */
- if (oopsstart >= 0 && !inbacktrace)
- {
- if (strstr(curline, "Call Trace:"))
- inbacktrace = 1;
- else
- if (strnlen(curline, 9) > 8
- && curline[0] == '[' && curline[1] == '<'
- && strstr(curline, ">]")
- && strstr(curline, "+0x")
- && strstr(curline, "/0x")
- ) {
- inbacktrace = 1;
- }
- }
-
- /* Are we at the end of an oops? */
- else if (oopsstart >= 0 && inbacktrace)
- {
- int oopsend = INT_MAX;
-
- /* line needs to start with " [" or have "] [" if it is still a call trace */
- /* example: "[<ffffffffa006c156>] radeon_get_ring_head+0x16/0x41 [radeon]" */
- if (curline[0] != '['
- && !strstr(curline, "] [")
- && !strstr(curline, "--- Exception")
- && !strstr(curline, "LR =")
- && !strstr(curline, "<#DF>")
- && !strstr(curline, "<IRQ>")
- && !strstr(curline, "<EOI>")
- && !strstr(curline, "<<EOE>>")
- && strncmp(curline, "Code: ", 6) != 0
- && strncmp(curline, "RIP ", 4) != 0
- && strncmp(curline, "RSP ", 4) != 0
- ) {
- oopsend = i-1; /* not a call trace line */
- }
- /* oops lines are always more than 8 chars long */
- else if (strnlen(curline, 8) < 8)
- oopsend = i-1;
- /* single oopses are of the same loglevel */
- else if (lines_info[i].level != prevlevel)
- oopsend = i-1;
- else if (strstr(curline, "Instruction dump:"))
- oopsend = i;
- /* if a new oops starts, this one has ended */
- else if (strstr(curline, "WARNING: at ") && oopsstart != i) /* WARN_ON() generated message */
- oopsend = i-1;
- else if (strstr(curline, "Unable to handle") && oopsstart != i)
- oopsend = i-1;
- /* kernel end-of-oops marker (not including marker itself) */
- else if (strstr(curline, "---[ end trace"))
- oopsend = i-1;
-
- if (oopsend <= i)
- {
- VERB3 log("End of oops at line %d (%d): '%s'", oopsend, i, lines_info[oopsend].ptr);
- record_oops(oops_list, lines_info, oopsstart, oopsend);
- oopsstart = -1;
- inbacktrace = 0;
- }
- }
-
- prevlevel = lines_info[i].level;
- i++;
-
- if (oopsstart >= 0)
- {
- /* Do we have a suspiciously long oops? Cancel it */
- if (i-oopsstart > 60)
- {
- inbacktrace = 0;
- oopsstart = -1;
- VERB3 log("Dropped oops, too long");
- continue;
- }
- if (!inbacktrace && i-oopsstart > 40)
- {
- /*inbacktrace = 0; - already is */
- oopsstart = -1;
- VERB3 log("Dropped oops, too long");
- continue;
- }
- }
- } /* while (i < lines_info_size) */
-
- /* process last oops if we have one */
- if (oopsstart >= 0 && inbacktrace)
- {
- int oopsend = i-1;
- VERB3 log("End of oops at line %d (end of file): '%s'", oopsend, lines_info[oopsend].ptr);
- record_oops(oops_list, lines_info, oopsstart, oopsend);
- }
-
- free(lines_info);
-}
-
#define MAX_SCAN_BLOCK (4*1024*1024)
#define READ_AHEAD (10*1024)
@@ -404,7 +39,7 @@ static void scan_dmesg(GList **oops_list)
*/
char *buffer = xzalloc(16*1024);
syscall(__NR_syslog, 3, buffer, 16*1024 - 1); /* always NUL terminated */
- extract_oopses(oops_list, buffer, strlen(buffer));
+ koops_extract_oopses(oops_list, buffer, strlen(buffer));
free(buffer);
}
@@ -463,7 +98,7 @@ static int scan_syslog_file(GList **oops_list, int fd, struct stat *statbuf, int
if (partial_line_len > 500) /* cap it */
partial_line_len = 500;
- extract_oopses(oops_list, buffer, r);
+ koops_extract_oopses(oops_list, buffer, r);
cur_pos += r;
} while (cur_pos < statbuf->st_size);
diff --git a/tests/Makefile.am b/tests/Makefile.am
new file mode 100644
index 0000000..5dcea73
--- /dev/null
+++ b/tests/Makefile.am
@@ -0,0 +1,54 @@
+## ------------ ##
+## package.m4. ##
+## ------------ ##
+
+package.m4: Makefile.in
+ { \
+ echo '# Signature of the current package.' && \
+ echo 'm4_define([AT_PACKAGE_NAME],' && \
+ echo ' [@PACKAGE_NAME@])' && \
+ echo 'm4_define([AT_PACKAGE_TARNAME],' && \
+ echo ' [@PACKAGE_TARNAME@])' && \
+ echo 'm4_define([AT_PACKAGE_VERSION],' && \
+ echo ' [@PACKAGE_VERSION@])' && \
+ echo 'm4_define([AT_PACKAGE_STRING],' && \
+ echo ' [@PACKAGE_STRING@])' && \
+ echo 'm4_define([AT_PACKAGE_BUGREPORT],' && \
+ echo ' [@PACKAGE_BUGREPORT@])'; \
+ echo 'm4_define([AT_PACKAGE_URL],' && \
+ echo ' [@PACKAGE_URL@])'; \
+ } >'package.m4'
+EXTRA_DIST = package.m4
+
+## ------------ ##
+## Test suite. ##
+## ------------ ##
+
+TESTSUITE_AT = \
+ local.at \
+ testsuite.at \
+ koops-parser.at
+
+EXTRA_DIST += $(TESTSUITE_AT)
+TESTSUITE = $(srcdir)/testsuite
+MAINTAINERCLEANFILES = Makefile.in $(TESTSUITE)
+check_DATA = atconfig atlocal $(TESTSUITE)
+DISTCLEANFILES = atconfig
+EXTRA_DIST += atlocal.in
+
+atconfig: $(top_builddir)/config.status
+ (cd ${top_builddir} && ./config.status ${subdir}/atconfig)
+
+check-local: $(check_DATA)
+ $(SHELL) '$(TESTSUITE)' $(TESTSUITEFLAGS) ||:
+
+installcheck-local: $(check_DATA)
+ $(SHELL) '$(TESTSUITE)' AUTOTEST_PATH='$(bindir)' $(TESTSUITEFLAGS) ||:
+
+clean-local:
+ test ! -f '$(TESTSUITE)' || $(SHELL) '$(TESTSUITE)' --clean
+
+AUTOTEST = $(AUTOM4TE) --language=autotest
+$(TESTSUITE): $(TESTSUITE_AT) $(srcdir)/package.m4
+ $(AUTOTEST) -I '$(srcdir)' -o $@.tmp $@.at
+ mv $@.tmp $@
diff --git a/tests/atlocal.in b/tests/atlocal.in
new file mode 100644
index 0000000..00c6885
--- /dev/null
+++ b/tests/atlocal.in
@@ -0,0 +1,15 @@
+# @configure_input@ -*- shell-script -*-
+# Configurable variable values for btparser test suite.
+
+# We need a C compiler.
+CC='@CC@'
+LIBTOOL="$abs_top_builddir/libtool"
+
+# We want no optimization.
+CFLAGS="@O0CFLAGS@ -I$abs_top_builddir/src/include -D_GNU_SOURCE @GLIB_CFLAGS@ @LIBREPORT_CFLAGS@"
+
+# Are special link options needed?
+LDFLAGS="@LDFLAGS@ $abs_top_builddir/src/lib/libabrt.la"
+
+# Are special libraries needed?
+LIBS="@LIBS@ @LIBREPORT_LIBS@"
diff --git a/tests/koops-parser.at b/tests/koops-parser.at
new file mode 100644
index 0000000..620903b
--- /dev/null
+++ b/tests/koops-parser.at
@@ -0,0 +1,46 @@
+# -*- Autotest -*-
+
+AT_BANNER([kernel_oops_parser])
+
+AT_TESTFUN([koops_extract_version],
+[[
+#include "libabrt.h"
+
+int run_test(const char *filename)
+{
+ FILE *fp = fopen(filename, "r");
+ if (!fp)
+ perror_msg_and_die("Can't open '%s'", filename);
+
+ char *line;
+ while ((line = xmalloc_fgetline(fp)) != NULL)
+ {
+ char *version = koops_extract_version(line);
+ if (version)
+ {
+ log("version %s", version);
+ return 0;
+ }
+
+ free(line);
+ }
+ fclose(fp);
+ return 1;
+}
+
+int main(void)
+{
+ /* tests run in abrt/tests/testsuite.dir/X, where X is test number */
+ char *filenames[] = {
+ "../../../examples/cut_here.right",
+ "../../../examples/oops-kernel-3.x.x",
+ NULL
+ };
+ int ret = 0;
+ char **tmp = filenames;
+ for ( ; *tmp; tmp++)
+ ret |= run_test(*tmp);
+
+ return ret;
+}
+]])
diff --git a/tests/local.at b/tests/local.at
new file mode 100644
index 0000000..758906d
--- /dev/null
+++ b/tests/local.at
@@ -0,0 +1,27 @@
+# Source: bison local.at
+
+# ----------------------------------------
+# AT_COMPILE(OUTPUT, [SOURCES = OUTPUT.c])
+# ----------------------------------------
+# Compile SOURCES into OUTPUT. If OUTPUT does not contain '.',
+# assume that we are linking too; this is a hack.
+m4_define([AT_COMPILE],
+[AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS m4_bmatch([$1], [[.]], [], [$LDFLAGS ])-o $1 m4_default([$2], [$1.c])[]m4_bmatch([$1], [[.]], [], [ $LIBS])],
+ 0, [ignore], [ignore])])
+
+# ------------------------
+# AT_TESTFUN(NAME, SOURCE)
+# ------------------------
+
+# Create a test named NAME by compiling and running C file with
+# contents SOURCE. The stdout and stderr output of the C program is
+# ignored by Autotest.
+
+m4_define([AT_TESTFUN],
+[AT_SETUP([$1])
+AT_DATA([$1.c], [$2])
+AT_COMPILE([$1])
+AT_CHECK([./$1], 0, [ignore], [ignore])
+AT_CLEANUP])
+
+AT_INIT
diff --git a/tests/testsuite.at b/tests/testsuite.at
new file mode 100644
index 0000000..807da66
--- /dev/null
+++ b/tests/testsuite.at
@@ -0,0 +1,4 @@
+# Test suite for abrt.
+# See http://www.gnu.org/software/hello/manual/autoconf/Writing-Testsuites.html
+
+m4_include([koops-parser.at])
--
1.7.7.138.g7f41b6
12 years, 7 months
[PATCH] wizard: align close button to left (bz#741230)
by Miroslav Lichvar
---
src/gui-wizard-gtk/wizard.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/src/gui-wizard-gtk/wizard.c b/src/gui-wizard-gtk/wizard.c
index 10c2342..6437c0a 100644
--- a/src/gui-wizard-gtk/wizard.c
+++ b/src/gui-wizard-gtk/wizard.c
@@ -2409,6 +2409,12 @@ static void add_pages()
GtkWidget *w;
if (!not_reportable)
{
+ /* Align the "Close" button to left */
+ w = gtk_alignment_new(0.0, 0.0, 1.0, 1.0);
+ gtk_assistant_add_action_widget(g_assistant, w);
+ gtk_box_set_child_packing(GTK_BOX(gtk_widget_get_parent(w)), w, TRUE, FALSE, 0, GTK_PACK_END);
+ gtk_widget_show(w);
+
w = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
g_signal_connect(w, "clicked", G_CALLBACK(gtk_main_quit), NULL);
gtk_widget_show(w);
--
1.7.6.4
12 years, 7 months