[LIBREPORT PATCH] trac#707: add ASK_YES_NO_YESFOREVER message type to event communication protocol
by Jakub Filak
- a questions having this prefix have three posible answers:
yes / no / yes and don't ask me again
- the prefix must be followed by ' ' and a single word as key for
configuration, a question message follows the key
- somebody can be confused byt the logic but it was originally
implemented in report-gtk ("Don't ask me again" check box)
Signed-off-by: Jakub Filak <jfilak(a)redhat.com>
---
src/cli/cli.c | 19 +++++++++++----
src/gui-wizard-gtk/wizard.c | 8 +++++++
src/include/client.h | 11 +++++++++
src/include/run_event.h | 29 +++++++++++++++++++++++
src/lib/run_event.c | 57 +++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 120 insertions(+), 4 deletions(-)
diff --git a/src/cli/cli.c b/src/cli/cli.c
index c82a783..bb73f70 100644
--- a/src/cli/cli.c
+++ b/src/cli/cli.c
@@ -134,6 +134,11 @@ int main(int argc, char** argv)
/* Get settings */
load_event_config_data();
+ /* At least, needed by ASK_YES_NO_YESFOREVER event command requests.
+ * Removing of the following statemen will get the yes forever stuff not
+ * working. */
+ load_user_settings("report-cli");
+
/* Do the selected operation. */
int exitcode = 0;
switch (op)
@@ -182,7 +187,7 @@ int main(int argc, char** argv)
/* Be consistent and return 1 when opening dd failed */
if (exitcode == -1)
- return 1;
+ exitcode = 1;
break;
}
@@ -194,9 +199,13 @@ int main(int argc, char** argv)
(always ? CLI_REPORT_BATCH : 0));
if (exitcode == -1)
- error_msg_and_die("Crash '%s' not found", dump_dir_name);
-
- if (opts & OPT_delete)
+ { /* Be consistent and return 1 */
+ exitcode = 1;
+ /* Can't use error_msg_and_die() function because we want to
+ * store user's answers on yes/no/yes forever questions */
+ error_msg("Crash '%s' not found", dump_dir_name);
+ }
+ else if (opts & OPT_delete)
{
int r = delete_dump_dir_possibly_using_abrtd(dump_dir_name);
if (exitcode == 0)
@@ -207,5 +216,7 @@ int main(int argc, char** argv)
}
}
+ /* At least, needed by ASK_YES_NO_YESFOREVER event command requests. */
+ save_user_settings();
return exitcode;
}
diff --git a/src/gui-wizard-gtk/wizard.c b/src/gui-wizard-gtk/wizard.c
index 1a48a8d..c2a7a72 100644
--- a/src/gui-wizard-gtk/wizard.c
+++ b/src/gui-wizard-gtk/wizard.c
@@ -1649,6 +1649,13 @@ static int run_event_gtk_ask_yes_no(const char *msg, void *args)
return ret;
}
+static int run_event_gtk_ask_yes_no_yesforever(const char *msg, const char *key, void *args)
+{
+ const int ret = ask_yes_no_save_result(msg, key);
+ log_request_response_communication(msg, ret ? "YES" : "NO", (struct analyze_event_data *)args);
+ return ret;
+}
+
static char *run_event_gtk_ask_password(const char *msg, void *args)
{
return ask_helper(msg, args, true);
@@ -1802,6 +1809,7 @@ static void start_event_run(const char *event_name,
state->alert_callback = run_event_gtk_alert;
state->ask_callback = run_event_gtk_ask;
state->ask_yes_no_callback = run_event_gtk_ask_yes_no;
+ state->ask_yes_no_yesforever_callback = run_event_gtk_ask_yes_no_yesforever;
state->ask_password_callback = run_event_gtk_ask_password;
if (prepare_commands(state, g_dump_dir_name, event_name) == 0)
diff --git a/src/include/client.h b/src/include/client.h
index a714ba8..8d7218c 100644
--- a/src/include/client.h
+++ b/src/include/client.h
@@ -21,6 +21,17 @@
#define LIBREPORT_CLIENT_H_
#define REPORT_PREFIX_ASK_YES_NO "ASK_YES_NO "
+/* The REPORT_PREFIX_ASK_YES_NO_YESFOREVER prefix must be followed by a single
+ * word used as key. If the prefix is followed only by the key the
+ * REPORT_PREFIX_ASK_YES_NO implementation is used instead.
+ *
+ * Example:
+ * ASK_YES_NO_YESFOREVER ask_before_suicide Do you really want to kill yourself?
+ *
+ * Example of message handle as REPORT_PREFIX_ASK_YES_NO:
+ * ASK_YES_NO_YESFOREVER Continue?
+ */
+#define REPORT_PREFIX_ASK_YES_NO_YESFOREVER "ASK_YES_NO_YESFOREVER "
#define REPORT_PREFIX_ASK "ASK "
#define REPORT_PREFIX_ASK_PASSWORD "ASK_PASSWORD "
#define REPORT_PREFIX_ALERT "ALERT "
diff --git a/src/include/run_event.h b/src/include/run_event.h
index fdf3555..c5791f0 100644
--- a/src/include/run_event.h
+++ b/src/include/run_event.h
@@ -89,6 +89,21 @@ struct run_event_state {
int (*ask_yes_no_callback)(const char *msg, void *interaction_param);
/*
+ * Called when child command wants to know 'yes/no/yesforever' decision.
+ * The yes forever means that in next call the yes answer is returned
+ * immediately without asking. The yes forever answer is stored in
+ * configuration under a passed key.
+ *
+ * The default value is run_event_stdio_ask_yes_no_yesforever()
+ *
+ * @param msg An ask message produced by child command
+ * @param key An option name used as a key in configuration
+ * @param args An implementor args
+ * @return Return 0 if an answer is NO, otherwise return nonzero value.
+ */
+ int (*ask_yes_no_yesforever_callback)(const char *msg, const char *key, void *interaction_param);
+
+ /*
* Called when child wants to know a password.
*
* The default value is run_event_stdio_ask_password()
@@ -179,6 +194,20 @@ char *run_event_stdio_ask(const char *msg, void *param);
int run_event_stdio_ask_yes_no(const char *msg, void *param);
/*
+ * Prints the msg param on stdout and reads a response from stdin. To store the
+ * yes forever answer uses libreport's user settings API. Therefore if you want
+ * to get the yes forever stuff working you have to call load_user_setting()
+ * function before this function call and call save_user_settings() function
+ * after this function call.
+ *
+ * @param msg a printed message
+ * @param key a key under which the yes forever answer is stored
+ * @param param UNUSED
+ * @return 0 if user's answer is 'no', otherwise non 0 value
+ */
+int run_event_stdio_ask_yes_no_yesforever(const char *msg, const char *key, void *param);
+
+/*
* Prints the msg param on stdout and reads a response from stdin
*
* @param msg a printed message
diff --git a/src/lib/run_event.c b/src/lib/run_event.c
index 622833a..f04cb37 100644
--- a/src/lib/run_event.c
+++ b/src/lib/run_event.c
@@ -28,6 +28,7 @@ struct run_event_state *new_run_event_state()
state->alert_callback = run_event_stdio_alert;
state->ask_callback = run_event_stdio_ask;
state->ask_yes_no_callback = run_event_stdio_ask_yes_no;
+ state->ask_yes_no_yesforever_callback= run_event_stdio_ask_yes_no_yesforever;
state->ask_password_callback = run_event_stdio_ask_password;
state->command_output = strbuf_new();
@@ -478,6 +479,37 @@ int consume_event_command_output(struct run_event_state *state, const char *dump
{
state->alert_callback(msg + sizeof(REPORT_PREFIX_ALERT) - 1 , state->interaction_param);
}
+ /* wait for y/N/f response on the same line */
+ else if (prefixcmp(msg, REPORT_PREFIX_ASK_YES_NO_YESFOREVER) == 0)
+ {
+ /* example:
+ * ASK_YES_NO_YESFOREVER ask_before_suicide Do you really want to kill yourself?
+ */
+ char *key = msg + sizeof(REPORT_PREFIX_ASK_YES_NO_YESFOREVER) - 1;
+ char *key_end = strchr(key, ' ');
+
+ bool ans = false;
+
+ if (!key_end)
+ { /* example:
+ * ASK_YES_NO_YESFOREVER Continue?
+ *
+ * Print a wraning only and do not scary users with error messages.
+ */
+ log("Warning: invalid input format (missing option name), using simple ask yes/no");
+
+ /* can't simply use 'goto ask_yes_no' because of different lenght of prefixes */
+ ans = state->ask_yes_no_callback(key, state->interaction_param);
+ }
+ else
+ {
+ key_end[0] = '\0'; /* split 'key msg' to 'key' and 'msg' */
+ ans = state->ask_yes_no_yesforever_callback(key + strlen(key) + 1, key, state->interaction_param);
+ key_end[0] = ' '; /* restore original message, not sure if it is necessary */
+ }
+
+ response = xstrdup(ans ? "yes" : "no");
+ }
/* wait for y/N response on the same line */
else if (prefixcmp(msg, REPORT_PREFIX_ASK_YES_NO) == 0)
{
@@ -671,6 +703,31 @@ int run_event_stdio_ask_yes_no(const char *msg, void *param)
return buf[0] == 'y' && (buf[1] == '\n' || buf[1] == '\0');
}
+int run_event_stdio_ask_yes_no_yesforever(const char *msg, const char *key, void *param)
+{
+ const char *ask_result = get_user_setting(key);
+
+ if (ask_result && string_to_bool(ask_result) == false)
+ /* Do you want to be asked? -> No, I don't */
+ return 1;
+
+ printf("%s [%s/%s/%s] ", msg, _("y"), _("N"), _("f"));
+ fflush(stdout);
+ char buf[16];
+ if (!fgets(buf, sizeof(buf), stdin))
+ buf[0] = '\0';
+
+ char *endln = strchr(buf, '\n');
+ if (endln)
+ endln[0] = '\0';
+
+ /* Do you want to be asked for next time? */
+ /* 'f' means 'yes forever' and it means 'no, dont' ask me again' */
+ set_user_setting(key, strcmp(_("f"), buf) == 0 ? "no" : "yes");
+
+ return strcmp(_("f"), buf) == 0 || strcmp(_("y"), buf) == 0;
+}
+
char *run_event_stdio_ask_password(const char *msg, void *param)
{
const bool changed = set_echo(false);
--
1.7.11.4
11 years, 7 months
[PATCH] don't show the credential in logs rhbz#856960
by Jiri Moskovcak
---
src/plugins/reporter-upload.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/src/plugins/reporter-upload.c b/src/plugins/reporter-upload.c
index ecd82c7..1a2c395 100644
--- a/src/plugins/reporter-upload.c
+++ b/src/plugins/reporter-upload.c
@@ -56,7 +56,19 @@ static int send_file(const char *url, const char *filename)
return 1;
}
- log(_("Sending %s to %s"), filename, url);
+ /* we don't want to print the whole url as it may contain password
+ * rhbz#856960
+ * there can be '@' in the login or password so let's try to find the
+ * first '@' from the end
+ */
+ char *clean_url = strrchr(url, '@');
+ if (clean_url != NULL)
+ clean_url++;
+ else
+ clean_url = url;
+
+
+ log(_("Sending %s to %s"), filename, clean_url);
struct stat stbuf;
fstat(fileno(fp), &stbuf); /* never fails */
@@ -95,7 +107,7 @@ static int send_file(const char *url, const char *filename)
error_msg("Error while uploading: '%s'", curl_easy_strerror(result));
else
/* This ends up a "reporting status message" in abrtd */
- log(_("Successfully sent %s to %s"), filename, url);
+ log(_("Successfully sent %s to %s"), filename, clean_url);
curl_easy_cleanup(curl);
--
1.7.11.4
11 years, 7 months
[PATCH] build: silence error in configure.ac
by Nikola Pajkovsky
running ./autogen.sh generates errors on every library
/usr/share/automake-1.12/am/ltlibrary.am: archiver requires 'AM_PROG_AR' in 'configure.ac'
src/client-python/Makefile.am:7: while processing Libtool library '_reportclient.la'
Signed-off-by: Nikola Pajkovsky <npajkovs(a)redhat.com>
---
configure.ac | 1 +
1 file changed, 1 insertion(+)
diff --git a/configure.ac b/configure.ac
index dd50bcf..129d091 100644
--- a/configure.ac
+++ b/configure.ac
@@ -9,6 +9,7 @@ AM_INIT_AUTOMAKE([-Wall -Werror foreign])
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES])
# The 'yes' argument is undocumented but it is common knowledge that it works.
AM_SILENT_RULES([yes])
+AM_PROG_AR
AC_DISABLE_STATIC
AC_PROG_LIBTOOL
--
1.7.12
11 years, 7 months
[ABRT PATCH] trac#703: set uid to caller's uid in D-Bus NewProblem() method
by Jakub Filak
Signed-off-by: Jakub Filak <jfilak(a)redhat.com>
---
src/dbus/abrt-dbus.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/src/dbus/abrt-dbus.c b/src/dbus/abrt-dbus.c
index 4302b4f..9f3b2d9 100644
--- a/src/dbus/abrt-dbus.c
+++ b/src/dbus/abrt-dbus.c
@@ -362,7 +362,7 @@ static bool allowed_problem_dir(const char *dir_name)
return true;
}
-static char *handle_new_problem(GVariant *problem_info, char **error)
+static char *handle_new_problem(GVariant *problem_info, uid_t caller_uid, char **error)
{
problem_data_t *pd = problem_data_new();
@@ -374,6 +374,14 @@ static char *handle_new_problem(GVariant *problem_info, char **error)
problem_data_add_text_editable(pd, key, value);
}
+ char buf[sizeof(uid_t) * 3 + 2];
+ if (caller_uid != 0)
+ { /* set uid field to caller's uid if caller is not root */
+ VERB2 log("Adding UID %d to problem data", caller_uid);
+ snprintf(buf, sizeof(buf), "%d", caller_uid);
+ problem_data_add_text_noteditable(pd, FILENAME_UID, buf);
+ }
+
char *problem_id = problem_data_save(pd);
if (!problem_id)
{
@@ -419,7 +427,7 @@ static void handle_method_call(GDBusConnection *connection,
if (g_strcmp0(method_name, "NewProblem") == 0)
{
char *error = NULL;
- char *problem_id = handle_new_problem(g_variant_get_child_value(parameters, 0), &error);
+ char *problem_id = handle_new_problem(g_variant_get_child_value(parameters, 0), caller_uid, &error);
if (!problem_id)
{
g_dbus_method_invocation_return_dbus_error(invocation,
--
1.7.11.4
11 years, 7 months
[LIBREPORT PATCH] trac#705: create dump dir from problem data with appropriate uid and gid
by Jakub Filak
Signed-off-by: Jakub Filak <jfilak(a)redhat.com>
---
src/lib/create_dump_dir.c | 35 +++++++++++++++++++++++++++--------
1 file changed, 27 insertions(+), 8 deletions(-)
diff --git a/src/lib/create_dump_dir.c b/src/lib/create_dump_dir.c
index 1e923a2..675547d 100644
--- a/src/lib/create_dump_dir.c
+++ b/src/lib/create_dump_dir.c
@@ -18,13 +18,14 @@
*/
#include "internal_libreport.h"
+#include <errno.h>
#define NEW_PD_SUFFIX ".new"
-static struct dump_dir *try_dd_create(const char *base_dir_name, const char *dir_name)
+static struct dump_dir *try_dd_create(const char *base_dir_name, const char *dir_name, uid_t uid)
{
char *path = concat_path_file(base_dir_name, dir_name);
- struct dump_dir *dd = dd_create(path, (uid_t)-1L, 0640);
+ struct dump_dir *dd = dd_create(path, uid, 0640);
free(path);
return dd;
}
@@ -39,17 +40,35 @@ struct dump_dir *create_dump_dir_from_problem_data(problem_data_t *problem_data,
return NULL;
}
+ uid_t uid = (uid_t)-1L;
+ char *uid_str = problem_data_get_content_or_NULL(problem_data, FILENAME_UID);
+
+ if (uid_str)
+ {
+ char *endptr;
+ errno = 0;
+ long val = strtol(uid_str, &endptr, 10);
+
+ if (errno != 0 || endptr == uid_str || *endptr != '\0' || INT_MAX < val)
+ {
+ error_msg(_("uid value is not valid: '%s'"), uid_str);
+ return NULL;
+ }
+
+ uid = (uid_t)val;
+ }
+
char *problem_id = xasprintf("%s-%s-%lu"NEW_PD_SUFFIX, type, iso_date_string(NULL), (long)getpid());
- VERB2 log("Saving to %s/%s", base_dir_name, problem_id);
+ VERB2 log("Saving to %s/%s with uid %d", base_dir_name, problem_id, uid);
struct dump_dir *dd;
if (base_dir_name)
- dd = try_dd_create(base_dir_name, problem_id);
+ dd = try_dd_create(base_dir_name, problem_id, uid);
else
{
/* Try /var/run/abrt */
- dd = try_dd_create(LOCALSTATEDIR"/run/abrt", problem_id);
+ dd = try_dd_create(LOCALSTATEDIR"/run/abrt", problem_id, uid);
/* Try $HOME/tmp */
if (!dd)
{
@@ -58,14 +77,14 @@ struct dump_dir *create_dump_dir_from_problem_data(problem_data_t *problem_data,
{
home = concat_path_file(home, "tmp");
/*mkdir(home, 0777); - do we want this? */
- dd = try_dd_create(home, problem_id);
+ dd = try_dd_create(home, problem_id, uid);
free(home);
}
}
//TODO: try user's home dir obtained by getpwuid(getuid())?
/* Try /tmp */
if (!dd)
- dd = try_dd_create("/tmp", problem_id);
+ dd = try_dd_create("/tmp", problem_id, uid);
}
if (!dd) /* try_dd_create() already emitted the error message */
@@ -106,7 +125,7 @@ struct dump_dir *create_dump_dir_from_problem_data(problem_data_t *problem_data,
* reporting from anaconda where we can't read /etc/{system,redhat}-release
* and os_release is taken from anaconda
*/
- dd_create_basic_files(dd, (uid_t)-1L, NULL);
+ dd_create_basic_files(dd, uid, NULL);
problem_id[strlen(problem_id) - strlen(NEW_PD_SUFFIX)] = '\0';
char* new_path = concat_path_file(base_dir_name, problem_id);
--
1.7.11.4
11 years, 7 months
[PATCH] reporter-ureport: enable translations
by Michal Toman
---
src/plugins/ureport.c | 8 +++++++-
1 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/src/plugins/ureport.c b/src/plugins/ureport.c
index a0ffa08..685bbad 100644
--- a/src/plugins/ureport.c
+++ b/src/plugins/ureport.c
@@ -244,6 +244,12 @@ static bool perform_attach(struct ureport_server_config *config, const char *ure
int main(int argc, char **argv)
{
+ setlocale(LC_ALL, "");
+#if ENABLE_NLS
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+#endif
+
abrt_init(argv);
struct ureport_server_config config = {
@@ -375,7 +381,7 @@ int main(int argc, char **argv)
/* If a reported problem is not known then emit NEEDMORE */
if (strcmp("true", response->value) == 0)
{
- log("This problem has already been reported.");
+ log(_("This problem has already been reported."));
if (response->message)
log(response->message);
log("THANKYOU");
--
1.7.1
11 years, 7 months
[LIBREPORT PATCH] trac#701: disable 'No' button if user checks 'Don t ask me again' box
by Jakub Filak
Signed-off-by: Jakub Filak <jfilak(a)redhat.com>
---
src/gui-wizard-gtk/wizard.c | 27 +++++++++++++++++++--------
1 file changed, 19 insertions(+), 8 deletions(-)
diff --git a/src/gui-wizard-gtk/wizard.c b/src/gui-wizard-gtk/wizard.c
index e00cdaf..6a62446 100644
--- a/src/gui-wizard-gtk/wizard.c
+++ b/src/gui-wizard-gtk/wizard.c
@@ -320,14 +320,18 @@ static void update_window_title(void)
free(title);
}
+/*
+ * We don't allow users to remember 'No' answer therefore if 'Don't ask me again' box is
+ * checked we have to disable 'No' button
+ */
static void on_toggle_ask_yes_no_save_result_cb(GtkToggleButton *tb, gpointer user_data)
{
- set_user_setting(user_data, gtk_toggle_button_get_active(tb) ? "no" : "yes");
+ gtk_widget_set_sensitive(GTK_WIDGET(user_data), !gtk_toggle_button_get_active(tb));
}
/*
* Function shows a dialog with 'Yes/No' buttons and a check box allowing to
- * remeber the answer. The answer is stored in configuration file under
+ * remember the answer. The answer is stored in configuration file under
* 'option_name' key.
*/
static bool ask_yes_no_save_result(const char *message, const char *option_name)
@@ -335,15 +339,19 @@ static bool ask_yes_no_save_result(const char *message, const char *option_name)
const char *ask_result = get_user_setting(option_name);
if (ask_result && string_to_bool(ask_result) == false)
+ /* Do you want to be asked? -> No, I don't. Do whatever you want */
return true;
GtkWidget *dialog = gtk_message_dialog_new(GTK_WINDOW(g_wnd_assistant),
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_QUESTION,
- GTK_BUTTONS_YES_NO,
+ GTK_BUTTONS_NONE,
"%s", message);
- gint response = GTK_RESPONSE_CANCEL;
+ gtk_dialog_add_button(GTK_DIALOG(dialog), GTK_STOCK_YES, GTK_RESPONSE_YES);
+ GtkWidget *no_button = gtk_dialog_add_button(GTK_DIALOG(dialog), GTK_STOCK_NO, GTK_RESPONSE_NO);
+
+ gint response = GTK_RESPONSE_NO;
g_signal_connect(G_OBJECT(dialog), "response",
G_CALLBACK(save_dialog_response), &response);
@@ -351,14 +359,17 @@ static bool ask_yes_no_save_result(const char *message, const char *option_name)
gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
ask_yes_no_cb, TRUE, TRUE, 0);
g_signal_connect(ask_yes_no_cb, "toggled",
- G_CALLBACK(on_toggle_ask_yes_no_save_result_cb), (gpointer)option_name);
+ G_CALLBACK(on_toggle_ask_yes_no_save_result_cb), (gpointer)no_button);
- /* check it by default if it's shown for the first time */
- if (!ask_result)
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ask_yes_no_cb), TRUE);
+ /* Don't check the box by default. If the box is checked the 'No' button is disabled and
+ * we don't want to force users to click on 'Yes' button. */
gtk_widget_show(ask_yes_no_cb);
gtk_dialog_run(GTK_DIALOG(dialog));
+
+ /* the box is checked -> Don't ask me again and my response is always 'Yes' */
+ set_user_setting(option_name, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ask_yes_no_cb)) ? "no" : "yes");
+
gtk_widget_destroy(dialog);
return response == GTK_RESPONSE_YES;
--
1.7.11.4
11 years, 8 months
[LIBREPORT PATCH] rhbz#852165: warn if adding commands without any rule condition
by Jakub Filak
- an event command line lead by an empty line is run for every event
- this behaviour make some peopel confused thus we notify them from now
Signed-off-by: Jakub Filak <jfilak(a)redhat.com>
---
src/lib/run_event.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/src/lib/run_event.c b/src/lib/run_event.c
index bc04c5e..04cf1a1 100644
--- a/src/lib/run_event.c
+++ b/src/lib/run_event.c
@@ -126,17 +126,23 @@ static GList *load_rule_list(GList *rule_list,
return rule_list;
}
+ /* Used only for better warning message */
+ int line_counter = 0;
/* Read and remember rules */
char *next_line = xmalloc_fgetline(conffile);
while (next_line)
{
/* Read and concatenate all lines in a rule */
char *line = next_line;
+ ++line_counter;
+
while (1)
{
next_line = xmalloc_fgetline(conffile);
if (!next_line || !isblank(next_line[0]))
break;
+
+ ++line_counter;
char *old_line = line;
line = xasprintf("%s\n%s", line, next_line);
free(old_line);
@@ -207,6 +213,9 @@ static GList *load_rule_list(GList *rule_list,
p = skip_whitespace(end_word);
} /* end of word loop */
+ if (cur_rule->conditions == NULL)
+ log("%s:%d: warning: command without conditions -> this command will be executed for all events", conf_file_name, line_counter);
+
VERB1 log("Adding '%s'", p);
cur_rule->command = xstrdup(p);
--
1.7.11.4
11 years, 8 months
[PATCH] fix core backtrace generation when debuginfo is present
by Richard Marko
In case when package debuginfo is present, gdb will output only
function names but no offsets preventing core backtrace generation.
Setting non-existent debuginfo directory resolves this.
---
src/lib/hooklib.c | 29 +++++++++++++++--------
src/plugins/abrt-action-generate-core-backtrace.c | 2 +-
2 files changed, 20 insertions(+), 11 deletions(-)
diff --git a/src/lib/hooklib.c b/src/lib/hooklib.c
index 1b30a5b..ca799e0 100644
--- a/src/lib/hooklib.c
+++ b/src/lib/hooklib.c
@@ -249,17 +249,26 @@ char *get_backtrace(const char *dump_dir_name, unsigned timeout_sec, const char
// (https://bugzilla.redhat.com/show_bug.cgi?id=528668):
args[2] = (char*)"-ex";
struct strbuf *set_debug_file_directory = strbuf_new();
- strbuf_append_str(set_debug_file_directory, "set debug-file-directory /usr/lib/debug");
- const char *p = debuginfo_dirs;
- while (1)
+ if(debuginfo_dirs == NULL)
{
- while (*p == ':')
- p++;
- if (*p == '\0')
- break;
- const char *colon_or_nul = strchrnul(p, ':');
- strbuf_append_strf(set_debug_file_directory, ":%.*s/usr/lib/debug", (int)(colon_or_nul - p), p);
- p = colon_or_nul;
+ // set non-existent debug file directory to prevent resolving
+ // function names - we need offsets for core backtrace.
+ strbuf_append_str(set_debug_file_directory, "set debug-file-directory /");
+ }
+ else
+ {
+ strbuf_append_str(set_debug_file_directory, "set debug-file-directory /usr/lib/debug");
+ const char *p = debuginfo_dirs;
+ while (1)
+ {
+ while (*p == ':')
+ p++;
+ if (*p == '\0')
+ break;
+ const char *colon_or_nul = strchrnul(p, ':');
+ strbuf_append_strf(set_debug_file_directory, ":%.*s/usr/lib/debug", (int)(colon_or_nul - p), p);
+ p = colon_or_nul;
+ }
}
args[3] = strbuf_free_nobuf(set_debug_file_directory);
diff --git a/src/plugins/abrt-action-generate-core-backtrace.c b/src/plugins/abrt-action-generate-core-backtrace.c
index 5fccb89..9bd09a4 100644
--- a/src/plugins/abrt-action-generate-core-backtrace.c
+++ b/src/plugins/abrt-action-generate-core-backtrace.c
@@ -106,7 +106,7 @@ int main(int argc, char **argv)
if (strcmp(analyzer, "CCpp") == 0)
{
VERB1 log("Querying gdb for backtrace");
- char *gdb_out = get_backtrace(dump_dir_name, exec_timeout_sec, "");
+ char *gdb_out = get_backtrace(dump_dir_name, exec_timeout_sec, NULL);
if (gdb_out == NULL)
xfunc_die();
--
1.7.11.4
11 years, 8 months
[ABRT PATCH] rhbz#853641: run analyze_LocalGDB if analyze_RetraceServer fails
by Jakub Filak
Signed-off-by: Jakub Filak <jfilak(a)redhat.com>
---
abrt.spec.in | 1 +
src/plugins/Makefile.am | 6 ++++--
src/plugins/abrt-action-analyze-crash | 15 +++++++++++++++
src/plugins/ccpp_retrace_event.conf | 2 +-
4 files changed, 21 insertions(+), 3 deletions(-)
create mode 100755 src/plugins/abrt-action-analyze-crash
diff --git a/abrt.spec.in b/abrt.spec.in
index a1c00ba..93689f3 100644
--- a/abrt.spec.in
+++ b/abrt.spec.in
@@ -535,6 +535,7 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || :
%{_bindir}/abrt-action-generate-core-backtrace
%{_bindir}/abrt-action-analyze-backtrace
%{_bindir}/abrt-action-list-dsos
+%{_bindir}/abrt-action-analyze-crash
%{_bindir}/abrt-dedup-client
%{_sbindir}/abrt-install-ccpp-hook
%{_sysconfdir}/libreport/events.d/ccpp_event.conf
diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
index 675b1a7..15223ef 100644
--- a/src/plugins/Makefile.am
+++ b/src/plugins/Makefile.am
@@ -4,7 +4,8 @@ bin_SCRIPTS = \
abrt-action-install-debuginfo \
abrt-action-analyze-core \
abrt-action-analyze-vmcore \
- abrt-action-list-dsos
+ abrt-action-list-dsos \
+ abrt-action-analyze-crash
bin_PROGRAMS = \
abrt-watch-log \
@@ -73,7 +74,8 @@ EXTRA_DIST = \
analyze_VMcore.xml.in \
abrt-action-analyze-vmcore \
https-utils.h \
- post_report.xml.in
+ post_report.xml.in \
+ abrt-action-analyze-crash
abrt_watch_log_SOURCES = \
abrt-watch-log.c
diff --git a/src/plugins/abrt-action-analyze-crash b/src/plugins/abrt-action-analyze-crash
new file mode 100755
index 0000000..1acca6b
--- /dev/null
+++ b/src/plugins/abrt-action-analyze-crash
@@ -0,0 +1,15 @@
+#!/bin/sh
+# For event handlers
+# Tries to retrace over retrace server
+# If retrace server fails asks user for an approval to run retracing locally
+
+abrt-retrace-client batch --dir "$DUMP_DIR" --status-delay 10 || (
+ echo `gettext "ASK_YES_NO Do you want to perform local analysis?"` && read answ
+ if test x"$answ" == x"yes"; then
+ abrt-action-analyze-core --core=coredump -o build_ids &&
+ /usr/libexec/abrt-action-install-debuginfo-to-abrt-cache --size_mb=4096 &&
+ abrt-action-generate-backtrace
+ else
+ exit 1
+ fi
+)
diff --git a/src/plugins/ccpp_retrace_event.conf b/src/plugins/ccpp_retrace_event.conf
index 60e53d7..3cd5450 100644
--- a/src/plugins/ccpp_retrace_event.conf
+++ b/src/plugins/ccpp_retrace_event.conf
@@ -1,5 +1,5 @@
EVENT=analyze_RetraceServer analyzer=CCpp
- abrt-retrace-client batch --dir "$DUMP_DIR" --status-delay 10 &&
+ abrt-action-analyze-crash &&
abrt-action-analyze-backtrace &&
(
bug_id=$(reporter-bugzilla -h `cat duphash`) &&
--
1.7.11.4
11 years, 8 months