mirror of https://github.com/xemu-project/xemu.git
Merge remote-tracking branch 'stefanha/tracing' into staging
This commit is contained in:
commit
143f6ffe9c
|
@ -26,14 +26,14 @@ for debugging, profiling, and observing execution.
|
|||
|
||||
== Trace events ==
|
||||
|
||||
There is a set of static trace events declared in the trace-events source
|
||||
There is a set of static trace events declared in the "trace-events" source
|
||||
file. Each trace event declaration names the event, its arguments, and the
|
||||
format string which can be used for pretty-printing:
|
||||
|
||||
qemu_malloc(size_t size, void *ptr) "size %zu ptr %p"
|
||||
qemu_free(void *ptr) "ptr %p"
|
||||
|
||||
The trace-events file is processed by the tracetool script during build to
|
||||
The "trace-events" file is processed by the "tracetool" script during build to
|
||||
generate code for the trace events. Trace events are invoked directly from
|
||||
source code like this:
|
||||
|
||||
|
@ -52,10 +52,10 @@ source code like this:
|
|||
|
||||
=== Declaring trace events ===
|
||||
|
||||
The tracetool script produces the trace.h header file which is included by
|
||||
The "tracetool" script produces the trace.h header file which is included by
|
||||
every source file that uses trace events. Since many source files include
|
||||
trace.h, it uses a minimum of types and other header files included to keep
|
||||
the namespace clean and compile times and dependencies down.
|
||||
trace.h, it uses a minimum of types and other header files included to keep the
|
||||
namespace clean and compile times and dependencies down.
|
||||
|
||||
Trace events should use types as follows:
|
||||
|
||||
|
@ -69,6 +69,11 @@ Trace events should use types as follows:
|
|||
cannot include all user-defined struct declarations and it is therefore
|
||||
necessary to use void * for pointers to structs.
|
||||
|
||||
Pointers (including char *) cannot be dereferenced easily (or at all) in
|
||||
some trace backends. If pointers are used, ensure they are meaningful by
|
||||
themselves and do not assume the data they point to will be traced. Do
|
||||
not pass in string arguments.
|
||||
|
||||
* For everything else, use primitive scalar types (char, int, long) with the
|
||||
appropriate signedness.
|
||||
|
||||
|
@ -105,10 +110,10 @@ portability macros, ensure they are preceded and followed by double quotes:
|
|||
|
||||
== Trace backends ==
|
||||
|
||||
The tracetool script automates tedious trace event code generation and also
|
||||
The "tracetool" script automates tedious trace event code generation and also
|
||||
keeps the trace event declarations independent of the trace backend. The trace
|
||||
events are not tightly coupled to a specific trace backend, such as LTTng or
|
||||
SystemTap. Support for trace backends can be added by extending the tracetool
|
||||
SystemTap. Support for trace backends can be added by extending the "tracetool"
|
||||
script.
|
||||
|
||||
The trace backend is chosen at configure time and only one trace backend can
|
||||
|
@ -176,12 +181,12 @@ events at runtime inside QEMU:
|
|||
==== Analyzing trace files ====
|
||||
|
||||
The "simple" backend produces binary trace files that can be formatted with the
|
||||
simpletrace.py script. The script takes the trace-events file and the binary
|
||||
simpletrace.py script. The script takes the "trace-events" file and the binary
|
||||
trace:
|
||||
|
||||
./simpletrace.py trace-events trace-12345
|
||||
|
||||
You must ensure that the same trace-events file was used to build QEMU,
|
||||
You must ensure that the same "trace-events" file was used to build QEMU,
|
||||
otherwise trace event declarations may have changed and output will not be
|
||||
consistent.
|
||||
|
||||
|
|
|
@ -133,7 +133,7 @@ grlib_apbuart_writel(void *opaque, target_phys_addr_t addr, uint32_t value)
|
|||
break;
|
||||
}
|
||||
|
||||
trace_grlib_apbuart_unknown_register("write", addr);
|
||||
trace_grlib_apbuart_writel_unknown(addr, value);
|
||||
}
|
||||
|
||||
static CPUReadMemoryFunc * const grlib_apbuart_read[] = {
|
||||
|
|
|
@ -165,15 +165,15 @@ static uint32_t grlib_gptimer_readl(void *opaque, target_phys_addr_t addr)
|
|||
/* Unit registers */
|
||||
switch (addr) {
|
||||
case SCALER_OFFSET:
|
||||
trace_grlib_gptimer_readl(-1, "scaler:", unit->scaler);
|
||||
trace_grlib_gptimer_readl(-1, addr, unit->scaler);
|
||||
return unit->scaler;
|
||||
|
||||
case SCALER_RELOAD_OFFSET:
|
||||
trace_grlib_gptimer_readl(-1, "reload:", unit->reload);
|
||||
trace_grlib_gptimer_readl(-1, addr, unit->reload);
|
||||
return unit->reload;
|
||||
|
||||
case CONFIG_OFFSET:
|
||||
trace_grlib_gptimer_readl(-1, "config:", unit->config);
|
||||
trace_grlib_gptimer_readl(-1, addr, unit->config);
|
||||
return unit->config;
|
||||
|
||||
default:
|
||||
|
@ -189,17 +189,16 @@ static uint32_t grlib_gptimer_readl(void *opaque, target_phys_addr_t addr)
|
|||
switch (timer_addr) {
|
||||
case COUNTER_OFFSET:
|
||||
value = ptimer_get_count(unit->timers[id].ptimer);
|
||||
trace_grlib_gptimer_readl(id, "counter value:", value);
|
||||
trace_grlib_gptimer_readl(id, addr, value);
|
||||
return value;
|
||||
|
||||
case COUNTER_RELOAD_OFFSET:
|
||||
value = unit->timers[id].reload;
|
||||
trace_grlib_gptimer_readl(id, "reload value:", value);
|
||||
trace_grlib_gptimer_readl(id, addr, value);
|
||||
return value;
|
||||
|
||||
case CONFIG_OFFSET:
|
||||
trace_grlib_gptimer_readl(id, "scaler value:",
|
||||
unit->timers[id].config);
|
||||
trace_grlib_gptimer_readl(id, addr, unit->timers[id].config);
|
||||
return unit->timers[id].config;
|
||||
|
||||
default:
|
||||
|
@ -208,7 +207,7 @@ static uint32_t grlib_gptimer_readl(void *opaque, target_phys_addr_t addr)
|
|||
|
||||
}
|
||||
|
||||
trace_grlib_gptimer_unknown_register("read", addr);
|
||||
trace_grlib_gptimer_readl(-1, addr, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -226,19 +225,19 @@ grlib_gptimer_writel(void *opaque, target_phys_addr_t addr, uint32_t value)
|
|||
case SCALER_OFFSET:
|
||||
value &= 0xFFFF; /* clean up the value */
|
||||
unit->scaler = value;
|
||||
trace_grlib_gptimer_writel(-1, "scaler:", unit->scaler);
|
||||
trace_grlib_gptimer_writel(-1, addr, unit->scaler);
|
||||
return;
|
||||
|
||||
case SCALER_RELOAD_OFFSET:
|
||||
value &= 0xFFFF; /* clean up the value */
|
||||
unit->reload = value;
|
||||
trace_grlib_gptimer_writel(-1, "reload:", unit->reload);
|
||||
trace_grlib_gptimer_writel(-1, addr, unit->reload);
|
||||
grlib_gptimer_set_scaler(unit, value);
|
||||
return;
|
||||
|
||||
case CONFIG_OFFSET:
|
||||
/* Read Only (disable timer freeze not supported) */
|
||||
trace_grlib_gptimer_writel(-1, "config (Read Only):", 0);
|
||||
trace_grlib_gptimer_writel(-1, addr, 0);
|
||||
return;
|
||||
|
||||
default:
|
||||
|
@ -253,18 +252,18 @@ grlib_gptimer_writel(void *opaque, target_phys_addr_t addr, uint32_t value)
|
|||
/* GPTimer registers */
|
||||
switch (timer_addr) {
|
||||
case COUNTER_OFFSET:
|
||||
trace_grlib_gptimer_writel(id, "counter:", value);
|
||||
trace_grlib_gptimer_writel(id, addr, value);
|
||||
unit->timers[id].counter = value;
|
||||
grlib_gptimer_enable(&unit->timers[id]);
|
||||
return;
|
||||
|
||||
case COUNTER_RELOAD_OFFSET:
|
||||
trace_grlib_gptimer_writel(id, "reload:", value);
|
||||
trace_grlib_gptimer_writel(id, addr, value);
|
||||
unit->timers[id].reload = value;
|
||||
return;
|
||||
|
||||
case CONFIG_OFFSET:
|
||||
trace_grlib_gptimer_writel(id, "config:", value);
|
||||
trace_grlib_gptimer_writel(id, addr, value);
|
||||
|
||||
if (value & GPTIMER_INT_PENDING) {
|
||||
/* clear pending bit */
|
||||
|
@ -297,7 +296,7 @@ grlib_gptimer_writel(void *opaque, target_phys_addr_t addr, uint32_t value)
|
|||
|
||||
}
|
||||
|
||||
trace_grlib_gptimer_unknown_register("write", addr);
|
||||
trace_grlib_gptimer_writel(-1, addr, value);
|
||||
}
|
||||
|
||||
static CPUReadMemoryFunc * const grlib_gptimer_read[] = {
|
||||
|
|
|
@ -220,7 +220,7 @@ static uint32_t grlib_irqmp_readl(void *opaque, target_phys_addr_t addr)
|
|||
return state->extended[cpu];
|
||||
}
|
||||
|
||||
trace_grlib_irqmp_unknown_register("read", addr);
|
||||
trace_grlib_irqmp_readl_unknown(addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -308,7 +308,7 @@ grlib_irqmp_writel(void *opaque, target_phys_addr_t addr, uint32_t value)
|
|||
return;
|
||||
}
|
||||
|
||||
trace_grlib_irqmp_unknown_register("write", addr);
|
||||
trace_grlib_irqmp_writel_unknown(addr, value);
|
||||
}
|
||||
|
||||
static CPUReadMemoryFunc * const grlib_irqmp_read[] = {
|
||||
|
|
|
@ -51,7 +51,7 @@ get_args()
|
|||
{
|
||||
local args
|
||||
args=${1#*\(}
|
||||
args=${args%\)*}
|
||||
args=${args%%\)*}
|
||||
echo "$args"
|
||||
}
|
||||
|
||||
|
@ -338,6 +338,7 @@ linetoc_ust()
|
|||
name=$(get_name "$1")
|
||||
args=$(get_args "$1")
|
||||
argnames=$(get_argnames "$1", ",")
|
||||
[ -z "$argnames" ] || argnames=", $argnames"
|
||||
fmt=$(get_fmt "$1")
|
||||
|
||||
cat <<EOF
|
||||
|
@ -345,7 +346,7 @@ DEFINE_TRACE(ust_$name);
|
|||
|
||||
static void ust_${name}_probe($args)
|
||||
{
|
||||
trace_mark(ust, $name, "$fmt", $argnames);
|
||||
trace_mark(ust, $name, "$fmt"$argnames);
|
||||
}
|
||||
EOF
|
||||
|
||||
|
@ -488,7 +489,7 @@ EOF
|
|||
cat <<EOF
|
||||
$arg = \$arg$i;
|
||||
EOF
|
||||
i="$((i+1))"
|
||||
i="$((i+1))"
|
||||
done
|
||||
|
||||
cat <<EOF
|
||||
|
@ -585,7 +586,7 @@ tracetostap()
|
|||
exit 1
|
||||
fi
|
||||
if [ -z "$probeprefix" ]; then
|
||||
probeprefix="qemu.$targettype.$targetarch";
|
||||
probeprefix="qemu.$targettype.$targetarch";
|
||||
fi
|
||||
echo "/* This file is autogenerated by tracetool, do not edit. */"
|
||||
convert stap
|
||||
|
|
14
trace-events
14
trace-events
|
@ -235,27 +235,27 @@ disable grlib_gptimer_disabled(int id, uint32_t config) "timer:%d Timer disable
|
|||
disable grlib_gptimer_restart(int id, uint32_t reload) "timer:%d reload val: 0x%x"
|
||||
disable grlib_gptimer_set_scaler(uint32_t scaler, uint32_t freq) "scaler:0x%x freq: 0x%x"
|
||||
disable grlib_gptimer_hit(int id) "timer:%d HIT"
|
||||
disable grlib_gptimer_readl(int id, const char *s, uint32_t val) "timer:%d %s 0x%x"
|
||||
disable grlib_gptimer_writel(int id, const char *s, uint32_t val) "timer:%d %s 0x%x"
|
||||
disable grlib_gptimer_unknown_register(const char *op, uint64_t val) "%s unknown register 0x%"PRIx64""
|
||||
disable grlib_gptimer_readl(int id, uint64_t addr, uint32_t val) "timer:%d addr 0x%"PRIx64" 0x%x"
|
||||
disable grlib_gptimer_writel(int id, uint64_t addr, uint32_t val) "timer:%d addr 0x%"PRIx64" 0x%x"
|
||||
|
||||
# hw/grlib_irqmp.c
|
||||
disable grlib_irqmp_check_irqs(uint32_t pend, uint32_t force, uint32_t mask, uint32_t lvl1, uint32_t lvl2) "pend:0x%04x force:0x%04x mask:0x%04x lvl1:0x%04x lvl0:0x%04x\n"
|
||||
disable grlib_irqmp_ack(int intno) "interrupt:%d"
|
||||
disable grlib_irqmp_set_irq(int irq) "Raise CPU IRQ %d"
|
||||
disable grlib_irqmp_unknown_register(const char *op, uint64_t val) "%s unknown register 0x%"PRIx64""
|
||||
disable grlib_irqmp_readl_unknown(uint64_t addr) "addr 0x%"PRIx64""
|
||||
disable grlib_irqmp_writel_unknown(uint64_t addr, uint32_t value) "addr 0x%"PRIx64" value 0x%x"
|
||||
|
||||
# hw/grlib_apbuart.c
|
||||
disable grlib_apbuart_event(int event) "event:%d"
|
||||
disable grlib_apbuart_unknown_register(const char *op, uint64_t val) "%s unknown register 0x%"PRIx64""
|
||||
disable grlib_apbuart_writel_unknown(uint64_t addr, uint32_t value) "addr 0x%"PRIx64" value 0x%x"
|
||||
|
||||
# hw/leon3.c
|
||||
disable leon3_set_irq(int intno) "Set CPU IRQ %d"
|
||||
disable leon3_reset_irq(int intno) "Reset CPU IRQ %d"
|
||||
|
||||
# spice-qemu-char.c
|
||||
disable spice_vmc_write(ssize_t out, int len) "spice wrottn %lu of requested %zd"
|
||||
disable spice_vmc_read(int bytes, int len) "spice read %lu of requested %zd"
|
||||
disable spice_vmc_write(ssize_t out, int len) "spice wrottn %zd of requested %d"
|
||||
disable spice_vmc_read(int bytes, int len) "spice read %d of requested %d"
|
||||
disable spice_vmc_register_interface(void *scd) "spice vmc registered interface %p"
|
||||
disable spice_vmc_unregister_interface(void *scd) "spice vmc unregistered interface %p"
|
||||
|
||||
|
|
Loading…
Reference in New Issue