Canonical backtrace branch
by Martin Milata
Hi,
I just pushed the branch 'canonical_backtrace' to both abrt and
libreport git repos. This is part of the effort to implement quick,
local check for duplicate bugs for ccpp-generated crashes without the
need for debuginfos. More info below if you're curious.
The idea is that the binary abrt-action-generate-canonical-backtrace
will be run in post-create hook and will extract 'canonical' backtrace
from the core dump. This canonical backtrace is a text file, which
contains one line for each function frame from the core dump stack. We
should be able to decide whether two lines represent the same function
and thus, using a string comparison algorithm (to be done), to decide
whether two such backtraces are a manifestation of the same bug.
Currently, each line contains:
- symbol name, if it is present in the binary (which is the case of
public functions in shared libraries)
- build id and instruction pointer offset relative to the start of
executable segment of the binary -- this should allow us to decide
stack frame equality for two crashes of the same build of a binary,
for more info see [1]
- file name (i.e. library or "[exe]") the code was loaded from
However, we would also like this approach to work on two different
builds of the same (or slightly different) binaries. We'd like to
achieve this by computing a 'fingerprint' of assembly of each function
in the file. This is somewhat tricky and we're still figuring out how to
do it effectively.
Question: is it ok to change history/rebase such development branch,
even though it's published?
Cheers,
Martin Milata
[1] http://fedoraproject.org/wiki/Summer_Coding_2010_ideas_-_Universal_Build-...
12 years, 7 months
[PATCH-libreport] Show 'reason' in the title of GUI wizard
by Martin Milata
This is an attempt to solve #304 (wrong title when reporting from
setroubleshoot). SETroubleshoot does not provide the name of the
application in question (or was setroubleshoot itself meant as the
application name?), so this patch uses the 'reason' item instead of the
dump dir path. This is IMHO more informative even in the typical ABRT
case.
Is that OK or should I display something else in the title (possibly
explicitly passed to libreport by setroubleshoot)?
---
src/gui-wizard-gtk/wizard.c | 9 ++++++---
1 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/src/gui-wizard-gtk/wizard.c b/src/gui-wizard-gtk/wizard.c
index 06a184a..bd4b5bb 100644
--- a/src/gui-wizard-gtk/wizard.c
+++ b/src/gui-wizard-gtk/wizard.c
@@ -374,7 +374,11 @@ struct dump_dir *steal_if_needed(struct dump_dir *dd)
g_dump_dir_name = xstrdup(dd->dd_dirname);
dd_close(dd);
- gtk_window_set_title(GTK_WINDOW(g_assistant), g_dump_dir_name);
+ /* reset the window title in case it fell back to g_dump_dir_name */
+ const char *reason = get_problem_item_content_or_NULL(g_cd, FILENAME_REASON);
+ if (reason == NULL)
+ gtk_window_set_title(GTK_WINDOW(g_assistant), g_dump_dir_name);
+
delete_dump_dir_possibly_using_abrtd(old_name); //TODO: if (deletion_failed) error_msg("BAD")?
free(old_name);
@@ -1010,10 +1014,9 @@ static void update_event_checkboxes(GList **events_gui_data,
void update_gui_state_from_problem_data(void)
{
- gtk_window_set_title(GTK_WINDOW(g_assistant), g_dump_dir_name);
-
const char *reason = get_problem_item_content_or_NULL(g_cd, FILENAME_REASON);
gtk_label_set_text(g_lbl_cd_reason, reason ? reason : _("(no description)"));
+ gtk_window_set_title(GTK_WINDOW(g_assistant), reason ? reason : g_dump_dir_name);
gtk_list_store_clear(g_ls_details);
struct cd_stats stats = { 0 };
--
1.7.6
12 years, 7 months
[PATCH 1/2] wizard: keep problem data selectable after attaching file (trac#344)
by Miroslav Lichvar
---
src/gui-wizard-gtk/main.c | 6 ++++++
src/gui-wizard-gtk/wizard.c | 12 +++++++++++-
2 files changed, 17 insertions(+), 1 deletions(-)
diff --git a/src/gui-wizard-gtk/main.c b/src/gui-wizard-gtk/main.c
index 6c37139..66402f2 100644
--- a/src/gui-wizard-gtk/main.c
+++ b/src/gui-wizard-gtk/main.c
@@ -63,10 +63,16 @@ void reload_problem_data_from_dump_dir(void)
if (old_item)
{
new_item->selected_by_user = old_item->selected_by_user;
+ new_item->allowed_by_reporter = old_item->allowed_by_reporter;
+ new_item->default_by_reporter = old_item->default_by_reporter;
+ new_item->required_by_reporter = old_item->required_by_reporter;
}
else
{
new_item->selected_by_user = 0;
+ new_item->allowed_by_reporter = 0;
+ new_item->default_by_reporter = 0;
+ new_item->required_by_reporter = 0;
}
//log("%s: was ->selected_by_user=%d", __func__, new_item->selected_by_user);
}
diff --git a/src/gui-wizard-gtk/wizard.c b/src/gui-wizard-gtk/wizard.c
index 0279f83..3494125 100644
--- a/src/gui-wizard-gtk/wizard.c
+++ b/src/gui-wizard-gtk/wizard.c
@@ -971,6 +971,17 @@ static void append_item_to_ls_details(gpointer name, gpointer value, gpointer da
-1);
free(msg);
}
+
+ int cur_value;
+ if (item->selected_by_user == 0)
+ cur_value = item->default_by_reporter;
+ else
+ cur_value = !!(item->selected_by_user + 1); /* map -1,1 to 0,1 */
+
+ gtk_list_store_set(g_ls_details, &iter,
+ DETAIL_COLUMN_CHECKBOX, cur_value,
+ -1);
+}
}
/* Update collector/reporter checkboxes according to events parameter.
@@ -2173,7 +2184,6 @@ static void on_btn_add_file(GtkButton *button)
}
if (!message)
{
-// FIXME: this destroys checkbox settings for each item!
reload_problem_data_from_dump_dir();
update_gui_state_from_problem_data();
}
--
1.7.6.2
12 years, 7 months
[PATCH] rhbz#724838 - don't file kernel bugs if "tainted: B" is set
by Nikola Pajkovsky
Kernel maintainers are not much happy that we filling bugs when kernel
is tainted.
Dave Jones said
---
If something has corrupted memory, we typically see a whole bunch of things
start crashing. This leads to situations where abrt files a lot of bugs, even
though most of them are just fallout from the first.
an example: bugs 710925 710930 710932 710933 710935 710942 710948 710955 710956
are all the same crash. The traces and addresses are different, but 'something
scribbled over memory' is the root cause here. Sadly out of all those bugs, we
actually somehow missed the first crash which is the most relevant one. (That
one would have not had the 'Tainted: G B' text)
---
First part of the patch is that we won't relay on /proc/sys/kernel/tainted and
we will parse the kernel bt manually, because of reading that file after an oops
is ALWAYS going to show it as tainted.
Second part of the patch is that whenever you want to prohibit reporting, put a
file with name *not-reportable* into <dump-dir>. That file could be empty or with
reasonable message why are you trying to prohibit reporting.
All 3 reporters plugins will be respect that file and it won't try to report anything.
Reporters will show only the messages from *not-reportable* and *reason*.
Signed-off-by: Nikola Pajkovsky <npajkovs(a)redhat.com>
---
src/gui-gtk/main.c | 15 ++++++++--
src/plugins/abrt-dump-oops.c | 65 +++++++++++++++++++++++------------------
2 files changed, 48 insertions(+), 32 deletions(-)
diff --git a/src/gui-gtk/main.c b/src/gui-gtk/main.c
index 8172951..ef57424 100644
--- a/src/gui-gtk/main.c
+++ b/src/gui-gtk/main.c
@@ -100,7 +100,14 @@ static void add_directory_to_dirlist(const char *dirname)
}
free(time_str);
- char *reason = dd_load_text(dd, FILENAME_REASON);
+
+ char *not_reportalbe_reason = dd_load_text_ext(dd, FILENAME_NOT_REPORTABLE, 0
+ | DD_LOAD_TEXT_RETURN_NULL_ON_FAILURE
+ | DD_FAIL_QUIETLY_ENOENT
+ | DD_FAIL_QUIETLY_EACCES);
+ char *reason = NULL;
+ if (!not_reportalbe_reason)
+ reason = dd_load_text(dd, FILENAME_REASON);
/* the source of the problem:
* - first we try to load component, as we use it on Fedora
@@ -142,7 +149,7 @@ static void add_directory_to_dirlist(const char *dirname)
gtk_list_store_append(list_store, &iter);
gtk_list_store_set(list_store, &iter,
COLUMN_SOURCE, source,
- COLUMN_REASON, reason,
+ COLUMN_REASON, not_reportalbe_reason? :reason,
//OPTION: time format
COLUMN_LATEST_CRASH_STR, time_buf,
COLUMN_LATEST_CRASH, t,
@@ -243,7 +250,9 @@ static void on_row_activated_cb(GtkTreeView *treeview, GtkTreePath *path, GtkTre
gtk_tree_model_get_value(store, &iter, COLUMN_DUMP_DIR, &d_dir);
const char *dirname = g_value_get_string(&d_dir);
- report_problem_in_dir(dirname, LIBREPORT_ANALYZE | LIBREPORT_NOWAIT | LIBREPORT_GETPID);
+
+ report_problem_in_dir(dirname,
+ LIBREPORT_ANALYZE | LIBREPORT_NOWAIT | LIBREPORT_GETPID);
}
}
}
diff --git a/src/plugins/abrt-dump-oops.c b/src/plugins/abrt-dump-oops.c
index 76c699d..f258da9 100644
--- a/src/plugins/abrt-dump-oops.c
+++ b/src/plugins/abrt-dump-oops.c
@@ -480,16 +480,6 @@ static unsigned save_oops_to_dump_dir(GList *oops_list, unsigned oops_cnt)
VERB1 log("Saving %u oopses as dump dirs", idx >= countdown ? countdown-1 : idx);
- char *tainted_str = NULL;
- FILE *tainted_fp = fopen("/proc/sys/kernel/tainted", "r");
- if (tainted_fp)
- {
- tainted_str = xmalloc_fgetline(tainted_fp);
- fclose(tainted_fp);
- }
- else
- perror_msg("Can't open '%s'", "/proc/sys/kernel/tainted");
-
char *cmdline_str = NULL;
FILE *cmdline_fp = fopen("/proc/cmdline", "r");
if (cmdline_fp)
@@ -536,35 +526,44 @@ static unsigned save_oops_to_dump_dir(GList *oops_list, unsigned oops_cnt)
if (cmdline_str)
dd_save_text(dd, FILENAME_CMDLINE, cmdline_str);
dd_save_text(dd, FILENAME_BACKTRACE, second_line);
-// TODO: add "Kernel oops: " prefix, so that all oopses have recognizable FILENAME_REASON?
-// kernel oops 1st line may look quite puzzling otherwise...
- strchrnul(second_line, '\n')[0] = '\0';
- dd_save_text(dd, FILENAME_REASON, second_line);
- if (tainted_str && tainted_str[0] != '0')
+ char *tainted_short = kernel_tainted_short(second_line);
+ if (tainted_short)
{
- unsigned long tainted = xatoi_positive(tainted_str);
- char *tainted_short = kernel_tainted_short(tainted);
- GList *tainted_long = kernel_tainted_long(tainted);
-
- struct strbuf *tnt_long = strbuf_new();
- for (GList *li = tainted_long; li; li = li->next)
- strbuf_append_strf(tnt_long, "%s\n", (char*) li->data);
-
- dd_save_text(dd, FILENAME_TAINTED, tainted_str);
+ VERB1 log("Kernel is tainted '%s'", tainted_short);
dd_save_text(dd, FILENAME_TAINTED_SHORT, tainted_short);
- dd_save_text(dd, FILENAME_TAINTED_LONG, tnt_long->buf);
- strbuf_free(tnt_long);
- list_free_with_free(tainted_long);
+ char *reason = xasprintf("Your kernel is tainted by flags '%s'. "
+ "Kernel maintainers are not interesting about "
+ "tainted kernel, because the trace not showing "
+ "the root problem."
+ , tainted_short);
+ dd_save_text(dd, FILENAME_NOT_REPORTABLE, reason);
+ free(reason);
}
+// TODO: add "Kernel oops: " prefix, so that all oopses have recognizable FILENAME_REASON?
+// kernel oops 1st line may look quite puzzling otherwise...
+ strchrnul(second_line, '\n')[0] = '\0';
+ dd_save_text(dd, FILENAME_REASON, second_line);
+/*
+ GList *tainted_long = kernel_tainted_long(tainted);
+
+ struct strbuf *tnt_long = strbuf_new();
+ for (GList *li = tainted_long; li; li = li->next)
+ strbuf_append_strf(tnt_long, "%s\n", (char*) li->data);
+
+ dd_save_text(dd, FILENAME_TAINTED, tainted_str);
+ dd_save_text(dd, FILENAME_TAINTED_SHORT, tainted_short);
+ dd_save_text(dd, FILENAME_TAINTED_LONG, tnt_long->buf);
+ strbuf_free(tnt_long);
+ list_free_with_free(tainted_long);
+*/
dd_close(dd);
}
else
errors++;
}
- free(tainted_str);
free(cmdline_str);
return errors;
@@ -718,7 +717,15 @@ int main(int argc, char **argv)
{
int i = 0;
while (i < oops_cnt)
- printf("\nVersion: %s", (char*)g_list_nth_data(oops_list, i++));
+ {
+ char *kernel_bt = (char*)g_list_nth_data(oops_list, i++);
+ char *tainted_short = kernel_tainted_short(kernel_bt);
+ if (tainted_short)
+ log("Kernel is tainted '%s'", tainted_short);
+
+ free(tainted_short);
+ printf("\nVersion: %s", kernel_bt);
+ }
}
if ((opts & OPT_d) || (opts & OPT_D))
{
--
1.7.7.rc0.70.g82660
12 years, 7 months
Test
by Vratislav Podzimek
I am just testing if my mails can make it through.
--
Vratislav Podzimek
12 years, 7 months
[PATCH-abrt] call ensure_writable_dir from a-a-install-debuginfo.in
by Nikola Pajkovsky
Signed-off-by: Nikola Pajkovsky <npajkovs(a)redhat.com>
---
src/daemon/abrtd.c | 19 -------------------
src/plugins/abrt-action-install-debuginfo.in | 11 +++++++++++
2 files changed, 11 insertions(+), 19 deletions(-)
diff --git a/src/daemon/abrtd.c b/src/daemon/abrtd.c
index b6b06ee..bac8edf 100644
--- a/src/daemon/abrtd.c
+++ b/src/daemon/abrtd.c
@@ -575,25 +575,6 @@ static void start_syslog_logging()
putenv((char*)"ABRT_SYSLOG=1");
}
-static void ensure_writable_dir(const char *dir, mode_t mode, const char *user)
-{
- struct stat sb;
-
- if (mkdir(dir, mode) != 0 && errno != EEXIST)
- perror_msg_and_die("Can't create '%s'", dir);
- if (stat(dir, &sb) != 0 || !S_ISDIR(sb.st_mode))
- error_msg_and_die("'%s' is not a directory", dir);
-
- struct passwd *pw = getpwnam(user);
- if (!pw)
- perror_msg_and_die("Can't find user '%s'", user);
-
- if ((sb.st_uid != pw->pw_uid || sb.st_gid != pw->pw_gid) && chown(dir, pw->pw_uid, pw->pw_gid) != 0)
- perror_msg_and_die("Can't set owner %u:%u on '%s'", (unsigned int)pw->pw_uid, (unsigned int)pw->pw_gid, dir);
- if ((sb.st_mode & 07777) != mode && chmod(dir, mode) != 0)
- perror_msg_and_die("Can't set mode %o on '%s'", mode, dir);
-}
-
static void sanitize_dump_dir_rights()
{
/* We can't allow everyone to create dumps: otherwise users can flood
diff --git a/src/plugins/abrt-action-install-debuginfo.in b/src/plugins/abrt-action-install-debuginfo.in
index 3e8a1c5..0ba844d 100644
--- a/src/plugins/abrt-action-install-debuginfo.in
+++ b/src/plugins/abrt-action-install-debuginfo.in
@@ -15,6 +15,7 @@ import reportclient
from subprocess import Popen, PIPE
from yum import _, YumBase
from yum.callbacks import DownloadBaseCallback
+from ctypes import *
# everything was ok
RETURN_OK = 0
@@ -511,6 +512,16 @@ if __name__ == "__main__":
if not b_ids:
exit(RETURN_FAILURE)
+ # We can't allow everyone to create dumps: otherwise users can flood
+ # us with thousands of bogus or malicious dumps
+ # 07000 bits are setuid, setgit, and sticky, and they must be unset
+ # 00777 bits are usual "rwxrwxrwx" access rights
+
+ libreport = CDLL("libreport.so") # doctest: +LINUX
+ ensure_writable_dir = libreport.abrt_ensure_writable_dir
+ ensure_writable_dir(c_char_p(cachedirs[0]), 0755, "abrt")
+
+
# Delete oldest/biggest files from cachedir.
# (Note that we need to do it before we check for missing debuginfos)
#
--
1.7.7.rc0.70.g82660
12 years, 7 months
[PATCH-libreport] move ensure_writable_dir from libabrt
by Nikola Pajkovsky
Right now, libabrt depends on libreport and it's not possible to call any
funtions from python written in libabrt.
Signed-off-by: Nikola Pajkovsky <npajkovs(a)redhat.com>
---
src/include/internal_libreport.h | 3 ++
src/lib/Makefile.am | 3 +-
src/lib/sanitize.c | 40 ++++++++++++++++++++++++++++++++++++++
3 files changed, 45 insertions(+), 1 deletions(-)
create mode 100644 src/lib/sanitize.c
diff --git a/src/include/internal_libreport.h b/src/include/internal_libreport.h
index afaf911..e1e0e30 100644
--- a/src/include/internal_libreport.h
+++ b/src/include/internal_libreport.h
@@ -707,6 +707,9 @@ unsigned parse_opts(int argc, char **argv, const struct options *opt,
#define show_usage_and_die libreport_show_usage_and_die
void show_usage_and_die(const char *usage, const struct options *opt) NORETURN;
+/* libabrt depends on libreport! break that chain and move this func back to abrt */
+#define ensure_writable_dir abrt_ensure_writable_dir
+void ensure_writable_dir(const char *dir, mode_t mode, const char *user);
#ifdef __cplusplus
}
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index e914f8a..1b30a20 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -46,7 +46,8 @@ libreport_la_SOURCES = \
event_config.c \
kernel-tainted.c \
report.c \
- client.c
+ client.c \
+ sanitize.c
libreport_la_CPPFLAGS = \
-Wall -Wwrite-strings -Werror \
-I$(srcdir)/../include \
diff --git a/src/lib/sanitize.c b/src/lib/sanitize.c
new file mode 100644
index 0000000..e8fd083
--- /dev/null
+++ b/src/lib/sanitize.c
@@ -0,0 +1,40 @@
+/*
+ Copyright (C) 2011 RedHat inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "internal_libreport.h"
+
+void ensure_writable_dir(const char *dir, mode_t mode, const char *user)
+{
+ struct stat sb;
+
+ if (mkdir(dir, mode) != 0 && errno != EEXIST)
+ perror_msg_and_die("Can't create '%s'", dir);
+ if (stat(dir, &sb) != 0 || !S_ISDIR(sb.st_mode))
+ error_msg_and_die("'%s' is not a directory", dir);
+
+ struct passwd *pw = getpwnam(user);
+ if (!pw)
+ perror_msg_and_die("Can't find user '%s'", user);
+
+ if ((sb.st_uid != pw->pw_uid || sb.st_gid != pw->pw_gid)
+ && chown(dir, pw->pw_uid, pw->pw_gid) != 0)
+ perror_msg_and_die("Can't set owner %u:%u on '%s'",
+ (unsigned int)pw->pw_uid, (unsigned int)pw->pw_gid, dir);
+ if ((sb.st_mode & 07777) != mode && chmod(dir, mode) != 0)
+ perror_msg_and_die("Can't set mode %o on '%s'", mode, dir);
+}
--
1.7.7.rc0.70.g82660
12 years, 7 months