aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2010-06-15 11:19:45 -0400
committerSteven Rostedt <rostedt@goodmis.org>2010-06-15 14:55:09 -0400
commit2f27be407d208c77cf8a3611beffd6cd66931a39 (patch)
treec59acfe7158e2dbe4277f46d15c887fff004e22b
parentf24b5515a0087e1560a4ce1d2c863151f4f6fe47 (diff)
kernelshark: Keep capture state persistent
Make the changes to the capture dialog persistent. That is if the user makes updates to the dialog then closes it, the next time they open it, it will still contain their changes. Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r--kernel-shark.c2
-rw-r--r--kernel-shark.h9
-rw-r--r--trace-capture.c185
3 files changed, 152 insertions, 44 deletions
diff --git a/kernel-shark.c b/kernel-shark.c
index acd6d09..0c50849 100644
--- a/kernel-shark.c
+++ b/kernel-shark.c
@@ -207,6 +207,8 @@ static void free_info(struct shark_info *info)
207 filter_task_hash_free(info->list_task_filter); 207 filter_task_hash_free(info->list_task_filter);
208 filter_task_hash_free(info->list_hide_tasks); 208 filter_task_hash_free(info->list_hide_tasks);
209 209
210 kernel_shark_clear_capture(info);
211
210 free(info->ginfo); 212 free(info->ginfo);
211 free(info); 213 free(info);
212} 214}
diff --git a/kernel-shark.h b/kernel-shark.h
index 31a64bf..e80ee33 100644
--- a/kernel-shark.h
+++ b/kernel-shark.h
@@ -49,11 +49,20 @@ struct shark_info {
49 gboolean sync_event_filters; 49 gboolean sync_event_filters;
50 struct filter_task *list_task_filter; 50 struct filter_task *list_task_filter;
51 struct filter_task *list_hide_tasks; 51 struct filter_task *list_hide_tasks;
52
53 /* Save capture state. */
54 gboolean cap_all_events;
55 gchar **cap_systems;
56 int *cap_events;
57 gchar *cap_plugin;
58 gchar *cap_command;
59 gchar *cap_file;
52}; 60};
53 61
54#define offset_of(type, field) (long)(&((type *)0)->field) 62#define offset_of(type, field) (long)(&((type *)0)->field)
55#define container_of(p, type, field) (type *)((long)p - offset_of(type, field)) 63#define container_of(p, type, field) (type *)((long)p - offset_of(type, field))
56 64
57int kernelshark_load_file(struct shark_info *info, const char *file); 65int kernelshark_load_file(struct shark_info *info, const char *file);
66void kernel_shark_clear_capture(struct shark_info *info);
58 67
59#endif /* _KERNEL_SHARK_H */ 68#endif /* _KERNEL_SHARK_H */
diff --git a/trace-capture.c b/trace-capture.c
index 74886d7..7e5f7fc 100644
--- a/trace-capture.c
+++ b/trace-capture.c
@@ -43,6 +43,8 @@
43 43
44#define default_output_file "trace.dat" 44#define default_output_file "trace.dat"
45 45
46#define PLUGIN_NONE "NONE"
47
46struct trace_capture { 48struct trace_capture {
47 struct pevent *pevent; 49 struct pevent *pevent;
48 struct shark_info *info; 50 struct shark_info *info;
@@ -55,13 +57,9 @@ struct trace_capture {
55 GtkWidget *plugin_combo; 57 GtkWidget *plugin_combo;
56 GtkWidget *stop_dialog; 58 GtkWidget *stop_dialog;
57 pthread_t thread; 59 pthread_t thread;
58 gboolean all_events;
59 gboolean kill_thread; 60 gboolean kill_thread;
60 gboolean capture_done; 61 gboolean capture_done;
61 gboolean load_file; 62 gboolean load_file;
62 gchar **systems;
63 int *events;
64 gchar *plugin;
65 int command_input_fd; 63 int command_input_fd;
66 int command_output_fd; 64 int command_output_fd;
67 int command_pid; 65 int command_pid;
@@ -77,25 +75,41 @@ static int is_just_ws(const char *str)
77 return !str[i]; 75 return !str[i];
78} 76}
79 77
80static void clear_capture_events(struct trace_capture *cap) 78static void ks_clear_capture_events(struct shark_info *info)
81{ 79{
82 int i; 80 int i;
83 81
84 cap->all_events = FALSE; 82 info->cap_all_events = FALSE;
85 83
86 if (cap->systems) { 84 if (info->cap_systems) {
87 for (i = 0; cap->systems[i]; i++) 85 for (i = 0; info->cap_systems[i]; i++)
88 free(cap->systems[i]); 86 free(info->cap_systems[i]);
89 87
90 free(cap->systems); 88 free(info->cap_systems);
91 cap->systems = NULL; 89 info->cap_systems = NULL;
92 } 90 }
93 91
94 free(cap->events); 92 free(info->cap_events);
95 cap->events = NULL; 93 info->cap_events = NULL;
96} 94}
97 95
98void end_capture(struct trace_capture *cap) 96static void clear_capture_events(struct trace_capture *cap)
97{
98 ks_clear_capture_events(cap->info);
99}
100
101void kernel_shark_clear_capture(struct shark_info *info)
102{
103 ks_clear_capture_events(info);
104
105 g_free(info->cap_plugin);
106 info->cap_plugin = NULL;
107
108 free(info->cap_file);
109 info->cap_file = NULL;
110}
111
112static void end_capture(struct trace_capture *cap)
99{ 113{
100 const char *filename; 114 const char *filename;
101 int pid; 115 int pid;
@@ -257,20 +271,20 @@ static int calculate_trace_cmd_words(struct trace_capture *cap)
257 int words = 4; /* trace-cmd record -o file */ 271 int words = 4; /* trace-cmd record -o file */
258 int i; 272 int i;
259 273
260 if (cap->all_events) 274 if (cap->info->cap_all_events)
261 words += 2; 275 words += 2;
262 else { 276 else {
263 if (cap->systems) { 277 if (cap->info->cap_systems) {
264 for (i = 0; cap->systems[i]; i++) 278 for (i = 0; cap->info->cap_systems[i]; i++)
265 words += 2; 279 words += 2;
266 } 280 }
267 281
268 if (cap->events) 282 if (cap->info->cap_events)
269 for (i = 0; cap->events[i] >= 0; i++) 283 for (i = 0; cap->info->cap_events[i] >= 0; i++)
270 words += 2; 284 words += 2;
271 } 285 }
272 286
273 if (cap->plugin) 287 if (cap->info->cap_plugin)
274 words += 2; 288 words += 2;
275 289
276 return words; 290 return words;
@@ -279,9 +293,9 @@ static int calculate_trace_cmd_words(struct trace_capture *cap)
279static int add_trace_cmd_words(struct trace_capture *cap, char **args) 293static int add_trace_cmd_words(struct trace_capture *cap, char **args)
280{ 294{
281 struct event_format *event; 295 struct event_format *event;
282 char **systems = cap->systems; 296 char **systems = cap->info->cap_systems;
283 const gchar *output; 297 const gchar *output;
284 int *events = cap->events; 298 int *events = cap->info->cap_events;
285 int words = 0; 299 int words = 0;
286 int len; 300 int len;
287 int i; 301 int i;
@@ -293,12 +307,12 @@ static int add_trace_cmd_words(struct trace_capture *cap, char **args)
293 args[words++] = strdup("-o"); 307 args[words++] = strdup("-o");
294 args[words++] = strdup(output); 308 args[words++] = strdup(output);
295 309
296 if (cap->plugin) { 310 if (cap->info->cap_plugin) {
297 args[words++] = strdup("-p"); 311 args[words++] = strdup("-p");
298 args[words++] = strdup(cap->plugin); 312 args[words++] = strdup(cap->info->cap_plugin);
299 } 313 }
300 314
301 if (cap->all_events) { 315 if (cap->info->cap_all_events) {
302 args[words++] = strdup("-e"); 316 args[words++] = strdup("-e");
303 args[words++] = strdup("all"); 317 args[words++] = strdup("all");
304 } else { 318 } else {
@@ -346,6 +360,67 @@ static gchar *get_combo_text(GtkComboBox *combo)
346 return text; 360 return text;
347} 361}
348 362
363static void update_plugin(struct trace_capture *cap)
364{
365 cap->info->cap_plugin = get_combo_text(GTK_COMBO_BOX(cap->plugin_combo));
366 if (strcmp(cap->info->cap_plugin, PLUGIN_NONE) == 0) {
367 g_free(cap->info->cap_plugin);
368 cap->info->cap_plugin = NULL;
369 }
370
371}
372
373static void set_plugin(struct trace_capture *cap)
374{
375 GtkComboBox *combo = GTK_COMBO_BOX(cap->plugin_combo);
376 GtkTreeModel *model;
377 GtkTreeIter iter;
378 gchar *text;
379 const gchar *plugin = cap->info->cap_plugin;
380 gboolean ret = TRUE;
381
382 if (!plugin)
383 plugin = PLUGIN_NONE;
384
385 model = gtk_combo_box_get_model(combo);
386 if (!model)
387 return;
388
389 if (!gtk_tree_model_get_iter_first(model, &iter))
390 return;
391
392 do {
393 gtk_tree_model_get(model, &iter,
394 0, &text,
395 -1);
396 if (strcmp(text, plugin) == 0) {
397 g_free(text);
398 break;
399 }
400
401 g_free(text);
402
403 ret = gtk_tree_model_iter_next(model, &iter);
404 } while (ret);
405
406 if (ret) {
407 gtk_combo_box_set_active_iter(GTK_COMBO_BOX(combo),
408 &iter);
409 return;
410 }
411
412 /* Not found? */
413 g_free(cap->info->cap_plugin);
414 cap->info->cap_plugin = NULL;
415
416 /* set to NONE */
417 if (!gtk_tree_model_get_iter_first(model, &iter))
418 return;
419
420 gtk_combo_box_set_active_iter(GTK_COMBO_BOX(combo),
421 &iter);
422}
423
349static void execute_command(struct trace_capture *cap) 424static void execute_command(struct trace_capture *cap)
350{ 425{
351 const gchar *ccommand; 426 const gchar *ccommand;
@@ -356,11 +431,7 @@ static void execute_command(struct trace_capture *cap)
356 int tc_words; 431 int tc_words;
357 int i; 432 int i;
358 433
359 cap->plugin = get_combo_text(GTK_COMBO_BOX(cap->plugin_combo)); 434 update_plugin(cap);
360 if (strcmp(cap->plugin, "NONE") == 0) {
361 g_free(cap->plugin);
362 cap->plugin = NULL;
363 }
364 435
365 ccommand = gtk_entry_get_text(GTK_ENTRY(cap->command_entry)); 436 ccommand = gtk_entry_get_text(GTK_ENTRY(cap->command_entry));
366 if (!ccommand || !strlen(ccommand) || is_just_ws(ccommand)) { 437 if (!ccommand || !strlen(ccommand) || is_just_ws(ccommand)) {
@@ -418,7 +489,7 @@ static void execute_command(struct trace_capture *cap)
418 for (i = 0; args[i]; i++) 489 for (i = 0; args[i]; i++)
419 free(args[i]); 490 free(args[i]);
420 free(args); 491 free(args);
421 g_free(cap->plugin); 492 g_free(cap->info->cap_plugin);
422} 493}
423 494
424static gint 495static gint
@@ -595,26 +666,28 @@ static void event_filter_callback(gboolean accept,
595 clear_capture_events(cap); 666 clear_capture_events(cap);
596 667
597 if (all_events) { 668 if (all_events) {
598 cap->all_events = TRUE; 669 cap->info->cap_all_events = TRUE;
599 return; 670 return;
600 } 671 }
601 672
602 if (systems) { 673 if (systems) {
603 for (nr_sys = 0; systems[nr_sys]; nr_sys++) 674 for (nr_sys = 0; systems[nr_sys]; nr_sys++)
604 ; 675 ;
605 cap->systems = malloc_or_die(sizeof(*cap->systems) * (nr_sys + 1)); 676 cap->info->cap_systems = malloc_or_die(sizeof(*cap->info->cap_systems) *
677 (nr_sys + 1));
606 for (i = 0; i < nr_sys; i++) 678 for (i = 0; i < nr_sys; i++)
607 cap->systems[i] = strdup(systems[i]); 679 cap->info->cap_systems[i] = strdup(systems[i]);
608 cap->systems[i] = NULL; 680 cap->info->cap_systems[i] = NULL;
609 } 681 }
610 682
611 if (events) { 683 if (events) {
612 for (nr_events = 0; events[nr_events] >= 0; nr_events++) 684 for (nr_events = 0; events[nr_events] >= 0; nr_events++)
613 ; 685 ;
614 cap->events = malloc_or_die(sizeof(*cap->events) * (nr_events + 1)); 686 cap->info->cap_events = malloc_or_die(sizeof(*cap->info->cap_events) *
687 (nr_events + 1));
615 for (i = 0; i < nr_events; i++) 688 for (i = 0; i < nr_events; i++)
616 cap->events[i] = events[i]; 689 cap->info->cap_events[i] = events[i];
617 cap->events[i] = -1; 690 cap->info->cap_events[i] = -1;
618 } 691 }
619} 692}
620 693
@@ -623,8 +696,8 @@ static void event_button_clicked(GtkWidget *widget, gpointer data)
623 struct trace_capture *cap = data; 696 struct trace_capture *cap = data;
624 struct pevent *pevent = cap->pevent; 697 struct pevent *pevent = cap->pevent;
625 698
626 trace_filter_pevent_dialog(pevent, cap->all_events, 699 trace_filter_pevent_dialog(pevent, cap->info->cap_all_events,
627 cap->systems, cap->events, 700 cap->info->cap_systems, cap->info->cap_events,
628 event_filter_callback, cap); 701 event_filter_callback, cap);
629} 702}
630 703
@@ -698,7 +771,7 @@ static GtkTreeModel *create_plugin_combo_model(gpointer data)
698 771
699 gtk_list_store_append(list, &iter); 772 gtk_list_store_append(list, &iter);
700 gtk_list_store_set(list, &iter, 773 gtk_list_store_set(list, &iter,
701 0, "NONE", 774 0, PLUGIN_NONE,
702 -1); 775 -1);
703 776
704 for (i = 0; plugins && plugins[i]; i++) { 777 for (i = 0; plugins && plugins[i]; i++) {
@@ -723,6 +796,8 @@ static void tracing_dialog(struct shark_info *info, const char *tracing)
723 char **plugins; 796 char **plugins;
724 int nr_plugins; 797 int nr_plugins;
725 struct trace_capture cap; 798 struct trace_capture cap;
799 const gchar *file;
800 const char *command;
726 801
727 memset(&cap, 0, sizeof(cap)); 802 memset(&cap, 0, sizeof(cap));
728 803
@@ -776,6 +851,9 @@ static void tracing_dialog(struct shark_info *info, const char *tracing)
776 combo = trace_create_combo_box(hbox, "Plugin: ", create_plugin_combo_model, plugins); 851 combo = trace_create_combo_box(hbox, "Plugin: ", create_plugin_combo_model, plugins);
777 cap.plugin_combo = combo; 852 cap.plugin_combo = combo;
778 853
854 if (cap.info->cap_plugin)
855 set_plugin(&cap);
856
779 label = gtk_label_new("Command:"); 857 label = gtk_label_new("Command:");
780 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), label, TRUE, TRUE, 0); 858 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), label, TRUE, TRUE, 0);
781 gtk_widget_show(label); 859 gtk_widget_show(label);
@@ -786,6 +864,9 @@ static void tracing_dialog(struct shark_info *info, const char *tracing)
786 864
787 cap.command_entry = entry; 865 cap.command_entry = entry;
788 866
867 if (cap.info->cap_command)
868 gtk_entry_set_text(GTK_ENTRY(entry), cap.info->cap_command);
869
789 hbox = gtk_hbox_new(FALSE, 0); 870 hbox = gtk_hbox_new(FALSE, 0);
790 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, TRUE, TRUE, 0); 871 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, TRUE, TRUE, 0);
791 gtk_widget_show(hbox); 872 gtk_widget_show(hbox);
@@ -802,7 +883,12 @@ static void tracing_dialog(struct shark_info *info, const char *tracing)
802 gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0); 883 gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0);
803 gtk_widget_show(entry); 884 gtk_widget_show(entry);
804 885
805 gtk_entry_set_text(GTK_ENTRY(entry), default_output_file); 886 if (cap.info->cap_file)
887 file = cap.info->cap_file;
888 else
889 file = default_output_file;
890
891 gtk_entry_set_text(GTK_ENTRY(entry), file);
806 cap.file_entry = entry; 892 cap.file_entry = entry;
807 893
808 button = gtk_button_new_with_label("Execute"); 894 button = gtk_button_new_with_label("Execute");
@@ -816,6 +902,19 @@ static void tracing_dialog(struct shark_info *info, const char *tracing)
816 gtk_widget_show(dialog); 902 gtk_widget_show(dialog);
817 gtk_dialog_run(GTK_DIALOG(dialog)); 903 gtk_dialog_run(GTK_DIALOG(dialog));
818 904
905 /* save the plugin and file to reuse if we come back */
906 update_plugin(&cap);
907
908 free(info->cap_file);
909 cap.info->cap_file = strdup(gtk_entry_get_text(GTK_ENTRY(cap.file_entry)));
910
911 free(info->cap_command);
912 command = gtk_entry_get_text(GTK_ENTRY(cap.command_entry));
913 if (command && strlen(command) && !is_just_ws(command))
914 cap.info->cap_command = strdup(command);
915 else
916 cap.info->cap_command = NULL;
917
819 gtk_widget_destroy(dialog); 918 gtk_widget_destroy(dialog);
820 919
821 end_capture(&cap); 920 end_capture(&cap);
@@ -828,8 +927,6 @@ static void tracing_dialog(struct shark_info *info, const char *tracing)
828 927
829 if (plugins) 928 if (plugins)
830 free_list(plugins); 929 free_list(plugins);
831
832 clear_capture_events(&cap);
833} 930}
834 931
835void tracecmd_capture_clicked(gpointer data) 932void tracecmd_capture_clicked(gpointer data)