From c9120cdc51ce7aba5a19500bf24692144ac64983 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 10 May 2011 02:08:58 +0200 Subject: Do away with reanalyze events Now code determines whether analyze event can be skipped by looking at backtrace element in .xml file. Signed-off-by: Denys Vlasenko --- abrt.spec.in | 2 - doc/design | 4 +- src/gui-wizard-gtk/main.c | 3 - src/gui-wizard-gtk/wizard.c | 109 ++++++++++++++++++++++++------- src/gui-wizard-gtk/wizard.h | 1 - src/include/report/event_config.h | 1 + src/lib/event_config.c | 1 + src/lib/event_xml_parser.c | 12 +++- src/plugins/Makefile.am | 4 -- src/plugins/analyze_LocalGDB.xml.in | 1 + src/plugins/analyze_RetraceServer.xml.in | 1 + src/plugins/ccpp_events.conf | 17 +---- 12 files changed, 105 insertions(+), 51 deletions(-) diff --git a/abrt.spec.in b/abrt.spec.in index 2d826f99..ba24b288 100644 --- a/abrt.spec.in +++ b/abrt.spec.in @@ -540,9 +540,7 @@ fi %{_bindir}/abrt-action-list-dsos.py* %{_sysconfdir}/%{name}/events.d/ccpp_events.conf %{_sysconfdir}/%{name}/events/analyze_LocalGDB.xml -%{_sysconfdir}/%{name}/events/reanalyze_LocalGDB.xml %{_sysconfdir}/%{name}/events/analyze_RetraceServer.xml -%{_sysconfdir}/%{name}/events/reanalyze_RetraceServer.xml %{_mandir}/man*/abrt-action-trim-files.* %{_mandir}/man*/abrt-action-generate-backtrace.* %{_mandir}/man*/abrt-action-analyze-backtrace.* diff --git a/doc/design b/doc/design index 5da16cc2..05a96cdd 100644 --- a/doc/design +++ b/doc/design @@ -71,8 +71,8 @@ can trigger their initial ("post-create") processing themselves] Crashes conceptually go through "events" in their lives. Apart from "post-create" event decribed above, they may have -"analyze" event, "reanalyze" event, "report[_FOO]" events, -ans arbitrarily-named other events. +"analyze" event, "report[_FOO]" events, +and arbitrarily-named other events. abrt-handle-crashdump tool can be used to "run" an event on a directory, or to query list of possible events for a directory. /etc/abrt/abrt_event.conf file describes what should be done on each event. diff --git a/src/gui-wizard-gtk/main.c b/src/gui-wizard-gtk/main.c index d2041cb9..cd100ac8 100644 --- a/src/gui-wizard-gtk/main.c +++ b/src/gui-wizard-gtk/main.c @@ -28,7 +28,6 @@ char *g_glade_file = NULL; char *g_dump_dir_name = NULL; char *g_analyze_events = NULL; -char *g_reanalyze_events = NULL; char *g_report_events = NULL; int g_report_only = false; problem_data_t *g_cd; @@ -38,7 +37,6 @@ void reload_problem_data_from_dump_dir(void) { free_problem_data(g_cd); free(g_analyze_events); - free(g_reanalyze_events); free(g_report_events); struct dump_dir *dd = dd_opendir(g_dump_dir_name, DD_OPEN_READONLY); @@ -49,7 +47,6 @@ void reload_problem_data_from_dump_dir(void) add_to_problem_data_ext(g_cd, CD_DUMPDIR, g_dump_dir_name, CD_FLAG_TXT + CD_FLAG_ISNOTEDITABLE); g_analyze_events = list_possible_events(dd, NULL, "analyze"); - g_reanalyze_events = list_possible_events(dd, NULL, "reanalyze"); 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 2dc87018..39f90e37 100644 --- a/src/gui-wizard-gtk/wizard.c +++ b/src/gui-wizard-gtk/wizard.c @@ -36,6 +36,7 @@ typedef struct event_gui_data_t static GtkAssistant *g_assistant; static char *g_analyze_event_selected; +static unsigned g_black_event_count = 0; static GtkBox *g_box_analyzers; /* List of event_gui_data's */ @@ -403,11 +404,12 @@ static gint find_by_button(gconstpointer a, gconstpointer button) static void analyze_rb_was_toggled(GtkButton *button, gpointer user_data) { + free(g_analyze_event_selected); + g_analyze_event_selected = NULL; GList *found = g_list_find_custom(g_list_analyzers, button, find_by_button); if (found) { event_gui_data_t *evdata = found->data; - free(g_analyze_event_selected); g_analyze_event_selected = xstrdup(evdata->event_name); } } @@ -461,6 +463,9 @@ static event_gui_data_t *add_event_buttons(GtkBox *box, g_list_free(*p_event_list); *p_event_list = NULL; + if (radio) + g_black_event_count = 0; + bool have_activated_btn = false; event_gui_data_t *first_button = NULL; while (event_name[0]) @@ -475,7 +480,10 @@ static event_gui_data_t *add_event_buttons(GtkBox *box, event_screen_name++; else event_screen_name = event_name; +///vda const char *event_description = NULL; + char *tmp_description = NULL; + bool green_choice = false; event_config_t *cfg = get_event_config(event_name); if (cfg) { @@ -483,7 +491,17 @@ static event_gui_data_t *add_event_buttons(GtkBox *box, if (cfg->screen_name) event_screen_name = cfg->screen_name; event_description = cfg->description; + if (cfg->creates_elements) + { + if (get_problem_data_item_or_NULL(g_cd, cfg->creates_elements)) + { + green_choice = true; + event_description = tmp_description = xasprintf("(not needed, %s already exists)", cfg->creates_elements); + } + } } + if (radio && !green_choice) + g_black_event_count++; //VERB2 log("adding button '%s' to box %p", event_name, box); char *event_label = xasprintf("%s%s%s", @@ -491,6 +509,8 @@ static event_gui_data_t *add_event_buttons(GtkBox *box, (event_description ? " - " : ""), event_description ? event_description : "" ); + free(tmp_description); + GtkWidget *button = radio ? gtk_radio_button_new_with_label_from_widget( (first_button ? GTK_RADIO_BUTTON(first_button->toggle_button) : NULL), @@ -498,6 +518,20 @@ static event_gui_data_t *add_event_buttons(GtkBox *box, ) : gtk_check_button_new_with_label(event_label); free(event_label); + + if (green_choice) + { + //static const GdkColor red = { .red = 0xffff }; + //gtk_widget_modify_text(button, GTK_STATE_NORMAL, &red); + GtkWidget *child = gtk_bin_get_child(GTK_BIN(button)); + if (child) + { + static const GdkColor green = { .green = 0x7fff }; + gtk_widget_modify_fg(child, GTK_STATE_NORMAL, &green); + gtk_widget_modify_fg(child, GTK_STATE_ACTIVE, &green); + gtk_widget_modify_fg(child, GTK_STATE_PRELIGHT, &green); + } + } if (func) g_signal_connect(G_OBJECT(button), "toggled", func, NULL); if (cfg->long_descr) @@ -511,19 +545,48 @@ static event_gui_data_t *add_event_buttons(GtkBox *box, if (!first_button) first_button = event_gui_data; - if (prev_selected && strcmp(prev_selected, event_name) == 0) - { + if ((radio && !prev_selected && !have_activated_btn && !green_choice) + || (prev_selected && strcmp(prev_selected, event_name) == 0) + ) { + prev_selected = NULL; gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), true); have_activated_btn = true; - prev_selected = NULL; } *event_name_end = '\n'; event_name = event_name_end + 1; gtk_box_pack_start(box, button, /*expand*/ false, /*fill*/ false, /*padding*/ 0); + } + + if (radio) + { + GtkWidget *button = radio + ? gtk_radio_button_new_with_label_from_widget( + (first_button ? GTK_RADIO_BUTTON(first_button->toggle_button) : NULL), + "Don't do anything" + ) + : gtk_check_button_new_with_label("Don't do anything"); + if (func) + g_signal_connect(G_OBJECT(button), "toggled", func, NULL); + + event_gui_data_t *event_gui_data = new_event_gui_data_t(); + event_gui_data->event_name = xstrdup(""); + event_gui_data->toggle_button = GTK_TOGGLE_BUTTON(button); + *p_event_list = g_list_append(*p_event_list, event_gui_data); + + if (!first_button) + first_button = event_gui_data; + if (g_black_event_count == 0 && !have_activated_btn) + { + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), true); + have_activated_btn = true; + } + + gtk_box_pack_start(box, button, /*expand*/ false, /*fill*/ false, /*padding*/ 0); } + return (have_activated_btn ? NULL : first_button); } @@ -652,7 +715,7 @@ void update_gui_state_from_problem_data(void) */ gtk_widget_show_all(GTK_WIDGET(g_assistant)); - if (g_reanalyze_events[0]) + if (g_analyze_events[0]) gtk_widget_show(GTK_WIDGET(g_btn_refresh)); else gtk_widget_hide(GTK_WIDGET(g_btn_refresh)); @@ -1047,19 +1110,14 @@ static void on_bt_approve_toggle(GtkToggleButton *togglebutton, gpointer user_da static void on_btn_refresh_clicked(GtkButton *button) { - if (g_reanalyze_events[0]) - { - /* Save backtrace text if changed */ - save_text_from_text_view(g_tv_backtrace, FILENAME_BACKTRACE); + /* Save backtrace text if changed */ + save_text_from_text_view(g_tv_backtrace, FILENAME_BACKTRACE); - g_analyze_events = append_to_malloced_string(g_analyze_events, g_reanalyze_events); - g_reanalyze_events[0] = '\0'; - /* Refresh GUI so that we see new analyze+reanalyze buttons */ - update_gui_state_from_problem_data(); + /* Refresh GUI so that we see new analyze buttons */ + update_gui_state_from_problem_data(); - /* Change page to analyzer selector - let user play with them */ - gtk_assistant_set_current_page(g_assistant, PAGENO_ANALYZE_SELECTOR); - } + /* Change page to analyzer selector - let user play with them */ + gtk_assistant_set_current_page(g_assistant, PAGENO_ANALYZE_SELECTOR); } @@ -1075,6 +1133,7 @@ static void next_page(GtkAssistant *assistant, gpointer user_data) if (added_pages[page_no]->name == PAGE_ANALYZE_SELECTOR && g_analyze_event_selected != NULL + && g_analyze_event_selected[0] ) { start_event_run(g_analyze_event_selected, NULL, @@ -1146,11 +1205,12 @@ static void on_page_prepare(GtkAssistant *assistant, GtkWidget *page, gpointer u static gint next_page_no(gint current_page_no, gpointer data) { - again: - current_page_no++; /* we don't need any magic here if we're in only-report mode */ if (g_report_only) - return current_page_no; + return current_page_no + 1; + + again: + current_page_no++; switch (current_page_no) { @@ -1167,12 +1227,17 @@ static gint next_page_no(gint current_page_no, gpointer data) goto again; /* no backtrace, skip next page */ case PAGENO_ANALYZE_SELECTOR: - if (!g_analyze_events[0]) + if (!g_analyze_events[0] || g_black_event_count == 0) { - //TODO: if (!g_reporter_events[0]) /* no reporters available */ then what? - return PAGENO_REPORTER_SELECTOR; /* skip analyze pages */ + /* skip analyze selector page and analyze log page */ + current_page_no = PAGENO_REPORTER_SELECTOR-1; + goto again; } break; + + case PAGENO_ANALYZE_PROGRESS: + if (!g_analyze_event_selected || !g_analyze_event_selected[0]) + goto again; } VERB2 log("next page_no:%d", current_page_no); diff --git a/src/gui-wizard-gtk/wizard.h b/src/gui-wizard-gtk/wizard.h index bfc6d915..772fcc05 100644 --- a/src/gui-wizard-gtk/wizard.h +++ b/src/gui-wizard-gtk/wizard.h @@ -24,7 +24,6 @@ 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_reanalyze_events; extern char *g_report_events; extern problem_data_t *g_cd; extern int g_report_only; diff --git a/src/include/report/event_config.h b/src/include/report/event_config.h index 5c898d9a..2e2783de 100644 --- a/src/include/report/event_config.h +++ b/src/include/report/event_config.h @@ -71,6 +71,7 @@ typedef struct //char *action; //action description to show in gui like: Upload report to the Red Hat bugzilla" char *description; // "Report to..."/"Save to file". Should be one sentence, not long char *long_descr; // Long(er) explanation, if needed + char *creates_elements; GList *options; } event_config_t; diff --git a/src/lib/event_config.c b/src/lib/event_config.c index 66f9beba..9f48af54 100644 --- a/src/lib/event_config.c +++ b/src/lib/event_config.c @@ -55,6 +55,7 @@ void free_event_config(event_config_t *p) //free(p->action); free(p->description); free(p->long_descr); + free(p->creates_elements); for (opt = p->options; opt; opt = opt->next) free_event_option(opt->data); g_list_free(p->options); diff --git a/src/lib/event_xml_parser.c b/src/lib/event_xml_parser.c index 17e8a72e..30c0ee31 100644 --- a/src/lib/event_xml_parser.c +++ b/src/lib/event_xml_parser.c @@ -25,6 +25,7 @@ #define LONG_DESCR_ELEMENT "long-description" #define ALLOW_EMPTY_ELEMENT "allow-empty" #define NOTE_HTML_ELEMENT "note-html" +#define CREATES_ELEMENT "creates-elements" #define OPTION_ELEMENT "option" //#define ACTION_ELEMENT "action" #define NAME_ELEMENT "name" @@ -297,11 +298,18 @@ static void text(GMarkupParseContext *context, if (strcmp(inner_element, ACTION_ELEMENT) == 0) { VERB2 log("action description:'%s'", text_copy); - free(ui->eo_action); - ui->eo_action = text_copy; + free(ui->action); + ui->action = text_copy; return; } */ + if (strcmp(inner_element, CREATES_ELEMENT) == 0) + { + VERB2 log("creates_elements:'%s'", text_copy); + free(ui->creates_elements); + ui->creates_elements = text_copy; + return; + } if (strcmp(inner_element, NAME_ELEMENT) == 0) { if (parse_data->attribute_lang != NULL) /* if it isn't for other locale */ diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am index bfa60903..b0d93c8b 100644 --- a/src/plugins/Makefile.am +++ b/src/plugins/Makefile.am @@ -102,10 +102,6 @@ EXTRA_DIST = \ $(DESTDIR)/$(DEBUG_INFO_DIR): $(mkdir_p) '$@' -install-data-hook: $(DESTDIR)/$(DEBUG_INFO_DIR) - $(LN_S) -f analyze_RetraceServer.xml $(DESTDIR)$(eventsdir)/reanalyze_RetraceServer.xml - $(LN_S) -f analyze_LocalGDB.xml $(DESTDIR)$(eventsdir)/reanalyze_LocalGDB.xml - abrt_dump_oops_SOURCES = \ abrt-dump-oops.c abrt_dump_oops_CPPFLAGS = \ diff --git a/src/plugins/analyze_LocalGDB.xml.in b/src/plugins/analyze_LocalGDB.xml.in index 925f2c41..4f7ccce1 100644 --- a/src/plugins/analyze_LocalGDB.xml.in +++ b/src/plugins/analyze_LocalGDB.xml.in @@ -5,4 +5,5 @@ <_long-description>Needs to downloads debuginfo packages, which might take significant time, and take up disk space. However, unlike RetraceServer, doesn't send coredump to remote machines. + backtrace diff --git a/src/plugins/analyze_RetraceServer.xml.in b/src/plugins/analyze_RetraceServer.xml.in index 497fa13e..d2072db5 100644 --- a/src/plugins/analyze_RetraceServer.xml.in +++ b/src/plugins/analyze_RetraceServer.xml.in @@ -6,6 +6,7 @@ Pros: no need for debuginfo downloads. Retrace server's database of debuginfos is more complete. Retrace server may generate better backtraces. Cons: coredump you upload contains all the data from the crashed program, including your private data, if any. + backtrace