예제 #1
0
파일: perf.cpp 프로젝트: tomspur/powertop
perf_event::~perf_event(void)
{
	if (name)
		free(name);

	if (perf_event::pevent->ref_count == 1) {
		pevent_free(perf_event::pevent);
		perf_event::pevent = NULL;
	} else
		pevent_unref(perf_event::pevent);
}
예제 #2
0
/**
 * tracecmd_local_events - create a pevent from the events on system
 * @tracing_dir: The directory that contains the events.
 *
 * Returns a pevent structure that contains the pevents local to
 * the system.
 */
struct pevent *tracecmd_local_events(const char *tracing_dir)
{
	struct pevent *pevent = NULL;

	pevent = pevent_alloc();
	if (!pevent)
		return NULL;

	if (tracecmd_fill_local_events(tracing_dir, pevent)) {
		pevent_free(pevent);
		pevent = NULL;
	}

	return pevent;
}
예제 #3
0
static void show_plugins(void)
{
	struct pevent *pevent;
	struct plugin_list *list;
	struct trace_seq s;

	pevent = pevent_alloc();
	if (!pevent)
		die("Can not allocate pevent\n");

	trace_seq_init(&s);

	list = tracecmd_load_plugins(pevent);
	trace_util_print_plugins(&s, "  ", "\n", list);
	trace_seq_do_printf(&s);
	tracecmd_unload_plugins(list, pevent);
	pevent_free(pevent);
}
예제 #4
0
void trace_event__cleanup(struct trace_event *t)
{
	traceevent_unload_plugins(t->plugin_list, t->pevent);
	pevent_free(t->pevent);
}
예제 #5
0
int main (int argc, char **argv)
{
	int c;

	errno = 0;

	if (argc < 2)
		usage(argv);

	if (strcmp(argv[1], "report") == 0) {
		trace_report(argc, argv);
		exit(0);
	} else if (strcmp(argv[1], "snapshot") == 0) {
		trace_snapshot(argc, argv);
		exit(0);
	} else if (strcmp(argv[1], "hist") == 0) {
		trace_hist(argc, argv);
		exit(0);
	} else if (strcmp(argv[1], "mem") == 0) {
		trace_mem(argc, argv);
		exit(0);
	} else if (strcmp(argv[1], "listen") == 0) {
		trace_listen(argc, argv);
		exit(0);
	} else if (strcmp(argv[1], "split") == 0) {
		trace_split(argc, argv);
		exit(0);
	} else if (strcmp(argv[1], "restore") == 0) {
		trace_restore(argc, argv);
		exit(0);
	} else if (strcmp(argv[1], "stack") == 0) {
		trace_stack(argc, argv);
		exit(0);
	} else if (strcmp(argv[1], "check-events") == 0) {
		const char *tracing;
		int ret;
		struct pevent *pevent = NULL;
		struct plugin_list *list = NULL;

		while ((c = getopt(argc-1, argv+1, "+hN")) >= 0) {
			switch (c) {
			case 'h':
			default:
				usage(argv);
				break;
			case 'N':
				tracecmd_disable_plugins = 1;
				break;
			}
		}
		tracing = tracecmd_get_tracing_dir();

		if (!tracing) {
			printf("Can not find or mount tracing directory!\n"
				"Either tracing is not configured for this "
				"kernel\n"
				"or you do not have the proper permissions to "
				"mount the directory");
			exit(EINVAL);
		}

		pevent = pevent_alloc();
		if (!pevent)
			exit(EINVAL);
		list = tracecmd_load_plugins(pevent);
		ret = tracecmd_fill_local_events(tracing, pevent);
		if (ret || pevent->parsing_failures)
			ret = EINVAL;
		tracecmd_unload_plugins(list, pevent);
		pevent_free(pevent);
		exit(ret);

	} else if (strcmp(argv[1], "record") == 0 ||
		   strcmp(argv[1], "start") == 0 ||
		   strcmp(argv[1], "extract") == 0 ||
		   strcmp(argv[1], "stop") == 0 ||
		   strcmp(argv[1], "stream") == 0 ||
		   strcmp(argv[1], "profile") == 0 ||
		   strcmp(argv[1], "restart") == 0 ||
		   strcmp(argv[1], "reset") == 0) {
		trace_record(argc, argv);
		exit(0);

	} else if (strcmp(argv[1], "stat") == 0) {
		trace_stat(argc, argv);
		exit(0);

	} else if (strcmp(argv[1], "options") == 0) {
		show_plugin_options();
		exit(0);
	} else if (strcmp(argv[1], "show") == 0) {
		const char *buffer = NULL;
		const char *file = "trace";
		const char *cpu = NULL;
		struct buffer_instance *instance = &top_instance;
		char cpu_path[128];
		char *path;
		int snap = 0;
		int pipe = 0;
		int show_name = 0;
		int option_index = 0;
		int stop = 0;
		static struct option long_options[] = {
			{"tracing_on", no_argument, NULL, OPT_tracing_on},
			{"current_tracer", no_argument, NULL, OPT_current_tracer},
			{"buffer_size", no_argument, NULL, OPT_buffer_size_kb},
			{"buffer_total_size", no_argument, NULL, OPT_buffer_total_size_kb},
			{"ftrace_filter", no_argument, NULL, OPT_ftrace_filter},
			{"ftrace_notrace", no_argument, NULL, OPT_ftrace_notrace},
			{"ftrace_pid", no_argument, NULL, OPT_ftrace_pid},
			{"graph_function", no_argument, NULL, OPT_graph_function},
			{"graph_notrace", no_argument, NULL, OPT_graph_notrace},
			{"cpumask", no_argument, NULL, OPT_cpumask},
			{"help", no_argument, NULL, '?'},
			{NULL, 0, NULL, 0}
		};

		while ((c = getopt_long(argc-1, argv+1, "B:c:fsp",
					long_options, &option_index)) >= 0) {
			switch (c) {
			case 'h':
				usage(argv);
				break;
			case 'B':
				if (buffer)
					die("Can only show one buffer at a time");
				buffer = optarg;
				instance = create_instance(optarg);
				if (!instance)
					die("Failed to create instance");
				break;
			case 'c':
				if (cpu)
					die("Can only show one CPU at a time");
				cpu = optarg;
				break;
			case 'f':
				show_name = 1;
				break;
			case 's':
				snap = 1;
				if (pipe)
					die("Can not have -s and -p together");
				break;
			case 'p':
				pipe = 1;
				if (snap)
					die("Can not have -s and -p together");
				break;
			case OPT_tracing_on:
				show_instance_file(instance, "tracing_on");
				stop = 1;
				break;
			case OPT_current_tracer:
				show_instance_file(instance, "current_tracer");
				stop = 1;
				break;
			case OPT_buffer_size_kb:
				show_instance_file(instance, "buffer_size_kb");
				stop = 1;
				break;
			case OPT_buffer_total_size_kb:
				show_instance_file(instance, "buffer_total_size_kb");
				stop = 1;
				break;
			case OPT_ftrace_filter:
				show_instance_file(instance, "set_ftrace_filter");
				stop = 1;
				break;
			case OPT_ftrace_notrace:
				show_instance_file(instance, "set_ftrace_notrace");
				stop = 1;
				break;
			case OPT_ftrace_pid:
				show_instance_file(instance, "set_ftrace_pid");
				stop = 1;
				break;
			case OPT_graph_function:
				show_instance_file(instance, "set_graph_function");
				stop = 1;
				break;
			case OPT_graph_notrace:
				show_instance_file(instance, "set_graph_notrace");
				stop = 1;
				break;
			case OPT_cpumask:
				show_instance_file(instance, "tracing_cpumask");
				stop = 1;
				break;
			default:
				usage(argv);
			}
		}
		if (stop)
			exit(0);
		if (pipe)
			file = "trace_pipe";
		else if (snap)
			file = "snapshot";

		if (cpu) {
			snprintf(cpu_path, 128, "per_cpu/cpu%d/%s", atoi(cpu), file);
			file = cpu_path;
		}
			
		if (buffer) {
			path = malloc(strlen(buffer) + strlen("instances//") +
				      strlen(file) + 1);
			if (path)
				die("Failed to allocate instance path %s", file);
			sprintf(path, "instances/%s/%s", buffer, file);
			file = path;
		}

		if (show_name) {
			char *name;
			name = tracecmd_get_tracing_file(file);
			printf("%s\n", name);
			tracecmd_put_tracing_file(name);
		}
		show_file(file);
		if (buffer)
			free(path);

		exit(0);
	} else if (strcmp(argv[1], "list") == 0) {
		int events = 0;
		int tracer = 0;
		int options = 0;
		int funcs = 0;
		int buffers = 0;
		int clocks = 0;
		int plug = 0;
		int plug_op = 0;
		int flags = 0;
		int show_all = 1;
		int i;
		const char *arg;
		const char *funcre = NULL;
		const char *eventre = NULL;

		for (i = 2; i < argc; i++) {
			arg = NULL;
			if (argv[i][0] == '-') {
				if (i < argc - 1) {
					if (argv[i+1][0] != '-')
						arg = argv[i+1];
				}
				switch (argv[i][1]) {
				case 'h':
					usage(argv);
					break;
				case 'e':
					events = 1;
					eventre = arg;
					show_all = 0;
					break;
				case 'B':
					buffers = 1;
					show_all = 0;
					break;
				case 'C':
					clocks = 1;
					show_all = 0;
					break;
				case 'F':
					flags |= SHOW_EVENT_FORMAT;
					break;
				case 'R':
					flags |= SHOW_EVENT_TRIGGER;
					break;
				case 'l':
					flags |= SHOW_EVENT_FILTER;
					break;
				case 'p':
				case 't':
					tracer = 1;
					show_all = 0;
					break;
				case 'P':
					plug = 1;
					show_all = 0;
					break;
				case 'O':
					plug_op = 1;
					show_all = 0;
					break;
				case 'o':
					options = 1;
					show_all = 0;
					break;
				case 'f':
					funcs = 1;
					funcre = arg;
					show_all = 0;
					break;
				default:
					fprintf(stderr, "list: invalid option -- '%c'\n",
						argv[optind][1]);
					usage(argv);
				}
			}
		}

		if (events)
			show_events(eventre, flags);

		if (tracer)
			show_tracers();

		if (options)
			show_options();

		if (plug)
			show_plugins();

		if (plug_op)
			show_plugin_options();

		if (funcs)
			show_functions(funcre);

		if (buffers)
			show_buffers();

		if (clocks)
			show_clocks();

		if (show_all) {
			printf("events:\n");
			show_events(NULL, 0);
			printf("\ntracers:\n");
			show_tracers();
			printf("\noptions:\n");
			show_options();
		}

		exit(0);

	} else if (strcmp(argv[1], "-h") == 0 ||
		   strcmp(argv[1], "help") == 0) {
		usage(argv);
	} else {
		fprintf(stderr, "unknown command: %s\n", argv[1]);
		usage(argv);
	}

	return 0;
}
ssize_t trace_report(int fd, struct pevent **ppevent, bool __repipe)
{
	char buf[BUFSIZ];
	char test[] = { 23, 8, 68 };
	char *version;
	int show_version = 0;
	int show_funcs = 0;
	int show_printk = 0;
	ssize_t size = -1;
	int file_bigendian;
	int host_bigendian;
	int file_long_size;
	int file_page_size;
	struct pevent *pevent;
	int err;

	*ppevent = NULL;

	repipe = __repipe;
	input_fd = fd;

	if (do_read(buf, 3) < 0)
		return -1;
	if (memcmp(buf, test, 3) != 0) {
		pr_debug("no trace data in the file");
		return -1;
	}

	if (do_read(buf, 7) < 0)
		return -1;
	if (memcmp(buf, "tracing", 7) != 0) {
		pr_debug("not a trace file (missing 'tracing' tag)");
		return -1;
	}

	version = read_string();
	if (version == NULL)
		return -1;
	if (show_version)
		printf("version = %s\n", version);
	free(version);

	if (do_read(buf, 1) < 0)
		return -1;
	file_bigendian = buf[0];
	host_bigendian = bigendian();

	pevent = read_trace_init(file_bigendian, host_bigendian);
	if (pevent == NULL) {
		pr_debug("read_trace_init failed");
		goto out;
	}

	if (do_read(buf, 1) < 0)
		goto out;
	file_long_size = buf[0];

	file_page_size = read4(pevent);
	if (!file_page_size)
		goto out;

	pevent_set_long_size(pevent, file_long_size);
	pevent_set_page_size(pevent, file_page_size);

	err = read_header_files(pevent);
	if (err)
		goto out;
	err = read_ftrace_files(pevent);
	if (err)
		goto out;
	err = read_event_files(pevent);
	if (err)
		goto out;
	err = read_proc_kallsyms(pevent);
	if (err)
		goto out;
	err = read_ftrace_printk(pevent);
	if (err)
		goto out;

	size = trace_data_size;
	repipe = false;

	if (show_funcs) {
		pevent_print_funcs(pevent);
	} else if (show_printk) {
		pevent_print_printk(pevent);
	}

	*ppevent = pevent;
	pevent = NULL;

out:
	if (pevent)
		pevent_free(pevent);
	return size;
}
예제 #7
0
/*
 * Trace Capture Dialog Window
 *
 *    +--------------------------------------------------------------------+
 *    |  Dialog Window                                                     |
 *    |  +-------------------------------+-------------------------------+ |
 *    |  | Paned Window                  | +---------------------------+ | |
 *    |  | +---------------------------+ | | Scroll window             | | |
 *    |  | | Hbox                      | | | +-----------------------+ | | |
 *    |  | |  Label   Plugin Combo     | | | | Event Tree            | | | |
 *    |  | +---------------------------+ | | |                       | | | |
 *    |  |                               | | |                       | | | |
 *    |  |                               | | +-----------------------+ | | |
 *    |  |                               | +---------------------------+ | |
 *    |  +-------------------------------+-------------------------------+ |
 *    +--------------------------------------------------------------------+
 */
static void tracing_dialog(struct shark_info *info, const char *tracing)
{
	struct pevent *pevent;
	GtkWidget *dialog;
	GtkWidget *button;
	GtkWidget *combo;
	GtkWidget *label;
	GtkWidget *entry;
	GtkWidget *frame;
	GtkWidget *vbox;
	GtkWidget *scrollwin;
	GtkWidget *table;
	GtkWidget *table2;
	GtkWidget *event_tree;
	GtkWidget *viewport;
	GtkWidget *textview;
	GtkWidget *hbox;
	GtkTextBuffer *buffer;
	GtkTextIter start_iter;
	GtkTextIter end_iter;
	char **plugins;
	int nr_plugins;
	struct trace_capture cap;
	const gchar *file;
	const char *command;
	const char *val;
	GString *str;
	gint result;

	memset(&cap, 0, sizeof(cap));

	cap.info = info;
	plugins = tracecmd_local_plugins(tracing);

	/* Skip latency plugins */
	nr_plugins = trim_plugins(plugins);
	if (!nr_plugins && plugins) {
		tracecmd_free_list(plugins);
		plugins = NULL;
	}

	/* Send parse warnings to status display */
	trace_dialog_register_alt_warning(vpr_stat);

	pevent = tracecmd_local_events(tracing);
	trace_dialog_register_alt_warning(NULL);

	cap.pevent = pevent;

	if (!pevent && !nr_plugins) {
		warning("No events or plugins found");
		return;
	}

	dialog = gtk_dialog_new();
	gtk_window_set_title(GTK_WINDOW(dialog), "Capture");

	button = gtk_button_new_with_label("Run");
	gtk_dialog_add_action_widget(GTK_DIALOG(dialog), button,
				       GTK_RESPONSE_ACCEPT);
	gtk_widget_show(button);

	cap.run_button = button;

	gtk_dialog_add_button(GTK_DIALOG(dialog), GTK_STOCK_CLOSE,
			      GTK_RESPONSE_REJECT);

	cap.main_dialog = dialog;

	/* --- Top Level Hpaned --- */
	table = gtk_table_new(4, 2, FALSE);

	/* It is possible that no pevents exist. */
	if (pevent) {

		scrollwin = gtk_scrolled_window_new(NULL, NULL);
		gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin),
					       GTK_POLICY_AUTOMATIC,
					       GTK_POLICY_AUTOMATIC);

		gtk_table_attach(GTK_TABLE(table), scrollwin, 0, 1, 1, 2,
				 GTK_FILL, GTK_FILL|GTK_EXPAND, 0, 0);
		gtk_widget_show(scrollwin);

		event_tree = trace_create_event_list_view(pevent, NULL,
							  cap.info->cap_all_events,
							  cap.info->cap_systems,
							  cap.info->cap_events);

		gtk_container_add(GTK_CONTAINER(scrollwin), event_tree);
		gtk_widget_show(event_tree);

		cap.event_view = event_tree;

	} else {
		/* No events */
		label = gtk_label_new("No events enabled on system");
		gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2,
				 GTK_FILL, GTK_EXPAND|GTK_FILL,
				 0, 10);
		gtk_widget_show(label);
		cap.event_view = NULL;
	}

	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), table, TRUE, TRUE, 0);
	gtk_widget_show(table);

	/*------------------ Frame Settings --------------------------- */

	frame = gtk_frame_new("Settings");
	gtk_table_attach(GTK_TABLE(table), frame, 0, 1, 0, 1,
			 GTK_FILL, 0, 0, 10);
	gtk_widget_show(frame);

	table2 = gtk_table_new(2, 3, FALSE);
	gtk_container_add(GTK_CONTAINER(frame), table2);
	gtk_widget_show(table2);

	gtk_table_set_col_spacings(GTK_TABLE(table2), 5);

	button = gtk_button_new_with_label("Save Settings");
	gtk_table_attach_defaults(GTK_TABLE(table2), button, 0, 1, 0, 1);
	gtk_widget_show(button);

	g_signal_connect (button, "clicked",
			  G_CALLBACK (save_settings_clicked),
			  (gpointer)&cap);

	button = gtk_button_new_with_label("Import Settings");
	gtk_table_attach_defaults(GTK_TABLE(table2), button, 1, 2, 0, 1);
	gtk_widget_show(button);

	g_signal_connect (button, "clicked",
			  G_CALLBACK (import_settings_clicked),
			  (gpointer)&cap);


	button = gtk_button_new_with_label("Export Settings");
	gtk_table_attach_defaults(GTK_TABLE(table2), button, 2, 3, 0, 1);
	gtk_widget_show(button);

	g_signal_connect (button, "clicked",
			  G_CALLBACK (export_settings_clicked),
			  (gpointer)&cap);

	if (cap.info->cap_settings_name)
		set_settings(&cap);

	label = gtk_label_new("Available Settings: ");
	gtk_table_attach_defaults(GTK_TABLE(table2), label, 0, 1, 1, 2);
	gtk_widget_show(label);

	combo = trace_create_combo_box(NULL, NULL,
				       create_settings_model, NULL);
	gtk_table_attach_defaults(GTK_TABLE(table2), combo, 1, 3, 1, 2);

	cap.settings_combo = combo;

	g_signal_connect (combo, "changed",
			  G_CALLBACK (settings_changed),
			  (gpointer)&cap);



	/*------------------ Frame Settings --------------------------- */

	frame = gtk_frame_new("Execute");
	gtk_table_attach(GTK_TABLE(table), frame, 0, 1, 3, 4,
			 GTK_FILL, 0, 0, 10);
	gtk_widget_show(frame);

	table2 = gtk_table_new(3, 3, FALSE);
	gtk_container_add(GTK_CONTAINER(frame), table2);
	gtk_widget_show(table2);

	label = gtk_label_new("Plugin: ");
	gtk_table_attach_defaults(GTK_TABLE(table2), label, 0, 1, 0, 1);
	gtk_widget_show(label);

	combo = trace_create_combo_box(NULL, NULL, create_plugin_combo_model, plugins);
	cap.plugin_combo = combo;

	gtk_table_attach_defaults(GTK_TABLE(table2), combo, 1, 3, 0, 1);

	if (cap.info->cap_plugin)
		set_plugin(&cap);


	label = gtk_label_new("Command:");
	gtk_table_attach_defaults(GTK_TABLE(table2), label, 0, 1, 1, 2);
	gtk_widget_show(label);

	entry = gtk_entry_new();
	gtk_table_attach_defaults(GTK_TABLE(table2), entry, 1, 3, 1, 2);
	gtk_widget_show(entry);

	cap.command_entry = entry;

	if (cap.info->cap_command)
		gtk_entry_set_text(GTK_ENTRY(entry), cap.info->cap_command);

	label = gtk_label_new("Output file: ");
	gtk_table_attach_defaults(GTK_TABLE(table2), label, 0, 1, 2, 3);
	gtk_widget_show(label);

	entry = gtk_entry_new();
	gtk_table_attach_defaults(GTK_TABLE(table2), entry, 1, 2, 2, 3);
	gtk_widget_show(entry);

	if (cap.info->cap_file)
		file = cap.info->cap_file;
	else
		file = default_output_file;

	gtk_entry_set_text(GTK_ENTRY(entry), file);
	cap.file_entry = entry;

	button = gtk_button_new_with_label("Browse");
	gtk_table_attach_defaults(GTK_TABLE(table2), button, 2, 3, 2, 3);
	gtk_widget_show(button);

	g_signal_connect (button, "clicked",
			  G_CALLBACK (file_clicked),
			  (gpointer)&cap);


	/*------------------ Command Output ------------------ */

	vbox = gtk_vbox_new(FALSE, 0);
	gtk_table_attach_defaults(GTK_TABLE(table), vbox, 1, 2, 0, 4);
	gtk_widget_show(vbox);
	gtk_widget_set_size_request(GTK_WIDGET(vbox), 500, 0);


	label = gtk_label_new("Output Display:");
	gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
	gtk_widget_show(label);

	scrollwin = gtk_scrolled_window_new(NULL, NULL);
	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin),
				       GTK_POLICY_AUTOMATIC,
				       GTK_POLICY_AUTOMATIC);
	gtk_box_pack_start(GTK_BOX(vbox), scrollwin, TRUE, TRUE, 0);
	gtk_widget_show(scrollwin);

	viewport = gtk_viewport_new(NULL, NULL);
	gtk_widget_show(viewport);

	gtk_container_add(GTK_CONTAINER(scrollwin), viewport);

	textview = gtk_text_view_new();
	buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));

	gtk_container_add(GTK_CONTAINER(viewport), textview);
	gtk_widget_show(textview);

	cap.output_text = textview;
	cap.output_buffer = buffer;

	/* set the buffer from its previous setting */
	if (info->cap_buffer_output)
		gtk_text_buffer_set_text(buffer, info->cap_buffer_output,
					 strlen(info->cap_buffer_output));

	hbox = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
	gtk_widget_show(hbox);

	label = gtk_label_new("Max # of characters in output display: ");
	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
	gtk_widget_show(label);

	entry = gtk_entry_new();
	gtk_box_pack_start(GTK_BOX(hbox), entry, FALSE, FALSE, 0);
	gtk_widget_show(entry);

	cap.max_num_entry = entry;

	if (!info->cap_max_buf_size)
		info->cap_max_buf_size = DEFAULT_MAX_BUF_SIZE;

	str = g_string_new("");
	g_string_append_printf(str, "%d", info->cap_max_buf_size);
	gtk_entry_set_text(GTK_ENTRY(entry), str->str);
	g_string_free(str, TRUE);

	g_signal_connect (entry, "insert-text",
			  G_CALLBACK (insert_text),
			  (gpointer)&cap);


	gtk_widget_set_size_request(GTK_WIDGET(dialog),
				    DIALOG_WIDTH, DIALOG_HEIGHT);

	gtk_widget_show(dialog);

 cont:
	result = gtk_dialog_run(GTK_DIALOG(dialog));

	if (result == GTK_RESPONSE_ACCEPT) {
		execute_button_clicked(&cap);
		goto cont;
	}

	/* Make sure no capture is running */
	end_capture(&cap);

	/* Get the max buffer size */
	val = gtk_entry_get_text(GTK_ENTRY(entry));
	info->cap_max_buf_size = atoi(val);

	gtk_text_buffer_get_start_iter(cap.output_buffer, &start_iter);
	gtk_text_buffer_get_end_iter(cap.output_buffer, &end_iter);

	g_free(info->cap_buffer_output);
	info->cap_buffer_output = gtk_text_buffer_get_text(cap.output_buffer,
							   &start_iter,
							   &end_iter,
							   FALSE);

	/* save the plugin and file to reuse if we come back */
	update_plugin(&cap);

	free(info->cap_file);
	cap.info->cap_file = strdup(gtk_entry_get_text(GTK_ENTRY(cap.file_entry)));

	free(info->cap_command);
	command = gtk_entry_get_text(GTK_ENTRY(cap.command_entry));
	if (command && strlen(command) && !is_just_ws(command))
		cap.info->cap_command = strdup(command);
	else
		cap.info->cap_command = NULL;

	update_events(&cap);

	gtk_widget_destroy(dialog);

	if (pevent)
		pevent_free(pevent);

	if (plugins)
		tracecmd_free_list(plugins);
}