Revision 22890ab5
b/configure | ||
---|---|---|
2468 | 2468 |
esac |
2469 | 2469 |
|
2470 | 2470 |
echo "TRACE_BACKEND=$trace_backend" >> $config_host_mak |
2471 |
if test "$trace_backend" = "simple"; then |
|
2472 |
echo "CONFIG_SIMPLE_TRACE=y" >> $config_host_mak |
|
2473 |
fi |
|
2471 | 2474 |
echo "TOOLS=$tools" >> $config_host_mak |
2472 | 2475 |
echo "ROMS=$roms" >> $config_host_mak |
2473 | 2476 |
echo "MAKE=$make" >> $config_host_mak |
b/monitor.c | ||
---|---|---|
56 | 56 |
#include "json-parser.h" |
57 | 57 |
#include "osdep.h" |
58 | 58 |
#include "exec-all.h" |
59 |
#ifdef CONFIG_SIMPLE_TRACE |
|
60 |
#include "trace.h" |
|
61 |
#endif |
|
59 | 62 |
|
60 | 63 |
//#define DEBUG |
61 | 64 |
//#define DEBUG_COMPLETION |
... | ... | |
539 | 542 |
help_cmd(mon, qdict_get_try_str(qdict, "name")); |
540 | 543 |
} |
541 | 544 |
|
545 |
#ifdef CONFIG_SIMPLE_TRACE |
|
546 |
static void do_change_trace_event_state(Monitor *mon, const QDict *qdict) |
|
547 |
{ |
|
548 |
const char *tp_name = qdict_get_str(qdict, "name"); |
|
549 |
bool new_state = qdict_get_bool(qdict, "option"); |
|
550 |
st_change_trace_event_state(tp_name, new_state); |
|
551 |
} |
|
552 |
#endif |
|
553 |
|
|
542 | 554 |
static void user_monitor_complete(void *opaque, QObject *ret_data) |
543 | 555 |
{ |
544 | 556 |
MonitorCompletionData *data = (MonitorCompletionData *)opaque; |
... | ... | |
938 | 950 |
} |
939 | 951 |
#endif |
940 | 952 |
|
953 |
#if defined(CONFIG_SIMPLE_TRACE) |
|
954 |
static void do_info_trace(Monitor *mon) |
|
955 |
{ |
|
956 |
st_print_trace((FILE *)mon, &monitor_fprintf); |
|
957 |
} |
|
958 |
|
|
959 |
static void do_info_trace_events(Monitor *mon) |
|
960 |
{ |
|
961 |
st_print_trace_events((FILE *)mon, &monitor_fprintf); |
|
962 |
} |
|
963 |
#endif |
|
964 |
|
|
941 | 965 |
/** |
942 | 966 |
* do_quit(): Quit QEMU execution |
943 | 967 |
*/ |
... | ... | |
2594 | 2618 |
.help = "show roms", |
2595 | 2619 |
.mhandler.info = do_info_roms, |
2596 | 2620 |
}, |
2621 |
#if defined(CONFIG_SIMPLE_TRACE) |
|
2622 |
{ |
|
2623 |
.name = "trace", |
|
2624 |
.args_type = "", |
|
2625 |
.params = "", |
|
2626 |
.help = "show current contents of trace buffer", |
|
2627 |
.mhandler.info = do_info_trace, |
|
2628 |
}, |
|
2629 |
{ |
|
2630 |
.name = "trace-events", |
|
2631 |
.args_type = "", |
|
2632 |
.params = "", |
|
2633 |
.help = "show available trace-events & their state", |
|
2634 |
.mhandler.info = do_info_trace_events, |
|
2635 |
}, |
|
2636 |
#endif |
|
2597 | 2637 |
{ |
2598 | 2638 |
.name = NULL, |
2599 | 2639 |
}, |
b/qemu-monitor.hx | ||
---|---|---|
281 | 281 |
Output logs to @var{filename}. |
282 | 282 |
ETEXI |
283 | 283 |
|
284 |
#ifdef CONFIG_SIMPLE_TRACE |
|
285 |
{ |
|
286 |
.name = "trace-event", |
|
287 |
.args_type = "name:s,option:b", |
|
288 |
.params = "name on|off", |
|
289 |
.help = "changes status of a specific trace event", |
|
290 |
.mhandler.cmd = do_change_trace_event_state, |
|
291 |
}, |
|
292 |
|
|
293 |
STEXI |
|
294 |
@item trace-event |
|
295 |
@findex trace-event |
|
296 |
changes status of a trace event |
|
297 |
ETEXI |
|
298 |
#endif |
|
299 |
|
|
284 | 300 |
{ |
285 | 301 |
.name = "log", |
286 | 302 |
.args_type = "items:s", |
... | ... | |
2529 | 2545 |
@end table |
2530 | 2546 |
ETEXI |
2531 | 2547 |
|
2548 |
#ifdef CONFIG_SIMPLE_TRACE |
|
2549 |
STEXI |
|
2550 |
@item info trace |
|
2551 |
show contents of trace buffer |
|
2552 |
@item info trace-events |
|
2553 |
show available trace events and their state |
|
2554 |
ETEXI |
|
2555 |
#endif |
|
2556 |
|
|
2532 | 2557 |
HXCOMM DO NOT add new commands after 'info', move your addition before it! |
2533 | 2558 |
|
2534 | 2559 |
STEXI |
b/simpletrace.c | ||
---|---|---|
101 | 101 |
*/ |
102 | 102 |
clock_gettime(CLOCK_MONOTONIC, &ts); |
103 | 103 |
|
104 |
if (!trace_list[event].state) { |
|
105 |
return; |
|
106 |
} |
|
107 |
|
|
104 | 108 |
rec->event = event; |
105 | 109 |
rec->timestamp_ns = ts.tv_sec * 1000000000LL + ts.tv_nsec; |
106 | 110 |
rec->x1 = x1; |
... | ... | |
157 | 161 |
{ |
158 | 162 |
atexit(st_flush_trace_buffer); |
159 | 163 |
} |
164 |
|
|
165 |
void st_print_trace(FILE *stream, int (*stream_printf)(FILE *stream, const char *fmt, ...)) |
|
166 |
{ |
|
167 |
unsigned int i; |
|
168 |
|
|
169 |
for (i = 0; i < trace_idx; i++) { |
|
170 |
stream_printf(stream, "Event %lu : %lx %lx %lx %lx %lx\n", |
|
171 |
trace_buf[i].event, trace_buf[i].x1, trace_buf[i].x2, |
|
172 |
trace_buf[i].x3, trace_buf[i].x4, trace_buf[i].x5); |
|
173 |
} |
|
174 |
} |
|
175 |
|
|
176 |
void st_print_trace_events(FILE *stream, int (*stream_printf)(FILE *stream, const char *fmt, ...)) |
|
177 |
{ |
|
178 |
unsigned int i; |
|
179 |
|
|
180 |
for (i = 0; i < NR_TRACE_EVENTS; i++) { |
|
181 |
stream_printf(stream, "%s [Event ID %u] : state %u\n", |
|
182 |
trace_list[i].tp_name, i, trace_list[i].state); |
|
183 |
} |
|
184 |
} |
|
185 |
|
|
186 |
static TraceEvent* find_trace_event_by_name(const char *tname) |
|
187 |
{ |
|
188 |
unsigned int i; |
|
189 |
|
|
190 |
if (!tname) { |
|
191 |
return NULL; |
|
192 |
} |
|
193 |
|
|
194 |
for (i = 0; i < NR_TRACE_EVENTS; i++) { |
|
195 |
if (!strcmp(trace_list[i].tp_name, tname)) { |
|
196 |
return &trace_list[i]; |
|
197 |
} |
|
198 |
} |
|
199 |
return NULL; /* indicates end of list reached without a match */ |
|
200 |
} |
|
201 |
|
|
202 |
void st_change_trace_event_state(const char *tname, bool tstate) |
|
203 |
{ |
|
204 |
TraceEvent *tp; |
|
205 |
|
|
206 |
tp = find_trace_event_by_name(tname); |
|
207 |
if (tp) { |
|
208 |
tp->state = tstate; |
|
209 |
} |
|
210 |
} |
b/simpletrace.h | ||
---|---|---|
12 | 12 |
#define SIMPLETRACE_H |
13 | 13 |
|
14 | 14 |
#include <stdint.h> |
15 |
#include <stdbool.h> |
|
16 |
#include <stdio.h> |
|
15 | 17 |
|
16 | 18 |
typedef uint64_t TraceEventID; |
17 | 19 |
|
20 |
typedef struct { |
|
21 |
const char *tp_name; |
|
22 |
bool state; |
|
23 |
} TraceEvent; |
|
24 |
|
|
18 | 25 |
void trace0(TraceEventID event); |
19 | 26 |
void trace1(TraceEventID event, uint64_t x1); |
20 | 27 |
void trace2(TraceEventID event, uint64_t x1, uint64_t x2); |
... | ... | |
22 | 29 |
void trace4(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4); |
23 | 30 |
void trace5(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5); |
24 | 31 |
void trace6(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5, uint64_t x6); |
32 |
void st_print_trace(FILE *stream, int (*stream_printf)(FILE *stream, const char *fmt, ...)); |
|
33 |
void st_print_trace_events(FILE *stream, int (*stream_printf)(FILE *stream, const char *fmt, ...)); |
|
34 |
void st_change_trace_event_state(const char *tname, bool tstate); |
|
25 | 35 |
|
26 | 36 |
#endif /* SIMPLETRACE_H */ |
b/tracetool | ||
---|---|---|
169 | 169 |
|
170 | 170 |
linetoh_end_simple() |
171 | 171 |
{ |
172 |
return |
|
172 |
cat <<EOF |
|
173 |
#define NR_TRACE_EVENTS $simple_event_num |
|
174 |
extern TraceEvent trace_list[NR_TRACE_EVENTS]; |
|
175 |
EOF |
|
173 | 176 |
} |
174 | 177 |
|
175 | 178 |
linetoc_begin_simple() |
176 | 179 |
{ |
177 |
return |
|
180 |
cat <<EOF |
|
181 |
#include "trace.h" |
|
182 |
|
|
183 |
TraceEvent trace_list[] = { |
|
184 |
EOF |
|
185 |
simple_event_num=0 |
|
186 |
|
|
178 | 187 |
} |
179 | 188 |
|
180 | 189 |
linetoc_simple() |
181 | 190 |
{ |
182 |
return |
|
191 |
local name |
|
192 |
name=$(get_name "$1") |
|
193 |
cat <<EOF |
|
194 |
{.tp_name = "$name", .state=0}, |
|
195 |
EOF |
|
196 |
simple_event_num=$((simple_event_num + 1)) |
|
183 | 197 |
} |
184 | 198 |
|
185 | 199 |
linetoc_end_simple() |
186 | 200 |
{ |
187 |
return |
|
201 |
cat <<EOF |
|
202 |
}; |
|
203 |
EOF |
|
188 | 204 |
} |
189 | 205 |
|
190 | 206 |
# Process stdin by calling begin, line, and end functions for the backend |
Also available in: Unified diff