diff options
| -rw-r--r-- | trace-capture.c | 284 | ||||
| -rw-r--r-- | trace-cmd.h | 3 | ||||
| -rw-r--r-- | trace-util.c | 21 |
3 files changed, 283 insertions, 25 deletions
diff --git a/trace-capture.c b/trace-capture.c index 7e5f7fc..b5e8852 100644 --- a/trace-capture.c +++ b/trace-capture.c | |||
| @@ -40,6 +40,7 @@ | |||
| 40 | #include "trace-cmd.h" | 40 | #include "trace-cmd.h" |
| 41 | #include "trace-gui.h" | 41 | #include "trace-gui.h" |
| 42 | #include "kernel-shark.h" | 42 | #include "kernel-shark.h" |
| 43 | #include "version.h" | ||
| 43 | 44 | ||
| 44 | #define default_output_file "trace.dat" | 45 | #define default_output_file "trace.dat" |
| 45 | 46 | ||
| @@ -77,17 +78,10 @@ static int is_just_ws(const char *str) | |||
| 77 | 78 | ||
| 78 | static void ks_clear_capture_events(struct shark_info *info) | 79 | static void ks_clear_capture_events(struct shark_info *info) |
| 79 | { | 80 | { |
| 80 | int i; | ||
| 81 | |||
| 82 | info->cap_all_events = FALSE; | 81 | info->cap_all_events = FALSE; |
| 83 | 82 | ||
| 84 | if (info->cap_systems) { | 83 | tracecmd_free_list(info->cap_systems); |
| 85 | for (i = 0; info->cap_systems[i]; i++) | 84 | info->cap_systems = NULL; |
| 86 | free(info->cap_systems[i]); | ||
| 87 | |||
| 88 | free(info->cap_systems); | ||
| 89 | info->cap_systems = NULL; | ||
| 90 | } | ||
| 91 | 85 | ||
| 92 | free(info->cap_events); | 86 | free(info->cap_events); |
| 93 | info->cap_events = NULL; | 87 | info->cap_events = NULL; |
| @@ -160,16 +154,6 @@ static char *get_tracing_dir(void) | |||
| 160 | return tracing_dir; | 154 | return tracing_dir; |
| 161 | } | 155 | } |
| 162 | 156 | ||
| 163 | static void free_list(char **list) | ||
| 164 | { | ||
| 165 | int i; | ||
| 166 | |||
| 167 | for (i = 0; list[i]; i++) | ||
| 168 | free(list[i]); | ||
| 169 | |||
| 170 | free(list); | ||
| 171 | } | ||
| 172 | |||
| 173 | static int is_latency(char *plugin) | 157 | static int is_latency(char *plugin) |
| 174 | { | 158 | { |
| 175 | return strcmp(plugin, "wakeup") == 0 || | 159 | return strcmp(plugin, "wakeup") == 0 || |
| @@ -760,6 +744,246 @@ static void execute_button_clicked(GtkWidget *widget, gpointer data) | |||
| 760 | end_stop_dialog(cap); | 744 | end_stop_dialog(cap); |
| 761 | } | 745 | } |
| 762 | 746 | ||
| 747 | static int load_events(struct trace_capture *cap, | ||
| 748 | struct tracecmd_xml_handle *handle, | ||
| 749 | struct tracecmd_xml_system_node *node) | ||
| 750 | { | ||
| 751 | struct shark_info *info = cap->info; | ||
| 752 | struct tracecmd_xml_system_node *event_node; | ||
| 753 | struct event_format *event; | ||
| 754 | struct pevent *pevent = cap->pevent; | ||
| 755 | const char *name; | ||
| 756 | int *events = NULL; | ||
| 757 | int event_len = 0; | ||
| 758 | const char *system; | ||
| 759 | const char *event_name; | ||
| 760 | |||
| 761 | for (node = tracecmd_xml_node_child(node); node; | ||
| 762 | node = tracecmd_xml_node_next(node)) { | ||
| 763 | name = tracecmd_xml_node_type(node); | ||
| 764 | |||
| 765 | if (strcmp(name, "Event") != 0) | ||
| 766 | continue; | ||
| 767 | |||
| 768 | event_node = tracecmd_xml_node_child(node); | ||
| 769 | if (!event_node) | ||
| 770 | continue; | ||
| 771 | |||
| 772 | name = tracecmd_xml_node_type(event_node); | ||
| 773 | if (strcmp(name, "System") != 0) | ||
| 774 | continue; | ||
| 775 | system = tracecmd_xml_node_value(handle, event_node); | ||
| 776 | |||
| 777 | event_node = tracecmd_xml_node_next(event_node); | ||
| 778 | if (!event_node) | ||
| 779 | continue; | ||
| 780 | |||
| 781 | name = tracecmd_xml_node_type(event_node); | ||
| 782 | if (strcmp(name, "Name") != 0) | ||
| 783 | continue; | ||
| 784 | event_name = tracecmd_xml_node_value(handle, event_node); | ||
| 785 | |||
| 786 | event = pevent_find_event_by_name(pevent, system, event_name); | ||
| 787 | |||
| 788 | if (!event) | ||
| 789 | continue; | ||
| 790 | |||
| 791 | if (!events) | ||
| 792 | events = malloc_or_die(sizeof(*events) * 2); | ||
| 793 | else | ||
| 794 | events = realloc(events, sizeof(*events) * (event_len + 2)); | ||
| 795 | events[event_len++] = event->id; | ||
| 796 | events[event_len] = -1; | ||
| 797 | } | ||
| 798 | |||
| 799 | info->cap_events = events; | ||
| 800 | return 0; | ||
| 801 | } | ||
| 802 | |||
| 803 | static int load_cap_events(struct trace_capture *cap, | ||
| 804 | struct tracecmd_xml_handle *handle, | ||
| 805 | struct tracecmd_xml_system_node *node) | ||
| 806 | { | ||
| 807 | struct shark_info *info = cap->info; | ||
| 808 | const char *name; | ||
| 809 | char **systems = NULL; | ||
| 810 | int sys_len = 0; | ||
| 811 | |||
| 812 | ks_clear_capture_events(info); | ||
| 813 | |||
| 814 | for (node = tracecmd_xml_node_child(node); node; | ||
| 815 | node = tracecmd_xml_node_next(node)) { | ||
| 816 | |||
| 817 | name = tracecmd_xml_node_type(node); | ||
| 818 | |||
| 819 | if (strcmp(name, "CaptureType") == 0) { | ||
| 820 | name = tracecmd_xml_node_value(handle, node); | ||
| 821 | if (strcmp(name, "all events") == 0) { | ||
| 822 | info->cap_all_events = TRUE; | ||
| 823 | break; | ||
| 824 | } | ||
| 825 | continue; | ||
| 826 | |||
| 827 | } else if (strcmp(name, "System") == 0) { | ||
| 828 | name = tracecmd_xml_node_value(handle, node); | ||
| 829 | systems = tracecmd_add_list(systems, name, sys_len++); | ||
| 830 | |||
| 831 | } else if (strcmp(name, "Events") == 0) | ||
| 832 | load_events(cap, handle, node); | ||
| 833 | } | ||
| 834 | |||
| 835 | info->cap_systems = systems; | ||
| 836 | |||
| 837 | return 0; | ||
| 838 | } | ||
| 839 | |||
| 840 | static void load_settings_clicked(GtkWidget *widget, gpointer data) | ||
| 841 | { | ||
| 842 | struct trace_capture *cap = data; | ||
| 843 | struct shark_info *info = cap->info; | ||
| 844 | struct tracecmd_xml_system_node *syschild; | ||
| 845 | struct tracecmd_xml_handle *handle; | ||
| 846 | struct tracecmd_xml_system *system; | ||
| 847 | const char *plugin; | ||
| 848 | const char *name; | ||
| 849 | gchar *filename; | ||
| 850 | |||
| 851 | filename = trace_get_file_dialog("Load Filters", NULL, FALSE); | ||
| 852 | if (!filename) | ||
| 853 | return; | ||
| 854 | |||
| 855 | handle = tracecmd_xml_open(filename); | ||
| 856 | if (!handle) { | ||
| 857 | warning("Could not open %s", filename); | ||
| 858 | g_free(filename); | ||
| 859 | } | ||
| 860 | |||
| 861 | g_free(filename); | ||
| 862 | |||
| 863 | system = tracecmd_xml_find_system(handle, "CaptureSettings"); | ||
| 864 | if (!system) | ||
| 865 | goto out; | ||
| 866 | |||
| 867 | syschild = tracecmd_xml_system_node(system); | ||
| 868 | if (!syschild) | ||
| 869 | goto out_free_sys; | ||
| 870 | |||
| 871 | g_free(info->cap_plugin); | ||
| 872 | info->cap_plugin = NULL; | ||
| 873 | |||
| 874 | do { | ||
| 875 | name = tracecmd_xml_node_type(syschild); | ||
| 876 | if (strcmp(name, "Events") == 0) | ||
| 877 | load_cap_events(cap, handle, syschild); | ||
| 878 | |||
| 879 | else if (strcmp(name, "Plugin") == 0) { | ||
| 880 | plugin = tracecmd_xml_node_value(handle, syschild); | ||
| 881 | info->cap_plugin = g_strdup(plugin); | ||
| 882 | |||
| 883 | } else if (strcmp(name, "Command") == 0) { | ||
| 884 | name = tracecmd_xml_node_value(handle, syschild); | ||
| 885 | gtk_entry_set_text(GTK_ENTRY(cap->command_entry), name); | ||
| 886 | |||
| 887 | } else if (strcmp(name, "File") == 0) { | ||
| 888 | name = tracecmd_xml_node_value(handle, syschild); | ||
| 889 | gtk_entry_set_text(GTK_ENTRY(cap->file_entry), name); | ||
| 890 | } | ||
| 891 | |||
| 892 | syschild = tracecmd_xml_node_next(syschild); | ||
| 893 | } while (syschild); | ||
| 894 | |||
| 895 | set_plugin(cap); | ||
| 896 | |||
| 897 | out_free_sys: | ||
| 898 | tracecmd_xml_free_system(system); | ||
| 899 | |||
| 900 | out: | ||
| 901 | tracecmd_xml_close(handle); | ||
| 902 | } | ||
| 903 | |||
| 904 | static void save_events(struct trace_capture *cap, | ||
| 905 | struct tracecmd_xml_handle *handle) | ||
| 906 | { | ||
| 907 | struct pevent *pevent = cap->pevent; | ||
| 908 | struct event_format *event; | ||
| 909 | char **systems = cap->info->cap_systems; | ||
| 910 | int *events = cap->info->cap_events; | ||
| 911 | int i; | ||
| 912 | |||
| 913 | tracecmd_xml_write_element(handle, "CaptureType", "Events"); | ||
| 914 | |||
| 915 | for (i = 0; systems && systems[i]; i++) | ||
| 916 | tracecmd_xml_write_element(handle, "System", systems[i]); | ||
| 917 | |||
| 918 | if (!events || events[0] < 0) | ||
| 919 | return; | ||
| 920 | |||
| 921 | tracecmd_xml_start_sub_system(handle, "Events"); | ||
| 922 | for (i = 0; events[i] > 0; i++) { | ||
| 923 | event = pevent_find_event(pevent, events[i]); | ||
| 924 | if (event) { | ||
| 925 | tracecmd_xml_start_sub_system(handle, "Event"); | ||
| 926 | tracecmd_xml_write_element(handle, "System", event->system); | ||
| 927 | tracecmd_xml_write_element(handle, "Name", event->name); | ||
| 928 | tracecmd_xml_end_sub_system(handle); | ||
| 929 | } | ||
| 930 | } | ||
| 931 | |||
| 932 | tracecmd_xml_end_sub_system(handle); | ||
| 933 | } | ||
| 934 | |||
| 935 | static void save_settings_clicked(GtkWidget *widget, gpointer data) | ||
| 936 | { | ||
| 937 | struct trace_capture *cap = data; | ||
| 938 | struct shark_info *info = cap->info; | ||
| 939 | struct tracecmd_xml_handle *handle; | ||
| 940 | gchar *filename; | ||
| 941 | const char *file; | ||
| 942 | const char *command; | ||
| 943 | |||
| 944 | filename = trace_get_file_dialog("Save Settings", "Save", TRUE); | ||
| 945 | if (!filename) | ||
| 946 | return; | ||
| 947 | |||
| 948 | handle = tracecmd_xml_create(filename, VERSION_STRING); | ||
| 949 | if (!handle) { | ||
| 950 | warning("Could not create %s", filename); | ||
| 951 | g_free(filename); | ||
| 952 | return; | ||
| 953 | } | ||
| 954 | |||
| 955 | g_free(filename); | ||
| 956 | |||
| 957 | tracecmd_xml_start_system(handle, "CaptureSettings"); | ||
| 958 | |||
| 959 | tracecmd_xml_start_sub_system(handle, "Events"); | ||
| 960 | |||
| 961 | if (info->cap_all_events) | ||
| 962 | tracecmd_xml_write_element(handle, "CaptureType", "all events"); | ||
| 963 | else if ((info->cap_systems && info->cap_systems[0]) || | ||
| 964 | (info->cap_events && info->cap_events[0] >= 0)) { | ||
| 965 | save_events(cap, handle); | ||
| 966 | } | ||
| 967 | |||
| 968 | tracecmd_xml_end_sub_system(handle); | ||
| 969 | |||
| 970 | update_plugin(cap); | ||
| 971 | if (info->cap_plugin) | ||
| 972 | tracecmd_xml_write_element(handle, "Plugin", info->cap_plugin); | ||
| 973 | |||
| 974 | command = gtk_entry_get_text(GTK_ENTRY(cap->command_entry)); | ||
| 975 | if (command && strlen(command) && !is_just_ws(command)) | ||
| 976 | tracecmd_xml_write_element(handle, "Command", command); | ||
| 977 | |||
| 978 | file = gtk_entry_get_text(GTK_ENTRY(cap->file_entry)); | ||
| 979 | if (file && strlen(file) && !is_just_ws(file)) | ||
| 980 | tracecmd_xml_write_element(handle, "File", file); | ||
| 981 | |||
| 982 | tracecmd_xml_end_system(handle); | ||
| 983 | |||
| 984 | tracecmd_xml_close(handle); | ||
| 985 | } | ||
| 986 | |||
| 763 | static GtkTreeModel *create_plugin_combo_model(gpointer data) | 987 | static GtkTreeModel *create_plugin_combo_model(gpointer data) |
| 764 | { | 988 | { |
| 765 | char **plugins = data; | 989 | char **plugins = data; |
| @@ -807,7 +1031,7 @@ static void tracing_dialog(struct shark_info *info, const char *tracing) | |||
| 807 | /* Skip latency plugins */ | 1031 | /* Skip latency plugins */ |
| 808 | nr_plugins = trim_plugins(plugins); | 1032 | nr_plugins = trim_plugins(plugins); |
| 809 | if (!nr_plugins && plugins) { | 1033 | if (!nr_plugins && plugins) { |
| 810 | free_list(plugins); | 1034 | tracecmd_free_list(plugins); |
| 811 | plugins = NULL; | 1035 | plugins = NULL; |
| 812 | } | 1036 | } |
| 813 | 1037 | ||
| @@ -899,6 +1123,24 @@ static void tracing_dialog(struct shark_info *info, const char *tracing) | |||
| 899 | G_CALLBACK (execute_button_clicked), | 1123 | G_CALLBACK (execute_button_clicked), |
| 900 | (gpointer)&cap); | 1124 | (gpointer)&cap); |
| 901 | 1125 | ||
| 1126 | |||
| 1127 | button = gtk_button_new_with_label("Load Settings"); | ||
| 1128 | gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), button, TRUE, TRUE, 0); | ||
| 1129 | gtk_widget_show(button); | ||
| 1130 | |||
| 1131 | g_signal_connect (button, "clicked", | ||
| 1132 | G_CALLBACK (load_settings_clicked), | ||
| 1133 | (gpointer)&cap); | ||
| 1134 | |||
| 1135 | |||
| 1136 | button = gtk_button_new_with_label("Save Settings"); | ||
| 1137 | gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), button, TRUE, TRUE, 0); | ||
| 1138 | gtk_widget_show(button); | ||
| 1139 | |||
| 1140 | g_signal_connect (button, "clicked", | ||
| 1141 | G_CALLBACK (save_settings_clicked), | ||
| 1142 | (gpointer)&cap); | ||
| 1143 | |||
| 902 | gtk_widget_show(dialog); | 1144 | gtk_widget_show(dialog); |
| 903 | gtk_dialog_run(GTK_DIALOG(dialog)); | 1145 | gtk_dialog_run(GTK_DIALOG(dialog)); |
| 904 | 1146 | ||
| @@ -926,7 +1168,7 @@ static void tracing_dialog(struct shark_info *info, const char *tracing) | |||
| 926 | pevent_free(pevent); | 1168 | pevent_free(pevent); |
| 927 | 1169 | ||
| 928 | if (plugins) | 1170 | if (plugins) |
| 929 | free_list(plugins); | 1171 | tracecmd_free_list(plugins); |
| 930 | } | 1172 | } |
| 931 | 1173 | ||
| 932 | void tracecmd_capture_clicked(gpointer data) | 1174 | void tracecmd_capture_clicked(gpointer data) |
diff --git a/trace-cmd.h b/trace-cmd.h index c85bb9b..cbd563e 100644 --- a/trace-cmd.h +++ b/trace-cmd.h | |||
| @@ -40,6 +40,9 @@ char **tracecmd_system_events(const char *tracing_dir, const char *system); | |||
| 40 | struct pevent *tracecmd_local_events(const char *tracing_dir); | 40 | struct pevent *tracecmd_local_events(const char *tracing_dir); |
| 41 | char **tracecmd_local_plugins(const char *tracing_dir); | 41 | char **tracecmd_local_plugins(const char *tracing_dir); |
| 42 | 42 | ||
| 43 | char **tracecmd_add_list(char **list, const char *name, int len); | ||
| 44 | void tracecmd_free_list(char **list); | ||
| 45 | |||
| 43 | enum { | 46 | enum { |
| 44 | RINGBUF_TYPE_PADDING = 29, | 47 | RINGBUF_TYPE_PADDING = 29, |
| 45 | RINGBUF_TYPE_TIME_EXTEND = 30, | 48 | RINGBUF_TYPE_TIME_EXTEND = 30, |
diff --git a/trace-util.c b/trace-util.c index 82c3d1e..058c9d2 100644 --- a/trace-util.c +++ b/trace-util.c | |||
| @@ -241,7 +241,7 @@ static char *append_file(const char *dir, const char *name) | |||
| 241 | return file; | 241 | return file; |
| 242 | } | 242 | } |
| 243 | 243 | ||
| 244 | static char **add_list(char **list, const char *name, int len) | 244 | char **tracecmd_add_list(char **list, const char *name, int len) |
| 245 | { | 245 | { |
| 246 | if (!list) | 246 | if (!list) |
| 247 | list = malloc_or_die(sizeof(*list) * 2); | 247 | list = malloc_or_die(sizeof(*list) * 2); |
| @@ -260,6 +260,19 @@ static char **add_list(char **list, const char *name, int len) | |||
| 260 | return list; | 260 | return list; |
| 261 | } | 261 | } |
| 262 | 262 | ||
| 263 | void tracecmd_free_list(char **list) | ||
| 264 | { | ||
| 265 | int i; | ||
| 266 | |||
| 267 | if (!list) | ||
| 268 | return; | ||
| 269 | |||
| 270 | for (i = 0; list[i]; i++) | ||
| 271 | free(list[i]); | ||
| 272 | |||
| 273 | free(list); | ||
| 274 | } | ||
| 275 | |||
| 263 | /** | 276 | /** |
| 264 | * tracecmd_event_systems - return list of systems for tracing | 277 | * tracecmd_event_systems - return list of systems for tracing |
| 265 | * @tracing_dir: directory holding the "events" directory | 278 | * @tracing_dir: directory holding the "events" directory |
| @@ -317,7 +330,7 @@ char **tracecmd_event_systems(const char *tracing_dir) | |||
| 317 | 330 | ||
| 318 | ret = stat(enable, &st); | 331 | ret = stat(enable, &st); |
| 319 | if (ret >= 0) | 332 | if (ret >= 0) |
| 320 | systems = add_list(systems, name, len++); | 333 | systems = tracecmd_add_list(systems, name, len++); |
| 321 | 334 | ||
| 322 | free(enable); | 335 | free(enable); |
| 323 | free(sys); | 336 | free(sys); |
| @@ -397,7 +410,7 @@ char **tracecmd_system_events(const char *tracing_dir, const char *system) | |||
| 397 | 410 | ||
| 398 | ret = stat(enable, &st); | 411 | ret = stat(enable, &st); |
| 399 | if (ret >= 0) | 412 | if (ret >= 0) |
| 400 | events = add_list(events, name, len++); | 413 | events = tracecmd_add_list(events, name, len++); |
| 401 | 414 | ||
| 402 | free(enable); | 415 | free(enable); |
| 403 | free(event); | 416 | free(event); |
| @@ -645,7 +658,7 @@ char **tracecmd_local_plugins(const char *tracing_dir) | |||
| 645 | strcmp(plugin, "none") == 0) | 658 | strcmp(plugin, "none") == 0) |
| 646 | continue; | 659 | continue; |
| 647 | 660 | ||
| 648 | plugins = add_list(plugins, plugin, len++); | 661 | plugins = tracecmd_add_list(plugins, plugin, len++); |
| 649 | } | 662 | } |
| 650 | free(buf); | 663 | free(buf); |
| 651 | 664 | ||
