]> git.proxmox.com Git - mirror_qemu.git/blame - trace/control.c
trace: count number of enabled events
[mirror_qemu.git] / trace / control.c
CommitLineData
23d15e86
LV
1/*
2 * Interface for configuring and controlling the state of tracing events.
3 *
5b808275 4 * Copyright (C) 2011-2014 Lluís Vilanova <vilanova@ac.upc.edu>
23d15e86 5 *
b1bae816
LV
6 * This work is licensed under the terms of the GNU GPL, version 2 or later.
7 * See the COPYING file in the top-level directory.
23d15e86
LV
8 */
9
10#include "trace/control.h"
5b808275
LV
11#ifdef CONFIG_TRACE_SIMPLE
12#include "trace/simple.h"
13#endif
14#ifdef CONFIG_TRACE_FTRACE
15#include "trace/ftrace.h"
16#endif
a35d9be6 17#include "qemu/error-report.h"
23d15e86 18
43b48cfc
PB
19int trace_events_enabled_count;
20
b1bae816
LV
21TraceEvent *trace_event_name(const char *name)
22{
23 assert(name != NULL);
24
25 TraceEventID i;
26 for (i = 0; i < trace_event_count(); i++) {
27 TraceEvent *ev = trace_event_id(i);
28 if (strcmp(trace_event_get_name(ev), name) == 0) {
29 return ev;
30 }
31 }
32 return NULL;
33}
34
35static bool pattern_glob(const char *pat, const char *ev)
36{
37 while (*pat != '\0' && *ev != '\0') {
38 if (*pat == *ev) {
39 pat++;
40 ev++;
41 }
42 else if (*pat == '*') {
43 if (pattern_glob(pat, ev+1)) {
44 return true;
45 } else if (pattern_glob(pat+1, ev)) {
46 return true;
47 } else {
48 return false;
49 }
50 } else {
51 return false;
52 }
53 }
54
55 while (*pat == '*') {
56 pat++;
57 }
58
59 if (*pat == '\0' && *ev == '\0') {
60 return true;
61 } else {
62 return false;
63 }
64}
65
66TraceEvent *trace_event_pattern(const char *pat, TraceEvent *ev)
23d15e86 67{
b1bae816 68 assert(pat != NULL);
ddde8acc 69
b1bae816
LV
70 TraceEventID i;
71
72 if (ev == NULL) {
73 i = -1;
74 } else {
75 i = trace_event_get_id(ev);
76 }
77 i++;
78
79 while (i < trace_event_count()) {
80 TraceEvent *res = trace_event_id(i);
81 if (pattern_glob(pat, trace_event_get_name(res))) {
82 return res;
83 }
84 i++;
85 }
86
87 return NULL;
88}
89
5b808275 90static void trace_init_events(const char *fname)
b1bae816 91{
a35d9be6
AK
92 Location loc;
93 FILE *fp;
94 char line_buf[1024];
95 size_t line_idx = 0;
96
23d15e86
LV
97 if (fname == NULL) {
98 return;
99 }
100
a35d9be6
AK
101 loc_push_none(&loc);
102 loc_set_file(fname, 0);
103 fp = fopen(fname, "r");
23d15e86 104 if (!fp) {
a35d9be6 105 error_report("%s", strerror(errno));
23d15e86
LV
106 exit(1);
107 }
23d15e86 108 while (fgets(line_buf, sizeof(line_buf), fp)) {
a35d9be6 109 loc_set_file(fname, ++line_idx);
23d15e86
LV
110 size_t len = strlen(line_buf);
111 if (len > 1) { /* skip empty lines */
112 line_buf[len - 1] = '\0';
794b1f96
AK
113 if ('#' == line_buf[0]) { /* skip commented lines */
114 continue;
115 }
b1bae816
LV
116 const bool enable = ('-' != line_buf[0]);
117 char *line_ptr = enable ? line_buf : line_buf + 1;
118 if (trace_event_is_pattern(line_ptr)) {
119 TraceEvent *ev = NULL;
120 while ((ev = trace_event_pattern(line_ptr, ev)) != NULL) {
121 if (trace_event_get_state_static(ev)) {
122 trace_event_set_state_dynamic(ev, enable);
123 }
124 }
ddde8acc 125 } else {
b1bae816
LV
126 TraceEvent *ev = trace_event_name(line_ptr);
127 if (ev == NULL) {
a35d9be6
AK
128 error_report("WARNING: trace event '%s' does not exist",
129 line_ptr);
82432638 130 } else if (!trace_event_get_state_static(ev)) {
81b07353 131 error_report("WARNING: trace event '%s' is not traceable",
a35d9be6 132 line_ptr);
82432638
AK
133 } else {
134 trace_event_set_state_dynamic(ev, enable);
b1bae816 135 }
23d15e86
LV
136 }
137 }
138 }
139 if (fclose(fp) != 0) {
a35d9be6
AK
140 loc_set_file(fname, 0);
141 error_report("%s", strerror(errno));
23d15e86
LV
142 exit(1);
143 }
a35d9be6 144 loc_pop(&loc);
23d15e86 145}
5b808275
LV
146
147bool trace_init_backends(const char *events, const char *file)
148{
149#ifdef CONFIG_TRACE_SIMPLE
150 if (!st_init(file)) {
151 fprintf(stderr, "failed to initialize simple tracing backend.\n");
152 return false;
153 }
154#else
155 if (file) {
156 fprintf(stderr, "error: -trace file=...: "
157 "option not supported by the selected tracing backends\n");
158 return false;
159 }
160#endif
161
162#ifdef CONFIG_TRACE_FTRACE
163 if (!ftrace_init()) {
164 fprintf(stderr, "failed to initialize ftrace backend.\n");
165 return false;
166 }
167#endif
168
169 trace_init_events(events);
170 return true;
171}