Here are patches that implement collect events (#309). They add additional step after analysis and before reporting phase (both in gui and cli) where user can select collect_* events that can gather additional information from user's system.
Smolt data and .xsession-errors collection have been rewritten as such events and included are also two events that attach vim's configuration files when the editor crashes.
I'll be grateful for any comments.
Martin Milata (7): wizard: add new pages for the collect events wizard: collect events - GUI state updating wizard: collect events - next page selection wizard: collect events - run selected events report-cli: ugly hack to allow code reuse report-cli: add getopt switches for collect action report-cli: add support for collect events
src/cli/cli-report.c | 93 +++++++++++++++- src/cli/cli-report.h | 1 + src/cli/cli.c | 34 ++++-- src/gui-wizard-gtk/main.c | 3 + src/gui-wizard-gtk/wizard.c | 227 ++++++++++++++++++++++++++++----------- src/gui-wizard-gtk/wizard.glade | 140 +++++++++++++++++++++++- src/gui-wizard-gtk/wizard.h | 1 + 7 files changed, 414 insertions(+), 85 deletions(-)
--- src/gui-wizard-gtk/wizard.c | 38 +++++++---- src/gui-wizard-gtk/wizard.glade | 140 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 159 insertions(+), 19 deletions(-)
diff --git a/src/gui-wizard-gtk/wizard.c b/src/gui-wizard-gtk/wizard.c index aba044e..63cc6c6 100644 --- a/src/gui-wizard-gtk/wizard.c +++ b/src/gui-wizard-gtk/wizard.c @@ -96,19 +96,25 @@ static PangoFontDescription *monospace_font;
/* THE PAGE FLOW - * page_5: user comments - * page_1: analyze action selection - * page_2: analyze progress - * page_3: reporter selection - * page_4: backtrace editor - * page_6: summary - * page_7: reporting progress + * page_0: introduction/summary + * page_1: user comments + * page_2: analyze action selection + * page_3: analyze progress + * page_4: file collect selection + * page_5: collect progress + * page_6: reporter selection + * page_7: backtrace editor + * page_8: summary + * page_9: reporting progress + * page_10: finished */ enum { PAGENO_SUMMARY, PAGENO_EDIT_COMMENT, PAGENO_ANALYZE_SELECTOR, PAGENO_ANALYZE_PROGRESS, + PAGENO_COLLECT_SELECTOR, + PAGENO_COLLECT_PROGRESS, PAGENO_REPORTER_SELECTOR, PAGENO_EDIT_BACKTRACE, PAGENO_REVIEW_DATA, @@ -126,12 +132,14 @@ static const gchar PAGE_SUMMARY[] = "page_0"; static const gchar PAGE_EDIT_COMMENT[] = "page_1"; static const gchar PAGE_ANALYZE_SELECTOR[] = "page_2"; static const gchar PAGE_ANALYZE_PROGRESS[] = "page_3"; -static const gchar PAGE_REPORTER_SELECTOR[] = "page_4_report"; -static const gchar PAGE_EDIT_BACKTRACE[] = "page_5"; -static const gchar PAGE_REVIEW_DATA[] = "page_6_report"; -static const gchar PAGE_REPORT_PROGRESS[] = "page_7_report"; -static const gchar PAGE_REPORT_DONE[] = "page_8_report"; -static const gchar PAGE_NOT_SHOWN[] = "page_9_report"; +static const gchar PAGE_COLLECT_SELECTOR[] = "page_4"; +static const gchar PAGE_COLLECT_PROGRESS[] = "page_5"; +static const gchar PAGE_REPORTER_SELECTOR[] = "page_6_report"; +static const gchar PAGE_EDIT_BACKTRACE[] = "page_7"; +static const gchar PAGE_REVIEW_DATA[] = "page_8_report"; +static const gchar PAGE_REPORT_PROGRESS[] = "page_9_report"; +static const gchar PAGE_REPORT_DONE[] = "page_10_report"; +static const gchar PAGE_NOT_SHOWN[] = "page_11_report";
static const gchar *const page_names[] = { @@ -139,6 +147,8 @@ static const gchar *const page_names[] = PAGE_EDIT_COMMENT, PAGE_ANALYZE_SELECTOR, PAGE_ANALYZE_PROGRESS, + PAGE_COLLECT_SELECTOR, + PAGE_COLLECT_PROGRESS, PAGE_REPORTER_SELECTOR, PAGE_EDIT_BACKTRACE, PAGE_REVIEW_DATA, @@ -174,6 +184,8 @@ static page_obj_t pages[] = { PAGE_EDIT_COMMENT,"Provide additional information", GTK_ASSISTANT_PAGE_CONTENT }, { PAGE_ANALYZE_SELECTOR , "Select analyzer" , GTK_ASSISTANT_PAGE_CONFIRM }, { PAGE_ANALYZE_PROGRESS , "Analyzing" , GTK_ASSISTANT_PAGE_INTRO }, + { PAGE_COLLECT_SELECTOR , "Select collector" , GTK_ASSISTANT_PAGE_CONFIRM }, + { PAGE_COLLECT_PROGRESS , "Collecting" , GTK_ASSISTANT_PAGE_INTRO }, /* Some reporters don't need backtrace, we can skip bt page for them. * Therefore we want to know reporters _before_ we go to bt page */ diff --git a/src/gui-wizard-gtk/wizard.glade b/src/gui-wizard-gtk/wizard.glade index aeca16c..c57b13d 100644 --- a/src/gui-wizard-gtk/wizard.glade +++ b/src/gui-wizard-gtk/wizard.glade @@ -294,10 +294,138 @@ </object> </child> </object> + <object class="GtkWindow" id="window10"> + <property name="can_focus">False</property> + <child> + <object class="GtkVBox" id="page_4"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="border_width">10</property> + <property name="spacing">3</property> + <child> + <object class="GtkLabel" id="lbl_page7"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Select additional files to attach to the report:</property> + <property name="use_markup">True</property> + <property name="justify">fill</property> + <property name="wrap">True</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkVBox" id="vb_collectors"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <child> + <placeholder/> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkHBox" id="hbox4"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <child> + <object class="GtkButton" id="button_cfg3"> + <property name="label" translatable="yes">Configure _Events</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="use_action_appearance">False</property> + <property name="use_underline">True</property> + <property name="image_position">right</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkAlignment" id="alignment5"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <child> + <placeholder/> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">2</property> + </packing> + </child> + </object> + </child> + </object> + <object class="GtkWindow" id="window11"> + <property name="can_focus">False</property> + <child> + <object class="GtkVBox" id="page_5"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="border_width">10</property> + <property name="spacing">3</property> + <child> + <object class="GtkLabel" id="lbl_collect_log"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Collecting did not start yet</property> + <property name="use_markup">True</property> + <property name="wrap">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkScrolledWindow" id="scrolledwindow7"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="shadow_type">GTK_SHADOW_OUT</property> + <child> + <object class="GtkTextView" id="tv_collect_log"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="editable">False</property> + <property name="accepts_tab">False</property> + </object> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + </child> + </object> <object class="GtkWindow" id="window4"> <property name="can_focus">False</property> <child> - <object class="GtkVBox" id="page_4_report"> + <object class="GtkVBox" id="page_6_report"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="border_width">10</property> @@ -380,7 +508,7 @@ <property name="can_focus">False</property> <property name="tooltip_text" translatable="yes">Use this button to generate more informative backtrace after you installed additional debug packages</property> <child> - <object class="GtkVBox" id="page_5"> + <object class="GtkVBox" id="page_7"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="border_width">10</property> @@ -562,7 +690,7 @@ <object class="GtkWindow" id="window6"> <property name="can_focus">False</property> <child> - <object class="GtkVBox" id="page_6_report"> + <object class="GtkVBox" id="page_8_report"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="border_width">10</property> @@ -721,7 +849,7 @@ <object class="GtkWindow" id="window7"> <property name="can_focus">False</property> <child> - <object class="GtkVBox" id="page_7_report"> + <object class="GtkVBox" id="page_9_report"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="border_width">10</property> @@ -767,7 +895,7 @@ <object class="GtkWindow" id="window8"> <property name="can_focus">False</property> <child> - <object class="GtkVBox" id="page_8_report"> + <object class="GtkVBox" id="page_10_report"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="border_width">10</property> @@ -811,7 +939,7 @@ <object class="GtkWindow" id="window9"> <property name="can_focus">False</property> <child> - <object class="GtkVBox" id="page_9_report"> + <object class="GtkVBox" id="page_11_report"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="border_width">10</property>
--- src/gui-wizard-gtk/main.c | 3 + src/gui-wizard-gtk/wizard.c | 129 +++++++++++++++++++++++++++++++------------ src/gui-wizard-gtk/wizard.h | 1 + 3 files changed, 98 insertions(+), 35 deletions(-)
diff --git a/src/gui-wizard-gtk/main.c b/src/gui-wizard-gtk/main.c index dc31dd8..344d109 100644 --- a/src/gui-wizard-gtk/main.c +++ b/src/gui-wizard-gtk/main.c @@ -26,6 +26,7 @@ char *g_glade_file = NULL; char *g_dump_dir_name = NULL; char *g_analyze_events = NULL; +char *g_collect_events = NULL; char *g_report_events = NULL; int g_report_only = false; problem_data_t *g_cd; @@ -34,6 +35,7 @@ problem_data_t *g_cd; void reload_problem_data_from_dump_dir(void) { free(g_analyze_events); + free(g_collect_events); free(g_report_events);
struct dump_dir *dd = dd_opendir(g_dump_dir_name, DD_OPEN_READONLY); @@ -44,6 +46,7 @@ void reload_problem_data_from_dump_dir(void) add_to_problem_data_ext(new_cd, CD_DUMPDIR, g_dump_dir_name, (CD_FLAG_TXT | CD_FLAG_ISNOTEDITABLE));
g_analyze_events = list_possible_events(dd, NULL, "analyze"); + g_collect_events = list_possible_events(dd, NULL, "collect"); g_report_events = list_possible_events(dd, NULL, "report"); dd_close(dd);
diff --git a/src/gui-wizard-gtk/wizard.c b/src/gui-wizard-gtk/wizard.c index 63cc6c6..40de5ae 100644 --- a/src/gui-wizard-gtk/wizard.c +++ b/src/gui-wizard-gtk/wizard.c @@ -39,6 +39,7 @@ typedef struct event_gui_data_t static GtkAssistant *g_assistant;
static char *g_analyze_event_selected; +static unsigned g_collect_events_selected_count = 0; static char *g_reporter_events_selected; static unsigned g_black_event_count = 0;
@@ -48,6 +49,12 @@ static GList *g_list_analyzers; static GtkLabel *g_lbl_analyze_log; static GtkTextView *g_tv_analyze_log;
+static GtkBox *g_box_collectors; +/* List of event_gui_data's */ +static GList *g_list_collectors; +static GtkLabel *g_lbl_collect_log; +static GtkTextView *g_tv_collect_log; + static GtkBox *g_box_reporters; /* List of event_gui_data's */ static GList *g_list_reporters; @@ -641,6 +648,31 @@ static void report_tb_was_toggled(GtkButton *button_unused, gpointer user_data_u gtk_label_set_text(g_lbl_reporters, g_reporter_events_selected); }
+static void collect_tb_was_toggled(GtkButton *button_unused, gpointer user_data_unused) +{ + /* Update the number of selected collectors. */ + g_collect_events_selected_count = 0; + + GList *li = g_list_collectors; + for (; li; li = li->next) + { + event_gui_data_t *event_gui_data = li->data; + if (gtk_toggle_button_get_active(event_gui_data->toggle_button) == TRUE) + { + g_collect_events_selected_count++; + + GHashTable *errors = validate_event(event_gui_data->event_name); + if (errors != NULL) + { + g_hash_table_unref(errors); + show_event_opt_error_dialog(event_gui_data->event_name); + } + } + } + + /* The page is complete even if no checkbox is checked. */ +} + /* event_name contains "EVENT1\nEVENT2\nEVENT3\n". * Add new {radio/check}buttons to GtkBox for each EVENTn (type depends on bool radio). * Remember them in GList **p_event_list (list of event_gui_data_t's). @@ -833,6 +865,55 @@ static void append_item_to_ls_details(gpointer name, gpointer value, gpointer da } }
+/* Update collector/reporter checkboxes according to events parameter. + * Checkboxes are created in box specified by the second argument and their + * data stored in events_gui_data list. Parameter func is the callback function + * passed to the checkboxes. + */ +static void update_event_checkboxes(GList **events_gui_data, + GtkBox *box, + char *events, + GCallback func) +{ + /* Remember names of selected events */ + GList *old_events = NULL; + GList *li = *events_gui_data; + for (; li; li = li->next) + { + event_gui_data_t *event_gui_data = li->data; + if (gtk_toggle_button_get_active(event_gui_data->toggle_button) == TRUE) + { + /* order isn't important. prepend is faster */ + old_events = g_list_prepend(old_events, xstrdup(event_gui_data->event_name)); + } + } + /* Delete old checkboxes and create new ones */ + add_event_buttons(box, events_gui_data, + events, /*callback:*/ func, + /*radio:*/ false + ); + /* Re-select new events which were selected before we deleted them */ + GList *li_new = *events_gui_data; + for (; li_new; li_new = li_new->next) + { + event_gui_data_t *new_gui_data = li_new->data; + GList *li_old = old_events; + for (; li_old; li_old = li_old->next) + { + if (strcmp(new_gui_data->event_name, li_old->data) == 0) + { + gtk_toggle_button_set_active(new_gui_data->toggle_button, true); + break; + } + } + } + list_free_with_free(old_events); + + /* Update readiness state of event selector page + * and eventually the "list of reporters" label */ + ((void (*)(GtkButton*, gpointer*))func)(NULL, NULL); +} + void update_gui_state_from_problem_data(void) { gtk_window_set_title(GTK_WINDOW(g_assistant), g_dump_dir_name); @@ -865,42 +946,12 @@ void update_gui_state_from_problem_data(void) VERB2 log("g_analyze_event_selected='%s'", g_analyze_event_selected);
/* Update reporter checkboxes */ - /* Remember names of selected reporters */ - GList *old_reporters = NULL; - GList *li = g_list_reporters; - for (; li; li = li->next) - { - event_gui_data_t *event_gui_data = li->data; - if (gtk_toggle_button_get_active(event_gui_data->toggle_button) == TRUE) - { - /* order isn't important. prepend is faster */ - old_reporters = g_list_prepend(old_reporters, xstrdup(event_gui_data->event_name)); - } - } - /* Delete old checkboxes and create new ones */ - add_event_buttons(g_box_reporters, &g_list_reporters, - g_report_events, /*callback:*/ G_CALLBACK(report_tb_was_toggled), - /*radio:*/ false - ); - /* Re-select new reporters which were selected before we deleted them */ - GList *li_new = g_list_reporters; - for (; li_new; li_new = li_new->next) - { - event_gui_data_t *new_gui_data = li_new->data; - GList *li_old = old_reporters; - for (; li_old; li_old = li_old->next) - { - if (strcmp(new_gui_data->event_name, li_old->data) == 0) - { - gtk_toggle_button_set_active(new_gui_data->toggle_button, true); - break; - } - } - } - list_free_with_free(old_reporters); + update_event_checkboxes(&g_list_reporters, g_box_reporters, g_report_events, + G_CALLBACK(report_tb_was_toggled));
- /* Update readiness state of reporter selector page and "list of reporters" label */ - report_tb_was_toggled(NULL, NULL); + /* Update collector checkboxes in a similar way */ + update_event_checkboxes(&g_list_collectors, g_box_collectors, g_collect_events, + G_CALLBACK(collect_tb_was_toggled));
/* We can't just do gtk_widget_show_all once in main: * We created new widgets (buttons). Need to make them visible. @@ -2117,6 +2168,9 @@ static void add_pages() g_box_analyzers = GTK_BOX( gtk_builder_get_object(builder, "vb_analyzers")); g_lbl_analyze_log = GTK_LABEL( gtk_builder_get_object(builder, "lbl_analyze_log")); g_tv_analyze_log = GTK_TEXT_VIEW( gtk_builder_get_object(builder, "tv_analyze_log")); + g_box_collectors = GTK_BOX( gtk_builder_get_object(builder, "vb_collectors")); + g_lbl_collect_log = GTK_LABEL( gtk_builder_get_object(builder, "lbl_collect_log")); + g_tv_collect_log = GTK_TEXT_VIEW( gtk_builder_get_object(builder, "tv_collect_log")); g_box_reporters = GTK_BOX( gtk_builder_get_object(builder, "vb_reporters")); g_lbl_report_log = GTK_LABEL( gtk_builder_get_object(builder, "lbl_report_log")); g_tv_report_log = GTK_TEXT_VIEW( gtk_builder_get_object(builder, "tv_report_log")); @@ -2158,6 +2212,11 @@ static void add_pages() if (config_btn) g_signal_connect(G_OBJECT(config_btn), "clicked", G_CALLBACK(on_show_event_list_cb), NULL);
+ /* Configure btn on select collectors page */ + config_btn = GTK_WIDGET(gtk_builder_get_object(builder, "button_cfg3")); + if (config_btn) + g_signal_connect(G_OBJECT(config_btn), "clicked", G_CALLBACK(on_show_event_list_cb), NULL); + /* Add "Close" button */ GtkWidget *w; w = gtk_button_new_from_stock(GTK_STOCK_CLOSE); diff --git a/src/gui-wizard-gtk/wizard.h b/src/gui-wizard-gtk/wizard.h index 2e1767c..9533280 100644 --- a/src/gui-wizard-gtk/wizard.h +++ b/src/gui-wizard-gtk/wizard.h @@ -29,6 +29,7 @@ void show_error_as_msgbox(const char *msg); extern char *g_glade_file; extern char *g_dump_dir_name; extern char *g_analyze_events; +extern char *g_collect_events; extern char *g_report_events; extern problem_data_t *g_cd; extern int g_report_only;
--- src/gui-wizard-gtk/wizard.c | 32 +++++++++++++++++--------------- 1 files changed, 17 insertions(+), 15 deletions(-)
diff --git a/src/gui-wizard-gtk/wizard.c b/src/gui-wizard-gtk/wizard.c index 40de5ae..5270812 100644 --- a/src/gui-wizard-gtk/wizard.c +++ b/src/gui-wizard-gtk/wizard.c @@ -789,7 +789,7 @@ static event_gui_data_t *add_event_buttons(GtkBox *box,
if (radio) { - const char *msg_proceed_to_reporting = _("Go to reporting step"); + const char *msg_proceed_to_reporting = _("Go to next step"); GtkWidget *button = radio ? gtk_radio_button_new_with_label_from_widget( (first_button ? GTK_RADIO_BUTTON(first_button->toggle_button) : NULL), @@ -1831,8 +1831,6 @@ static gint select_next_page_no(gint current_page_no, gpointer data) return current_page_no; }
- gint prev_page_no = current_page_no; - again: current_page_no++;
@@ -1854,7 +1852,7 @@ static gint select_next_page_no(gint current_page_no, gpointer data) if (!g_analyze_events[0] || g_black_event_count == 0) { /* skip analyze selector page and analyze log page */ - current_page_no = PAGENO_REPORTER_SELECTOR-1; + current_page_no = PAGENO_COLLECT_SELECTOR-1; goto again; } break; @@ -1866,20 +1864,24 @@ static gint select_next_page_no(gint current_page_no, gpointer data) goto again; /* skip this page */ break;
- case PAGENO_REPORTER_SELECTOR: - VERB2 log("%s: REPORTER_SELECTOR: g_black_event_count:%d", - __func__, g_black_event_count); - /* if we _did_ run an event (didn't skip it) - * and still have analyzers which didn't run - */ - if (prev_page_no == PAGENO_ANALYZE_PROGRESS - && g_black_event_count != 0 - ) { - /* Go back to analyzer selectors */ - current_page_no = PAGENO_ANALYZE_SELECTOR-1; + case PAGENO_COLLECT_SELECTOR: + /* skip collection if there are no applicable events */ + if (!g_collect_events[0]) + { + current_page_no = PAGENO_REPORTER_SELECTOR-1; goto again; } break; + + case PAGENO_COLLECT_PROGRESS: + /* skip progress page if no events were chosen */ + if (g_collect_events_selected_count == 0) + { + current_page_no = PAGENO_REPORTER_SELECTOR-1; + goto again; + } + break; + case PAGENO_NOT_SHOWN: /* No! this would SEGV (infinitely recurse into select_next_page_no) */ /*gtk_assistant_commit(g_assistant);*/
--- src/gui-wizard-gtk/wizard.c | 28 ++++++++++++++++++++++++++++ 1 files changed, 28 insertions(+), 0 deletions(-)
diff --git a/src/gui-wizard-gtk/wizard.c b/src/gui-wizard-gtk/wizard.c index 5270812..0fc8a30 100644 --- a/src/gui-wizard-gtk/wizard.c +++ b/src/gui-wizard-gtk/wizard.c @@ -1656,6 +1656,34 @@ static void next_page(GtkAssistant *assistant, gpointer user_data) ); } } + + /* Run 'collect' events. */ + if (added_pages[page_no]->name == PAGE_COLLECT_SELECTOR) + { + GList *collectors = NULL; + GList *li = g_list_collectors; + for (; li; li = li->next) + { + event_gui_data_t *event_gui_data = li->data; + if (gtk_toggle_button_get_active(event_gui_data->toggle_button) == TRUE) + { + collectors = g_list_append(collectors, event_gui_data->event_name); + } + } + if (collectors) + { + char *first_event_name = collectors->data; + collectors = g_list_remove(collectors, collectors->data); + start_event_run(first_event_name, + collectors, + pages[PAGENO_COLLECT_PROGRESS].page_widget, + g_tv_collect_log, + g_lbl_collect_log, + _("Collecting..."), + _("Collecting finished with exit code %d") + ); + } + } }
static void on_show_event_list_cb(GtkWidget *button, gpointer user_data)
The function run_events() is general enough to run arbitrary list of events, but it prints some reporting-specific string. This chage makes the function accept part of these strings as an argument. --- src/cli/cli-report.c | 15 ++++++++++----- 1 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/src/cli/cli-report.c b/src/cli/cli-report.c index f203fad..689fc4e 100644 --- a/src/cli/cli-report.c +++ b/src/cli/cli-report.c @@ -520,7 +520,7 @@ static char *do_log_and_save_line(char *log_line, void *param) l_state->last_line = log_line; return NULL; } -static int run_events(const char *dump_dir_name, GList *events) +static int run_events(const char *dump_dir_name, GList *events, const char *event_type) { int error_cnt = 0; GList *env_list = NULL; @@ -547,11 +547,16 @@ static int run_events(const char *dump_dir_name, GList *events) } if (r == 0) { - printf("%s: %s\n", event, (l_state.last_line ? : "Reporting succeeded")); + printf("%s: ", event); + if (l_state.last_line) + printf("%s\n", l_state.last_line); + else + printf("%s succeeded\n", event_type); } else { - error_msg("Reporting via '%s' was not successful%s%s", + error_msg("%s via '%s' was not successful%s%s", + event_type, event, l_state.last_line ? ": " : "", l_state.last_line ? l_state.last_line : "" @@ -745,7 +750,7 @@ int report(const char *dump_dir_name, int flags) if (flags & CLI_REPORT_BATCH) { puts(_("Reporting...")); - errors += run_events(dump_dir_name, report_events); + errors += run_events(dump_dir_name, report_events, "Reporting"); plugins += g_list_length(report_events); } else @@ -804,7 +809,7 @@ int report(const char *dump_dir_name, int flags) */ GList *cur_event = NULL; cur_event = g_list_append(cur_event, reporter_name); - errors += run_events(dump_dir_name, cur_event); + errors += run_events(dump_dir_name, cur_event, "Reporting"); g_list_free(cur_event);
plugins++;
--- src/cli/cli.c | 25 ++++++++++++++----------- 1 files changed, 14 insertions(+), 11 deletions(-)
diff --git a/src/cli/cli.c b/src/cli/cli.c index 7fc150d..d209dc6 100644 --- a/src/cli/cli.c +++ b/src/cli/cli.c @@ -48,22 +48,24 @@ int main(int argc, char** argv) "\b [-vsp] -L[PREFIX] [DUMP_DIR]\n" " or: \b [-vsp] -e EVENT DUMP_DIR\n" " or: \b [-vsp] -a[y] DUMP_DIR\n" + " or: \b [-vsp] -c[y] DUMP_DIR\n" " or: \b [-vsp] -r[y|o|d] DUMP_DIR\n" ); enum { OPT_list_events = 1 << 0, OPT_run_event = 1 << 1, OPT_analyze = 1 << 2, - OPT_report = 1 << 3, - OPT_version = 1 << 4, - OPT_delete = 1 << 5, - OPTMASK_op = OPT_list_events|OPT_run_event|OPT_analyze|OPT_report|OPT_version, - OPTMASK_need_arg = OPT_run_event|OPT_analyze|OPT_report, - OPT_y = 1 << 6, - OPT_o = 1 << 7, - OPT_v = 1 << 8, - OPT_s = 1 << 9, - OPT_p = 1 << 10, + OPT_collect = 1 << 3, + OPT_report = 1 << 4, + OPT_version = 1 << 5, + OPT_delete = 1 << 6, + OPTMASK_op = OPT_list_events|OPT_run_event|OPT_analyze|OPT_collect|OPT_report|OPT_version, + OPTMASK_need_arg = OPT_run_event|OPT_analyze|OPT_collect|OPT_report, + OPT_y = 1 << 7, + OPT_o = 1 << 8, + OPT_v = 1 << 9, + OPT_s = 1 << 10, + OPT_p = 1 << 11, }; /* Keep enum above and order of options below in sync! */ struct options program_options[] = { @@ -71,7 +73,8 @@ int main(int argc, char** argv) OPT_OPTSTRING('L', NULL , &pfx, "PREFIX", _("List possible events [which start with PREFIX]")), OPT_STRING( 'e', NULL , &event_name, "EVENT", _("Run EVENT on DUMP_DIR")), OPT_BOOL( 'a', "analyze", NULL, _("Run analyze event(s) on DUMP_DIR")), - OPT_BOOL( 'r', "report" , NULL, _("Analyze and report problem data in DUMP_DIR")), + OPT_BOOL( 'c', "collect", NULL, _("Run collect event(s) on DUMP_DIR")), + OPT_BOOL( 'r', "report" , NULL, _("Analyze, collect and report problem data in DUMP_DIR")), OPT_BOOL( 'V', "version", NULL, _("Display version and exit")), OPT_BOOL( 'd', "delete" , NULL, _("Remove DUMP_DIR after reporting")), OPT_BOOL( 'y', "always" , NULL, _("Noninteractive: don't ask questions, assume 'yes'")),
Collect events are run both in report mode (-r) and in standalone collect mode (-c). --- src/cli/cli-report.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/cli/cli-report.h | 1 + src/cli/cli.c | 9 ++++++ 3 files changed, 88 insertions(+), 0 deletions(-)
diff --git a/src/cli/cli-report.c b/src/cli/cli-report.c index 689fc4e..9fdf05d 100644 --- a/src/cli/cli-report.c +++ b/src/cli/cli-report.c @@ -664,6 +664,75 @@ GList *str_to_glist(char *str, int delim) return list; }
+/* When this function returns the dump dir passed as dd is closed */ +int collect(const char *dump_dir_name, struct dump_dir *dd, int batch) +{ + int errors = 0; + char wanted_collectors[255]; + GList *selected_events = NULL; + + char *collect_events_as_lines = list_possible_events(dd, NULL, "collect"); + dd_close(dd); + + /* return if there are no collect events */ + if (!collect_events_as_lines) + return 0; + + if (!*collect_events_as_lines) + { + free(collect_events_as_lines); + return 0; + } + + GList *list_collect_events = str_to_glist(collect_events_as_lines, '\n'); + free(collect_events_as_lines); + + if (!batch) + { + GList *li; + unsigned i; + + puts(_("What additional information would you like to collect?")); + /* Print list of collectors and ask the user which should be used. */ + for (li = list_collect_events, i = 1; li; li = li->next, i++) + { + char *collector_name = (char *) li->data; + event_config_t *config = get_event_config(collector_name); + + if (!config) + VERB1 log("No configuration file found for collector '%s'", collector_name); + + printf(" %d) %s\n", i, (config && config->screen_name) ? config->screen_name : collector_name); + } + + read_from_stdin(_("Select collector(s): "), wanted_collectors, sizeof(wanted_collectors)); + + for (li = list_collect_events, i = 1; li; li = li->next, i++) + { + char *collector_name = (char *) li->data; + + /* Was this collector requested? */ + if (!is_number_in_string(i, wanted_collectors)) + continue; + + selected_events = g_list_append(selected_events, collector_name); + } + } + else + { + /* run all collectors in noninteractive mode */ + selected_events = list_collect_events; + } + + errors = run_events(dump_dir_name, selected_events, "Collection"); + + list_free_with_free(list_collect_events); + if (!batch) + g_list_free(selected_events); + + return errors; +} + /* Report the crash */ int report(const char *dump_dir_name, int flags) { @@ -696,6 +765,15 @@ int report(const char *dump_dir_name, int flags) dd = dd_opendir(dump_dir_name, /*flags:*/ 0); if (!dd) return -1; + + int collect_errors = collect(dump_dir_name, dd, flags & CLI_REPORT_BATCH); + if (collect_errors > 0) + printf(_("There were %d errors while collecting additional data\n"), collect_errors); + + /* Load dd from (possibly updated by collect) dump dir */ + dd = dd_opendir(dump_dir_name, /*flags:*/ 0); + if (!dd) + return -1; }
char *report_events_as_lines = list_possible_events(dd, NULL, "report"); diff --git a/src/cli/cli-report.h b/src/cli/cli-report.h index d3d8d70..a2138ce 100644 --- a/src/cli/cli-report.h +++ b/src/cli/cli-report.h @@ -32,6 +32,7 @@ enum { CLI_REPORT_ONLY = 1 << 1, }; int report(const char *dump_dir_name, int flags); +int collect(const char *dump_dir_name, struct dump_dir *dd, int batch);
#ifdef __cplusplus } diff --git a/src/cli/cli.c b/src/cli/cli.c index d209dc6..ac71ab9 100644 --- a/src/cli/cli.c +++ b/src/cli/cli.c @@ -176,6 +176,15 @@ int main(int argc, char** argv) free(analyze_events_as_lines); break; } + case OPT_collect: + { + struct dump_dir *dd = dd_opendir(dump_dir_name, DD_OPEN_READONLY); + if (!dd) + return 1; + + exitcode = collect(dump_dir_name, dd, always); + break; + } case OPT_report: { struct dump_dir *dd = dd_opendir(dump_dir_name, DD_OPEN_READONLY);
Martin Milata mmilata@redhat.com writes:
Collect events are run both in report mode (-r) and in standalone collect mode (-c).
src/cli/cli-report.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/cli/cli-report.h | 1 + src/cli/cli.c | 9 ++++++ 3 files changed, 88 insertions(+), 0 deletions(-)
diff --git a/src/cli/cli-report.c b/src/cli/cli-report.c index 689fc4e..9fdf05d 100644 --- a/src/cli/cli-report.c +++ b/src/cli/cli-report.c @@ -664,6 +664,75 @@ GList *str_to_glist(char *str, int delim) return list; }
+/* When this function returns the dump dir passed as dd is closed */ +int collect(const char *dump_dir_name, struct dump_dir *dd, int batch)
Is there a reason why this function takes both dump_dir_name and already-opened dd?
It seems that dump dir can be opened and closed inside of this function, similarly to the report function.
+{
- int errors = 0;
- char wanted_collectors[255];
- GList *selected_events = NULL;
- char *collect_events_as_lines = list_possible_events(dd, NULL, "collect");
- dd_close(dd);
On Thu, Jul 28, 2011 at 15:11:36 +0200, Karel Klíč wrote:
Martin Milata mmilata@redhat.com writes:
Collect events are run both in report mode (-r) and in standalone collect mode (-c).
src/cli/cli-report.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/cli/cli-report.h | 1 + src/cli/cli.c | 9 ++++++ 3 files changed, 88 insertions(+), 0 deletions(-)
diff --git a/src/cli/cli-report.c b/src/cli/cli-report.c index 689fc4e..9fdf05d 100644 --- a/src/cli/cli-report.c +++ b/src/cli/cli-report.c @@ -664,6 +664,75 @@ GList *str_to_glist(char *str, int delim) return list; }
+/* When this function returns the dump dir passed as dd is closed */ +int collect(const char *dump_dir_name, struct dump_dir *dd, int batch)
Is there a reason why this function takes both dump_dir_name and already-opened dd?
It seems that dump dir can be opened and closed inside of this function, similarly to the report function.
I can't think of any reason except that I wasn't thinking when I wrote it. Corrected patch should be in a reply to this message, thanks for pointing this out.
+{
- int errors = 0;
- char wanted_collectors[255];
- GList *selected_events = NULL;
- char *collect_events_as_lines = list_possible_events(dd, NULL, "collect");
- dd_close(dd);
Crash-catcher mailing list Crash-catcher@lists.fedorahosted.org https://fedorahosted.org/mailman/listinfo/crash-catcher
Collect events are run both in report mode (-r) and in standalone collect mode (-c). --- src/cli/cli-report.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++- src/cli/cli-report.h | 1 + src/cli/cli.c | 10 ++++++ 3 files changed, 97 insertions(+), 1 deletions(-)
diff --git a/src/cli/cli-report.c b/src/cli/cli-report.c index 689fc4e..1998fad 100644 --- a/src/cli/cli-report.c +++ b/src/cli/cli-report.c @@ -664,6 +664,84 @@ GList *str_to_glist(char *str, int delim) return list; }
+/* Runs collect_* events if there are any. If batch is nonzero, no questions + * are asked and positive answers are assumed, i.e. all events are ran. + * returns: 0: success + * -1: failed to open dumpdir + * >0: number of errors encountered when running the events + */ +int collect(const char *dump_dir_name, int batch) +{ + int errors = 0; + char wanted_collectors[255]; + GList *selected_events = NULL; + + struct dump_dir *dd = dd_opendir(dump_dir_name, DD_OPEN_READONLY); + if (!dd) + return -1; + + char *collect_events_as_lines = list_possible_events(dd, NULL, "collect"); + dd_close(dd); + + /* return if there are no collect events */ + if (!collect_events_as_lines) + return 0; + + if (!*collect_events_as_lines) + { + free(collect_events_as_lines); + return 0; + } + + GList *list_collect_events = str_to_glist(collect_events_as_lines, '\n'); + free(collect_events_as_lines); + + if (!batch) + { + GList *li; + unsigned i; + + puts(_("What additional information would you like to collect?")); + /* Print list of collectors and ask the user which should be used. */ + for (li = list_collect_events, i = 1; li; li = li->next, i++) + { + char *collector_name = (char *) li->data; + event_config_t *config = get_event_config(collector_name); + + if (!config) + VERB1 log("No configuration file found for collector '%s'", collector_name); + + printf(" %d) %s\n", i, (config && config->screen_name) ? config->screen_name : collector_name); + } + + read_from_stdin(_("Select collector(s): "), wanted_collectors, sizeof(wanted_collectors)); + + for (li = list_collect_events, i = 1; li; li = li->next, i++) + { + char *collector_name = (char *) li->data; + + /* Was this collector requested? */ + if (!is_number_in_string(i, wanted_collectors)) + continue; + + selected_events = g_list_append(selected_events, collector_name); + } + } + else + { + /* run all collectors in noninteractive mode */ + selected_events = list_collect_events; + } + + errors = run_events(dump_dir_name, selected_events, "Collection"); + + list_free_with_free(list_collect_events); + if (!batch) + g_list_free(selected_events); + + return errors; +} + /* Report the crash */ int report(const char *dump_dir_name, int flags) { @@ -692,7 +770,14 @@ int report(const char *dump_dir_name, int flags) return 1; }
- /* Load problem_data from (possibly updated by analyze) dump dir */ + /* Run collect events if there are any */ + int collect_res = collect(dump_dir_name, flags & CLI_REPORT_BATCH); + if (collect_res == -1) + return -1; + else if (collect_res > 0) + printf(_("There were %d errors while collecting additional data\n"), collect_res); + + /* Load dd from (possibly updated by collect) dump dir */ dd = dd_opendir(dump_dir_name, /*flags:*/ 0); if (!dd) return -1; diff --git a/src/cli/cli-report.h b/src/cli/cli-report.h index d3d8d70..77af8d8 100644 --- a/src/cli/cli-report.h +++ b/src/cli/cli-report.h @@ -32,6 +32,7 @@ enum { CLI_REPORT_ONLY = 1 << 1, }; int report(const char *dump_dir_name, int flags); +int collect(const char *dump_dir_name, int batch);
#ifdef __cplusplus } diff --git a/src/cli/cli.c b/src/cli/cli.c index d209dc6..a8d843a 100644 --- a/src/cli/cli.c +++ b/src/cli/cli.c @@ -176,6 +176,16 @@ int main(int argc, char** argv) free(analyze_events_as_lines); break; } + case OPT_collect: + { + exitcode = collect(dump_dir_name, always); + + /* Be consistent and return 1 when opening dd failed */ + if (exitcode == -1) + return 1; + + break; + } case OPT_report: { struct dump_dir *dd = dd_opendir(dump_dir_name, DD_OPEN_READONLY);
--- abrt.spec.in | 2 +- src/plugins/Makefile.am | 4 ++-- src/plugins/analyze_xsession_errors.xml.in | 10 ---------- src/plugins/ccpp_event.conf | 2 +- src/plugins/collect_xsession_errors.xml.in | 10 ++++++++++ 5 files changed, 14 insertions(+), 14 deletions(-) delete mode 100644 src/plugins/analyze_xsession_errors.xml.in create mode 100644 src/plugins/collect_xsession_errors.xml.in
diff --git a/abrt.spec.in b/abrt.spec.in index 342c626..e208213 100644 --- a/abrt.spec.in +++ b/abrt.spec.in @@ -403,7 +403,7 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || : %{_sbindir}/abrt-install-ccpp-hook %{_sysconfdir}/libreport/events.d/ccpp_event.conf %{_sysconfdir}/libreport/events/analyze_LocalGDB.xml -%{_sysconfdir}/libreport/events/analyze_xsession_errors.xml +%{_sysconfdir}/libreport/events/collect_xsession_errors.xml %{_sysconfdir}/libreport/events/analyze_Smolt.xml %{_mandir}/man*/abrt-action-trim-files.* %{_mandir}/man*/abrt-action-generate-backtrace.* diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am index 6ff72c3..84447dc 100644 --- a/src/plugins/Makefile.am +++ b/src/plugins/Makefile.am @@ -27,7 +27,7 @@ eventsdir = $(EVENTS_DIR) dist_events_DATA = \ analyze_LocalGDB.xml \ analyze_RetraceServer.xml \ - analyze_xsession_errors.xml \ + collect_xsession_errors.xml \ analyze_Smolt.xml
@INTLTOOL_XML_RULE@ @@ -76,7 +76,7 @@ EXTRA_DIST = \ $(PYTHON_FILES) \ $(man1_MANS) \ analyze_Smolt.xml.in \ - analyze_xsession_errors.xml.in \ + collect_xsession_errors.xml.in \ analyze_LocalGDB.xml.in \ analyze_RetraceServer.xml.in
diff --git a/src/plugins/analyze_xsession_errors.xml.in b/src/plugins/analyze_xsession_errors.xml.in deleted file mode 100644 index 1e3d738..0000000 --- a/src/plugins/analyze_xsession_errors.xml.in +++ /dev/null @@ -1,10 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<event> - <name>Collect .xsession-errors</name> - <_description>Save relevant lines from ~/.xsession-errors file</_description> - <_long-description> - Scans through ~/.xsession-errors file and saves those lines which contain executable's name. - The result is saved as 'xsession_errors' element. - </_long-description> - <creates-items>xsession_errors</creates-items> -</event> diff --git a/src/plugins/ccpp_event.conf b/src/plugins/ccpp_event.conf index e058072..d1a6f8e 100644 --- a/src/plugins/ccpp_event.conf +++ b/src/plugins/ccpp_event.conf @@ -16,7 +16,7 @@ EVENT=post-create analyzer=CCpp fi )
-EVENT=analyze_xsession_errors analyzer=CCpp dso_list~=.*/libX11.* +EVENT=collect_xsession_errors analyzer=CCpp dso_list~=.*/libX11.* test -f ~/.xsession-errors || { echo "No ~/.xsession-errors"; exit 1; } test -r ~/.xsession-errors || { echo "Can't read ~/.xsession-errors"; exit 1; } executable=`cat executable` && diff --git a/src/plugins/collect_xsession_errors.xml.in b/src/plugins/collect_xsession_errors.xml.in new file mode 100644 index 0000000..1e3d738 --- /dev/null +++ b/src/plugins/collect_xsession_errors.xml.in @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<event> + <name>Collect .xsession-errors</name> + <_description>Save relevant lines from ~/.xsession-errors file</_description> + <_long-description> + Scans through ~/.xsession-errors file and saves those lines which contain executable's name. + The result is saved as 'xsession_errors' element. + </_long-description> + <creates-items>xsession_errors</creates-items> +</event>
--- abrt.spec.in | 2 +- src/plugins/Makefile.am | 4 ++-- src/plugins/analyze_Smolt.xml.in | 9 --------- src/plugins/collect_Smolt.xml.in | 9 +++++++++ src/plugins/smolt_event.conf | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) delete mode 100644 src/plugins/analyze_Smolt.xml.in create mode 100644 src/plugins/collect_Smolt.xml.in
diff --git a/abrt.spec.in b/abrt.spec.in index e208213..5f1eec5 100644 --- a/abrt.spec.in +++ b/abrt.spec.in @@ -404,7 +404,7 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || : %{_sysconfdir}/libreport/events.d/ccpp_event.conf %{_sysconfdir}/libreport/events/analyze_LocalGDB.xml %{_sysconfdir}/libreport/events/collect_xsession_errors.xml -%{_sysconfdir}/libreport/events/analyze_Smolt.xml +%{_sysconfdir}/libreport/events/collect_Smolt.xml %{_mandir}/man*/abrt-action-trim-files.* %{_mandir}/man*/abrt-action-generate-backtrace.* %{_mandir}/man*/abrt-action-analyze-backtrace.* diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am index 84447dc..42e6c42 100644 --- a/src/plugins/Makefile.am +++ b/src/plugins/Makefile.am @@ -28,7 +28,7 @@ dist_events_DATA = \ analyze_LocalGDB.xml \ analyze_RetraceServer.xml \ collect_xsession_errors.xml \ - analyze_Smolt.xml + collect_Smolt.xml
@INTLTOOL_XML_RULE@
@@ -75,7 +75,7 @@ EXTRA_DIST = \ $(MAN_TXT) \ $(PYTHON_FILES) \ $(man1_MANS) \ - analyze_Smolt.xml.in \ + collect_Smolt.xml.in \ collect_xsession_errors.xml.in \ analyze_LocalGDB.xml.in \ analyze_RetraceServer.xml.in diff --git a/src/plugins/analyze_Smolt.xml.in b/src/plugins/analyze_Smolt.xml.in deleted file mode 100644 index 05112c3..0000000 --- a/src/plugins/analyze_Smolt.xml.in +++ /dev/null @@ -1,9 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<event> - <name>Collect Smolt profile</name> - <_description>Save your computer's hardware profile information</_description> - <_long-description> - Runs smoltSendProfile -p and seves its output as 'smolt_data' element. - </_long-description> - <creates-items>smolt_data</creates-items> -</event> diff --git a/src/plugins/collect_Smolt.xml.in b/src/plugins/collect_Smolt.xml.in new file mode 100644 index 0000000..05112c3 --- /dev/null +++ b/src/plugins/collect_Smolt.xml.in @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<event> + <name>Collect Smolt profile</name> + <_description>Save your computer's hardware profile information</_description> + <_long-description> + Runs smoltSendProfile -p and seves its output as 'smolt_data' element. + </_long-description> + <creates-items>smolt_data</creates-items> +</event> diff --git a/src/plugins/smolt_event.conf b/src/plugins/smolt_event.conf index 831c55c..34e546d 100644 --- a/src/plugins/smolt_event.conf +++ b/src/plugins/smolt_event.conf @@ -11,7 +11,7 @@ # To be moved to smolt package, so that it is (de)installed # together with these packages.
-EVENT=analyze_Smolt +EVENT=collect_Smolt which skdump >/dev/null 2>&1 || exit 0 smoltSendProfile -p >smolt_data 2>&1 || exit $? echo 'Smolt profile successfully saved'
If the currently reported application is linked against libgconf, this event extracts application's configuration from GConf. --- abrt.spec.in | 2 ++ src/plugins/Makefile.am | 7 +++++-- src/plugins/collect_GConf.xml.in | 7 +++++++ src/plugins/gconf_event.conf | 12 ++++++++++++ 4 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 src/plugins/collect_GConf.xml.in create mode 100644 src/plugins/gconf_event.conf
diff --git a/abrt.spec.in b/abrt.spec.in index 5f1eec5..93286bd 100644 --- a/abrt.spec.in +++ b/abrt.spec.in @@ -402,9 +402,11 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || : %{_bindir}/abrt-action-list-dsos %{_sbindir}/abrt-install-ccpp-hook %{_sysconfdir}/libreport/events.d/ccpp_event.conf +%{_sysconfdir}/libreport/events.d/gconf_event.conf %{_sysconfdir}/libreport/events/analyze_LocalGDB.xml %{_sysconfdir}/libreport/events/collect_xsession_errors.xml %{_sysconfdir}/libreport/events/collect_Smolt.xml +%{_sysconfdir}/libreport/events/collect_GConf.xml %{_mandir}/man*/abrt-action-trim-files.* %{_mandir}/man*/abrt-action-generate-backtrace.* %{_mandir}/man*/abrt-action-analyze-backtrace.* diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am index 42e6c42..c887574 100644 --- a/src/plugins/Makefile.am +++ b/src/plugins/Makefile.am @@ -28,7 +28,8 @@ dist_events_DATA = \ analyze_LocalGDB.xml \ analyze_RetraceServer.xml \ collect_xsession_errors.xml \ - collect_Smolt.xml + collect_Smolt.xml \ + collect_GConf.xml
@INTLTOOL_XML_RULE@
@@ -40,7 +41,8 @@ dist_eventsconf_DATA = \ koops_event.conf \ python_event.conf \ smart_event.conf \ - smolt_event.conf + smolt_event.conf \ + gconf_event.conf
man_MANS = \ abrt-plugins.7 @@ -77,6 +79,7 @@ EXTRA_DIST = \ $(man1_MANS) \ collect_Smolt.xml.in \ collect_xsession_errors.xml.in \ + collect_GConf.xml.in \ analyze_LocalGDB.xml.in \ analyze_RetraceServer.xml.in
diff --git a/src/plugins/collect_GConf.xml.in b/src/plugins/collect_GConf.xml.in new file mode 100644 index 0000000..b30ec97 --- /dev/null +++ b/src/plugins/collect_GConf.xml.in @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<event> + <_name>Collect GConf configuration</_name> + <_description>Save configuration from application's GConf directory</_description> + <_long-description>Runs gconftool-2 --recursive-list /apps/executable and saves it as 'gconf_subtree' element.</_long-description> + <creates-items>gconf_subtree</creates-items> +</event> diff --git a/src/plugins/gconf_event.conf b/src/plugins/gconf_event.conf new file mode 100644 index 0000000..4bb7369 --- /dev/null +++ b/src/plugins/gconf_event.conf @@ -0,0 +1,12 @@ +EVENT=collect_GConf analyzer=CCpp dso_list~=.*/libgconf-2.* + # assumption: gconftool-2 is present because libgconf is + executable=`cat executable` && + gconfdir="/apps/${executable##*/}" && + { + gconftool-2 --dir-exists=$gconfdir || + { echo "GConf directory $gconfdir does not exist"; exit 1; } + } && + gconftool-2 --recursive-list $gconfdir >gconf_subtree && + echo "Element 'gconf_subtree' saved" + +
Added example events that attach vim config files whenever vim crashes. --- abrt.spec.in | 3 ++ src/plugins/Makefile.am | 9 +++++- src/plugins/collect_vimrc_system.xml.in | 7 +++++ src/plugins/collect_vimrc_user.xml.in | 7 +++++ src/plugins/vimrc_event.conf | 42 +++++++++++++++++++++++++++++++ 5 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 src/plugins/collect_vimrc_system.xml.in create mode 100644 src/plugins/collect_vimrc_user.xml.in create mode 100644 src/plugins/vimrc_event.conf
diff --git a/abrt.spec.in b/abrt.spec.in index 93286bd..fadeb86 100644 --- a/abrt.spec.in +++ b/abrt.spec.in @@ -403,10 +403,13 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || : %{_sbindir}/abrt-install-ccpp-hook %{_sysconfdir}/libreport/events.d/ccpp_event.conf %{_sysconfdir}/libreport/events.d/gconf_event.conf +%{_sysconfdir}/libreport/events.d/vimrc_event.conf %{_sysconfdir}/libreport/events/analyze_LocalGDB.xml %{_sysconfdir}/libreport/events/collect_xsession_errors.xml %{_sysconfdir}/libreport/events/collect_Smolt.xml %{_sysconfdir}/libreport/events/collect_GConf.xml +%{_sysconfdir}/libreport/events/collect_vimrc_user.xml +%{_sysconfdir}/libreport/events/collect_vimrc_system.xml %{_mandir}/man*/abrt-action-trim-files.* %{_mandir}/man*/abrt-action-generate-backtrace.* %{_mandir}/man*/abrt-action-analyze-backtrace.* diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am index c887574..95956a4 100644 --- a/src/plugins/Makefile.am +++ b/src/plugins/Makefile.am @@ -29,7 +29,9 @@ dist_events_DATA = \ analyze_RetraceServer.xml \ collect_xsession_errors.xml \ collect_Smolt.xml \ - collect_GConf.xml + collect_GConf.xml \ + collect_vimrc_user.xml \ + collect_vimrc_system.xml
@INTLTOOL_XML_RULE@
@@ -42,7 +44,8 @@ dist_eventsconf_DATA = \ python_event.conf \ smart_event.conf \ smolt_event.conf \ - gconf_event.conf + gconf_event.conf \ + vimrc_event.conf
man_MANS = \ abrt-plugins.7 @@ -80,6 +83,8 @@ EXTRA_DIST = \ collect_Smolt.xml.in \ collect_xsession_errors.xml.in \ collect_GConf.xml.in \ + collect_vimrc_user.xml.in \ + collect_vimrc_system.xml.in \ analyze_LocalGDB.xml.in \ analyze_RetraceServer.xml.in
diff --git a/src/plugins/collect_vimrc_system.xml.in b/src/plugins/collect_vimrc_system.xml.in new file mode 100644 index 0000000..486e5e0 --- /dev/null +++ b/src/plugins/collect_vimrc_system.xml.in @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<event> + <_name>Collect system-wide vim configuration files</_name> + <_description>Save /etc/vimrc and /etc/gvimrc</_description> + <_long-description>Checks if there are vimrc and gvimrc files in /etc and saves them as system_vimrc and system_gvimrc, respectively.</_long-description> + <creates-items>system_vimrc,system_gvimrc</creates-items> +</event> diff --git a/src/plugins/collect_vimrc_user.xml.in b/src/plugins/collect_vimrc_user.xml.in new file mode 100644 index 0000000..934df18 --- /dev/null +++ b/src/plugins/collect_vimrc_user.xml.in @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<event> + <_name>Collect yours vim configuration files</_name> + <_description>Save .vimrc and .gvimrc from your home directory</_description> + <_long-description>Checks if there are .vimrc and .gvimrc in your home directory and saves them as user_vimrc and user_gvimrc, respectively.</_long-description> + <creates-items>user_vimrc,user_gvimrc</creates-items> +</event> diff --git a/src/plugins/vimrc_event.conf b/src/plugins/vimrc_event.conf new file mode 100644 index 0000000..6487854 --- /dev/null +++ b/src/plugins/vimrc_event.conf @@ -0,0 +1,42 @@ +# Exemple events that allow the reporter to attach vim configuration files +# whenever vim crash is reported. + +EVENT=collect_vimrc_user component=vim + # there has to be a comment here, otherwise + # the next line is interpreted as a condition + vimrc=~/.vimrc + gvimrc=~/.gvimrc + saved=none + if [ -r $vimrc -a -f $vimrc ]; then + cp $vimrc user_vimrc || exit $? + saved="$saved, user_vimrc" + else + echo "File $vimrc not found" + fi + if [ -r $gvimrc -a -f $gvimrc ]; then + cp $gvimrc user_gvimrc || exit $? + saved="$saved, user_gvimrc" + else + echo "File $gvimrc not found" + fi + echo "Elements saved: ${saved#none, }" + +EVENT=collect_vimrc_system component=vim + # there has to be a comment here, otherwise + # the next line is interpreted as a condition + vimrc=/etc/vimrc + gvimrc=/etc/gvimrc + saved=none + if [ -r $vimrc -a -f $vimrc ]; then + cp $vimrc system_vimrc || exit $? + saved="$saved, system_vimrc" + else + echo "File $vimrc not found" + fi + if [ -r $gvimrc -a -f $gvimrc ]; then + cp $gvimrc system_gvimrc || exit $? + saved="$saved, system_gvimrc" + else + echo "File $gvimrc not found" + fi + echo "Elements saved: ${saved#none, }"
Martin Milata mmilata@redhat.com writes:
Here are patches that implement collect events (#309). They add additional step after analysis and before reporting phase (both in gui and cli) where user can select collect_* events that can gather additional information from user's system.
Smolt data and .xsession-errors collection have been rewritten as such events and included are also two events that attach vim's configuration files when the editor crashes.
I'll be grateful for any comments.
I have tested both the wizard and cli with Smolt collection: the changes work well and look good code-wise. I think we can apply it.
Not sure whether we want "stealing" to be added to the --collect option in report-cli. Currently it is not there, so users cannot run --collect on crashes in /var/spool.
On Fri, Jul 29, 2011 at 11:53:22 +0200, Karel Klíč wrote:
Martin Milata mmilata@redhat.com writes:
Here are patches that implement collect events (#309). They add additional step after analysis and before reporting phase (both in gui and cli) where user can select collect_* events that can gather additional information from user's system.
Smolt data and .xsession-errors collection have been rewritten as such events and included are also two events that attach vim's configuration files when the editor crashes.
I'll be grateful for any comments.
I have tested both the wizard and cli with Smolt collection: the changes work well and look good code-wise. I think we can apply it.
Not sure whether we want "stealing" to be added to the --collect option in report-cli. Currently it is not there, so users cannot run --collect on crashes in /var/spool.
I wanted --collect to behave similarly to --analyze, which does not steal the directory either. If there's a demand, I'll write a patch for that.
crash-catcher@lists.fedorahosted.org