* [Qemu-devel] [PULL v2 0/5] Tracing pull request @ 2014-06-09 15:23 Stefan Hajnoczi 2014-06-09 15:23 ` [Qemu-devel] [PULL 1/5] trace: add pid field to simpletrace record Stefan Hajnoczi ` (5 more replies) 0 siblings, 6 replies; 9+ messages in thread From: Stefan Hajnoczi @ 2014-06-09 15:23 UTC (permalink / raw) To: qemu-devel; +Cc: Peter Maydell, Stefan Hajnoczi v2: * Previous version was interleaved with an older pull request and the email thread was a mess. Resending. The following changes since commit 959e41473f2179850578482052fb73b913bc4e42: slirp/arp: do not special-case bogus IP addresses (2014-06-09 01:49:28 +0200) are available in the git repository at: git://github.com/stefanha/qemu.git tags/tracing-pull-request for you to fetch changes up to a35d9be622a85d9ad6be5448e78c8a3f95ee5f00: trace: Replace fprintf with error_report and print location (2014-06-09 15:43:40 +0200) ---------------------------------------------------------------- Tracing pull request ---------------------------------------------------------------- Alexey Kardashevskiy (2): trace: Replace error with warning if event is not defined trace: Replace fprintf with error_report and print location Lluís Vilanova (1): trace: Multi-backend tracing Stefan Hajnoczi (2): trace: add pid field to simpletrace record simpletrace: add support for trace record pid field .travis.yml | 8 ++-- Makefile | 4 +- Makefile.target | 4 +- configure | 47 ++++++++++--------- docs/tracing.txt | 4 +- qemu-io.c | 2 +- scripts/simpletrace.py | 26 ++++++----- scripts/tracetool.py | 43 +++++++++--------- scripts/tracetool/__init__.py | 24 +++++----- scripts/tracetool/backend/__init__.py | 15 +++--- trace/Makefile.objs | 32 ++++++------- trace/control-internal.h | 4 +- trace/control.c | 86 +++++++++++++++++++++++++++-------- trace/control.h | 27 ++--------- trace/default.c | 40 ---------------- trace/ftrace.c | 25 +--------- trace/ftrace.h | 5 ++ trace/simple.c | 27 +++-------- trace/simple.h | 1 + trace/stderr.c | 30 ------------ vl.c | 4 +- 21 files changed, 195 insertions(+), 263 deletions(-) delete mode 100644 trace/default.c delete mode 100644 trace/stderr.c -- 1.9.3 ^ permalink raw reply [flat|nested] 9+ messages in thread
* [Qemu-devel] [PULL 1/5] trace: add pid field to simpletrace record 2014-06-09 15:23 [Qemu-devel] [PULL v2 0/5] Tracing pull request Stefan Hajnoczi @ 2014-06-09 15:23 ` Stefan Hajnoczi 2014-06-09 15:23 ` [Qemu-devel] [PULL 2/5] simpletrace: add support for trace record pid field Stefan Hajnoczi ` (4 subsequent siblings) 5 siblings, 0 replies; 9+ messages in thread From: Stefan Hajnoczi @ 2014-06-09 15:23 UTC (permalink / raw) To: qemu-devel; +Cc: Peter Maydell, Stefan Hajnoczi It is useful to know the QEMU process ID when working with traces from multiple VMs. Although the trace filename may contain the pid, tools that aggregate traces or even trace globally need somewhere to record the pid. There is a reserved field in the trace event header struct that we can use. It is not necessary to bump the simpletrace file format version number because it has already been incremented for the QEMU 2.1 release cycle in commit "trace: [simple] Bump up log version number". Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> --- trace/simple.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/trace/simple.c b/trace/simple.c index bb0b52c..5a2e188 100644 --- a/trace/simple.c +++ b/trace/simple.c @@ -75,6 +75,7 @@ uint8_t trace_buf[TRACE_BUF_LEN]; static volatile gint trace_idx; static unsigned int writeout_idx; static volatile gint dropped_events; +static uint32_t trace_pid; static FILE *trace_fp; static char *trace_file_name; @@ -83,7 +84,7 @@ typedef struct { uint64_t event; /* TraceEventID */ uint64_t timestamp_ns; uint32_t length; /* in bytes */ - uint32_t reserved; /* unused */ + uint32_t pid; uint64_t arguments[]; } TraceRecord; @@ -190,7 +191,7 @@ static gpointer writeout_thread(gpointer opaque) dropped.rec.event = DROPPED_EVENT_ID, dropped.rec.timestamp_ns = get_clock(); dropped.rec.length = sizeof(TraceRecord) + sizeof(uint64_t), - dropped.rec.reserved = 0; + dropped.rec.pid = trace_pid; do { dropped_count = g_atomic_int_get(&dropped_events); } while (!g_atomic_int_compare_and_exchange(&dropped_events, @@ -249,6 +250,7 @@ int trace_record_start(TraceBufferRecord *rec, TraceEventID event, size_t datasi rec_off = write_to_buffer(rec_off, &event_u64, sizeof(event_u64)); rec_off = write_to_buffer(rec_off, ×tamp_ns, sizeof(timestamp_ns)); rec_off = write_to_buffer(rec_off, &rec_len, sizeof(rec_len)); + rec_off = write_to_buffer(rec_off, &trace_pid, sizeof(trace_pid)); rec->tbuf_idx = idx; rec->rec_off = (idx + sizeof(TraceRecord)) % TRACE_BUF_LEN; @@ -414,6 +416,8 @@ bool trace_backend_init(const char *events, const char *file) { GThread *thread; + trace_pid = getpid(); + #if !GLIB_CHECK_VERSION(2, 31, 0) trace_available_cond = g_cond_new(); trace_empty_cond = g_cond_new(); -- 1.9.3 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Qemu-devel] [PULL 2/5] simpletrace: add support for trace record pid field 2014-06-09 15:23 [Qemu-devel] [PULL v2 0/5] Tracing pull request Stefan Hajnoczi 2014-06-09 15:23 ` [Qemu-devel] [PULL 1/5] trace: add pid field to simpletrace record Stefan Hajnoczi @ 2014-06-09 15:23 ` Stefan Hajnoczi 2014-06-09 15:23 ` [Qemu-devel] [PULL 3/5] trace: Replace error with warning if event is not defined Stefan Hajnoczi ` (3 subsequent siblings) 5 siblings, 0 replies; 9+ messages in thread From: Stefan Hajnoczi @ 2014-06-09 15:23 UTC (permalink / raw) To: qemu-devel; +Cc: Peter Maydell, Stefan Hajnoczi Extract the pid field from the trace record and print it. Change the trace record tuple from: (event_num, timestamp, arg1, ..., arg6) to: (event_num, timestamp, pid, arg1, ..., arg6) Trace event methods now support 3 prototypes: 1. <event-name>(arg1, arg2, arg3) 2. <event-name>(timestamp, arg1, arg2, arg3) 3. <event-name>(timestamp, pid, arg1, arg2, arg3) Existing script continue to work without changes, they only know about prototypes 1 and 2. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> --- scripts/simpletrace.py | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/scripts/simpletrace.py b/scripts/simpletrace.py index 800835a..1aa9460 100755 --- a/scripts/simpletrace.py +++ b/scripts/simpletrace.py @@ -31,10 +31,10 @@ def read_header(fobj, hfmt): return struct.unpack(hfmt, hdr) def get_record(edict, rechdr, fobj): - """Deserialize a trace record from a file into a tuple (event_num, timestamp, arg1, ..., arg6).""" + """Deserialize a trace record from a file into a tuple (event_num, timestamp, pid, arg1, ..., arg6).""" if rechdr is None: return None - rec = (rechdr[0], rechdr[1]) + rec = (rechdr[0], rechdr[1], rechdr[3]) if rechdr[0] != dropped_event_id: event_id = rechdr[0] event = edict[event_id] @@ -54,12 +54,12 @@ def get_record(edict, rechdr, fobj): def read_record(edict, fobj): - """Deserialize a trace record from a file into a tuple (event_num, timestamp, arg1, ..., arg6).""" + """Deserialize a trace record from a file into a tuple (event_num, timestamp, pid, arg1, ..., arg6).""" rechdr = read_header(fobj, rec_header_fmt) return get_record(edict, rechdr, fobj) # return tuple of record elements def read_trace_file(edict, fobj): - """Deserialize trace records from a file, yielding record tuples (event_num, timestamp, arg1, ..., arg6).""" + """Deserialize trace records from a file, yielding record tuples (event_num, timestamp, pid, arg1, ..., arg6).""" header = read_header(fobj, log_header_fmt) if header is None or \ header[0] != header_event_id or \ @@ -127,10 +127,13 @@ def process(events, log, analyzer): fn_argcount = len(inspect.getargspec(fn)[0]) - 1 if fn_argcount == event_argcount + 1: # Include timestamp as first argument - return lambda _, rec: fn(*rec[1:2 + event_argcount]) + return lambda _, rec: fn(*((rec[1:2],) + rec[3:3 + event_argcount])) + elif fn_argcount == event_argcount + 2: + # Include timestamp and pid + return lambda _, rec: fn(*rec[1:3 + event_argcount]) else: - # Just arguments, no timestamp - return lambda _, rec: fn(*rec[2:2 + event_argcount]) + # Just arguments, no timestamp or pid + return lambda _, rec: fn(*rec[3:3 + event_argcount]) analyzer.begin() fn_cache = {} @@ -162,19 +165,20 @@ if __name__ == '__main__': self.last_timestamp = None def catchall(self, event, rec): - i = 1 timestamp = rec[1] if self.last_timestamp is None: self.last_timestamp = timestamp delta_ns = timestamp - self.last_timestamp self.last_timestamp = timestamp - fields = [event.name, '%0.3f' % (delta_ns / 1000.0)] + fields = [event.name, '%0.3f' % (delta_ns / 1000.0), + 'pid=%d' % rec[2]] + i = 3 for type, name in event.args: if is_string(type): - fields.append('%s=%s' % (name, rec[i + 1])) + fields.append('%s=%s' % (name, rec[i])) else: - fields.append('%s=0x%x' % (name, rec[i + 1])) + fields.append('%s=0x%x' % (name, rec[i])) i += 1 print ' '.join(fields) -- 1.9.3 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Qemu-devel] [PULL 3/5] trace: Replace error with warning if event is not defined 2014-06-09 15:23 [Qemu-devel] [PULL v2 0/5] Tracing pull request Stefan Hajnoczi 2014-06-09 15:23 ` [Qemu-devel] [PULL 1/5] trace: add pid field to simpletrace record Stefan Hajnoczi 2014-06-09 15:23 ` [Qemu-devel] [PULL 2/5] simpletrace: add support for trace record pid field Stefan Hajnoczi @ 2014-06-09 15:23 ` Stefan Hajnoczi 2014-06-09 15:23 ` [Qemu-devel] [PULL 4/5] trace: Multi-backend tracing Stefan Hajnoczi ` (2 subsequent siblings) 5 siblings, 0 replies; 9+ messages in thread From: Stefan Hajnoczi @ 2014-06-09 15:23 UTC (permalink / raw) To: qemu-devel; +Cc: Alexey Kardashevskiy, Peter Maydell, Stefan Hajnoczi From: Alexey Kardashevskiy <aik@ozlabs.ru> At the moment QEMU exits if trace point is not defined which makes a developer life harder if he has to switch between branches with different traces implemented. This replaces error+exit wit WARNING if the tracepoint does not exist or not traceable. Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> --- trace/control.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/trace/control.c b/trace/control.c index 49f61e1..4aa02cf 100644 --- a/trace/control.c +++ b/trace/control.c @@ -112,15 +112,15 @@ void trace_backend_init_events(const char *fname) TraceEvent *ev = trace_event_name(line_ptr); if (ev == NULL) { fprintf(stderr, - "error: trace event '%s' does not exist\n", line_ptr); - exit(1); - } - if (!trace_event_get_state_static(ev)) { + "WARNING: trace event '%s' does not exist\n", + line_ptr); + } else if (!trace_event_get_state_static(ev)) { fprintf(stderr, - "error: trace event '%s' is not traceable\n", line_ptr); - exit(1); + "WARNING: trace event '%s' is not traceable\n", + line_ptr); + } else { + trace_event_set_state_dynamic(ev, enable); } - trace_event_set_state_dynamic(ev, enable); } } } -- 1.9.3 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Qemu-devel] [PULL 4/5] trace: Multi-backend tracing 2014-06-09 15:23 [Qemu-devel] [PULL v2 0/5] Tracing pull request Stefan Hajnoczi ` (2 preceding siblings ...) 2014-06-09 15:23 ` [Qemu-devel] [PULL 3/5] trace: Replace error with warning if event is not defined Stefan Hajnoczi @ 2014-06-09 15:23 ` Stefan Hajnoczi 2014-06-16 9:58 ` Peter Maydell 2014-06-09 15:23 ` [Qemu-devel] [PULL 5/5] trace: Replace fprintf with error_report and print location Stefan Hajnoczi 2014-06-09 16:03 ` [Qemu-devel] [PULL v2 0/5] Tracing pull request Peter Maydell 5 siblings, 1 reply; 9+ messages in thread From: Stefan Hajnoczi @ 2014-06-09 15:23 UTC (permalink / raw) To: qemu-devel; +Cc: Peter Maydell, Lluís Vilanova, Stefan Hajnoczi From: Lluís Vilanova <vilanova@ac.upc.edu> Adds support to compile QEMU with multiple tracing backends at the same time. For example, you can compile QEMU with: $ ./configure --enable-trace-backends=ftrace,dtrace Where 'ftrace' can be handy for having an in-flight record of events, and 'dtrace' can be later used to extract more information from the system. This patch allows having both available without recompiling QEMU. Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> --- .travis.yml | 8 +++--- Makefile | 4 +-- Makefile.target | 4 +-- configure | 47 ++++++++++++++++----------------- docs/tracing.txt | 4 +-- qemu-io.c | 2 +- scripts/tracetool.py | 43 +++++++++++++++--------------- scripts/tracetool/__init__.py | 24 ++++++++--------- scripts/tracetool/backend/__init__.py | 15 ++++++----- trace/Makefile.objs | 32 +++++++++++------------ trace/control-internal.h | 4 +-- trace/control.c | 49 +++++++++++++++++++++++++++++++++-- trace/control.h | 27 +++---------------- trace/default.c | 40 ---------------------------- trace/ftrace.c | 25 +----------------- trace/ftrace.h | 5 ++++ trace/simple.c | 19 +------------- trace/simple.h | 1 + trace/stderr.c | 30 --------------------- vl.c | 4 +-- 20 files changed, 153 insertions(+), 234 deletions(-) delete mode 100644 trace/default.c delete mode 100644 trace/stderr.c diff --git a/.travis.yml b/.travis.yml index 04da973..89c30ae 100644 --- a/.travis.yml +++ b/.travis.yml @@ -66,16 +66,16 @@ matrix: compiler: gcc # All the trace backends (apart from dtrace) - env: TARGETS=i386-softmmu,x86_64-softmmu - EXTRA_CONFIG="--enable-trace-backend=stderr" + EXTRA_CONFIG="--enable-trace-backends=stderr" compiler: gcc - env: TARGETS=i386-softmmu,x86_64-softmmu - EXTRA_CONFIG="--enable-trace-backend=simple" + EXTRA_CONFIG="--enable-trace-backends=simple" compiler: gcc - env: TARGETS=i386-softmmu,x86_64-softmmu - EXTRA_CONFIG="--enable-trace-backend=ftrace" + EXTRA_CONFIG="--enable-trace-backends=ftrace" TEST_CMD="" compiler: gcc - env: TARGETS=i386-softmmu,x86_64-softmmu EXTRA_PKGS="liblttng-ust-dev liburcu-dev" - EXTRA_CONFIG="--enable-trace-backend=ust" + EXTRA_CONFIG="--enable-trace-backends=ust" compiler: gcc diff --git a/Makefile b/Makefile index d830483..3c8f19c 100644 --- a/Makefile +++ b/Makefile @@ -52,12 +52,12 @@ GENERATED_HEADERS += trace/generated-events.h GENERATED_SOURCES += trace/generated-events.c GENERATED_HEADERS += trace/generated-tracers.h -ifeq ($(TRACE_BACKEND),dtrace) +ifeq ($(findstring dtrace,$(TRACE_BACKENDS)),dtrace) GENERATED_HEADERS += trace/generated-tracers-dtrace.h endif GENERATED_SOURCES += trace/generated-tracers.c -ifeq ($(TRACE_BACKEND),ust) +ifeq ($(findstring ust,$(TRACE_BACKENDS)),ust) GENERATED_HEADERS += trace/generated-ust-provider.h GENERATED_SOURCES += trace/generated-ust.c endif diff --git a/Makefile.target b/Makefile.target index 9986047..8155496 100644 --- a/Makefile.target +++ b/Makefile.target @@ -49,7 +49,7 @@ endif $(QEMU_PROG).stp-installed: $(SRC_PATH)/trace-events $(call quiet-command,$(TRACETOOL) \ --format=stap \ - --backend=$(TRACE_BACKEND) \ + --backends=$(TRACE_BACKENDS) \ --binary=$(bindir)/$(QEMU_PROG) \ --target-name=$(TARGET_NAME) \ --target-type=$(TARGET_TYPE) \ @@ -58,7 +58,7 @@ $(QEMU_PROG).stp-installed: $(SRC_PATH)/trace-events $(QEMU_PROG).stp: $(SRC_PATH)/trace-events $(call quiet-command,$(TRACETOOL) \ --format=stap \ - --backend=$(TRACE_BACKEND) \ + --backends=$(TRACE_BACKENDS) \ --binary=$(realpath .)/$(QEMU_PROG) \ --target-name=$(TARGET_NAME) \ --target-type=$(TARGET_TYPE) \ diff --git a/configure b/configure index 0e516f9..a994f41 100755 --- a/configure +++ b/configure @@ -182,6 +182,10 @@ path_of() { return 1 } +have_backend () { + echo "$trace_backends" | grep "$1" >/dev/null +} + # default parameters source_path=`dirname "$0"` cpu="" @@ -293,7 +297,7 @@ pkgversion="" pie="" zero_malloc="" qom_cast_debug="yes" -trace_backend="nop" +trace_backends="nop" trace_file="trace" spice="" rbd="" @@ -753,7 +757,10 @@ for opt do ;; --target-list=*) target_list="$optarg" ;; - --enable-trace-backend=*) trace_backend="$optarg" + --enable-trace-backends=*) trace_backends="$optarg" + ;; + # XXX: backwards compatibility + --enable-trace-backend=*) trace_backends="$optarg" ;; --with-trace-file=*) trace_file="$optarg" ;; @@ -1320,7 +1327,7 @@ Advanced options (experts only): --disable-docs disable documentation build --disable-vhost-net disable vhost-net acceleration support --enable-vhost-net enable vhost-net acceleration support - --enable-trace-backend=B Set trace backend + --enable-trace-backends=B Set trace backend Available backends: $($python $source_path/scripts/tracetool.py --list-backends) --with-trace-file=NAME Full PATH,NAME of file to store traces Default:trace-<pid> @@ -3666,15 +3673,15 @@ fi ########################################## # check if trace backend exists -$python "$source_path/scripts/tracetool.py" "--backend=$trace_backend" --check-backend > /dev/null 2> /dev/null +$python "$source_path/scripts/tracetool.py" "--backends=$trace_backends" --check-backends > /dev/null 2> /dev/null if test "$?" -ne 0 ; then - error_exit "invalid trace backend" \ - "Please choose a supported trace backend." + error_exit "invalid trace backends" \ + "Please choose supported trace backends." fi ########################################## # For 'ust' backend, test if ust headers are present -if test "$trace_backend" = "ust"; then +if have_backend "ust"; then cat > $TMPC << EOF #include <lttng/tracepoint.h> int main(void) { return 0; } @@ -3700,7 +3707,7 @@ fi ########################################## # For 'dtrace' backend, test if 'dtrace' command is present -if test "$trace_backend" = "dtrace"; then +if have_backend "dtrace"; then if ! has 'dtrace' ; then error_exit "dtrace command is not found in PATH $PATH" fi @@ -4170,7 +4177,7 @@ echo "uuid support $uuid" echo "libcap-ng support $cap_ng" echo "vhost-net support $vhost_net" echo "vhost-scsi support $vhost_scsi" -echo "Trace backend $trace_backend" +echo "Trace backends $trace_backends" if test "$trace_backend" = "simple"; then echo "Trace output file $trace_file-<pid>" fi @@ -4664,43 +4671,35 @@ if test "$tpm" = "yes"; then fi fi -# use default implementation for tracing backend-specific routines -trace_default=yes -echo "TRACE_BACKEND=$trace_backend" >> $config_host_mak -if test "$trace_backend" = "nop"; then +echo "TRACE_BACKENDS=$trace_backends" >> $config_host_mak +if have_backend "nop"; then echo "CONFIG_TRACE_NOP=y" >> $config_host_mak fi -if test "$trace_backend" = "simple"; then +if have_backend "simple"; then echo "CONFIG_TRACE_SIMPLE=y" >> $config_host_mak - trace_default=no # Set the appropriate trace file. trace_file="\"$trace_file-\" FMT_pid" fi -if test "$trace_backend" = "stderr"; then +if have_backend "stderr"; then echo "CONFIG_TRACE_STDERR=y" >> $config_host_mak - trace_default=no fi -if test "$trace_backend" = "ust"; then +if have_backend "ust"; then echo "CONFIG_TRACE_UST=y" >> $config_host_mak fi -if test "$trace_backend" = "dtrace"; then +if have_backend "dtrace"; then echo "CONFIG_TRACE_DTRACE=y" >> $config_host_mak if test "$trace_backend_stap" = "yes" ; then echo "CONFIG_TRACE_SYSTEMTAP=y" >> $config_host_mak fi fi -if test "$trace_backend" = "ftrace"; then +if have_backend "ftrace"; then if test "$linux" = "yes" ; then echo "CONFIG_TRACE_FTRACE=y" >> $config_host_mak - trace_default=no else feature_not_found "ftrace(trace backend)" "ftrace requires Linux" fi fi echo "CONFIG_TRACE_FILE=$trace_file" >> $config_host_mak -if test "$trace_default" = "yes"; then - echo "CONFIG_TRACE_DEFAULT=y" >> $config_host_mak -fi if test "$rdma" = "yes" ; then echo "CONFIG_RDMA=y" >> $config_host_mak diff --git a/docs/tracing.txt b/docs/tracing.txt index bf2e15c..c6ab1c1 100644 --- a/docs/tracing.txt +++ b/docs/tracing.txt @@ -9,7 +9,7 @@ for debugging, profiling, and observing execution. 1. Build with the 'simple' trace backend: - ./configure --enable-trace-backend=simple + ./configure --enable-trace-backends=simple make 2. Create a file with the events you want to trace: @@ -142,7 +142,7 @@ script. The trace backend is chosen at configure time and only one trace backend can be built into the binary: - ./configure --trace-backend=simple + ./configure --trace-backends=simple For a list of supported trace backends, try ./configure --help or see below. diff --git a/qemu-io.c b/qemu-io.c index 795cf46..b55a550 100644 --- a/qemu-io.c +++ b/qemu-io.c @@ -433,7 +433,7 @@ int main(int argc, char **argv) } break; case 'T': - if (!trace_backend_init(optarg, NULL)) { + if (!trace_init_backends(optarg, NULL)) { exit(1); /* error message will have been printed */ } break; diff --git a/scripts/tracetool.py b/scripts/tracetool.py index 5f4890f..83bde7b 100755 --- a/scripts/tracetool.py +++ b/scripts/tracetool.py @@ -6,7 +6,7 @@ Command-line wrapper for the tracetool machinery. """ __author__ = "Lluís Vilanova <vilanova@ac.upc.edu>" -__copyright__ = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>" +__copyright__ = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>" __license__ = "GPL version 2 or (at your option) any later version" __maintainer__ = "Stefan Hajnoczi" @@ -32,7 +32,7 @@ def error_opt(msg = None): format_descr = "\n".join([ " %-15s %s" % (n, d) for n,d in tracetool.format.get_list() ]) error_write("""\ -Usage: %(script)s --format=<format> --backend=<backend> [<options>] +Usage: %(script)s --format=<format> --backends=<backends> [<options>] Backends: %(backends)s @@ -43,7 +43,7 @@ Formats: Options: --help This help message. --list-backends Print list of available backends. - --check-backend Check if the given backend is valid. + --check-backends Check if the given backend is valid. --binary <path> Full path to QEMU binary. --target-type <type> QEMU emulator target type ('system' or 'user'). --target-name <name> QEMU emulator target name. @@ -65,16 +65,17 @@ def main(args): global _SCRIPT _SCRIPT = args[0] - long_opts = [ "backend=", "format=", "help", "list-backends", "check-backend" ] - long_opts += [ "binary=", "target-type=", "target-name=", "probe-prefix=" ] + long_opts = ["backends=", "format=", "help", "list-backends", + "check-backends"] + long_opts += ["binary=", "target-type=", "target-name=", "probe-prefix="] try: opts, args = getopt.getopt(args[1:], "", long_opts) except getopt.GetoptError, err: error_opt(str(err)) - check_backend = False - arg_backend = "" + check_backends = False + arg_backends = [] arg_format = "" binary = None target_type = None @@ -84,8 +85,8 @@ def main(args): if opt == "--help": error_opt() - elif opt == "--backend": - arg_backend = arg + elif opt == "--backends": + arg_backends = arg.split(",") elif opt == "--format": arg_format = arg @@ -93,8 +94,8 @@ def main(args): public_backends = tracetool.backend.get_list(only_public = True) out(", ".join([ b for b,_ in public_backends ])) sys.exit(0) - elif opt == "--check-backend": - check_backend = True + elif opt == "--check-backends": + check_backends = True elif opt == "--binary": binary = arg @@ -108,14 +109,14 @@ def main(args): else: error_opt("unhandled option: %s" % opt) - if arg_backend is None: - error_opt("backend not set") + if len(arg_backends) == 0: + error_opt("no backends specified") - if check_backend: - if tracetool.backend.exists(arg_backend): - sys.exit(0) - else: - sys.exit(1) + if check_backends: + for backend in arg_backends: + if not tracetool.backend.exists(backend): + sys.exit(1) + sys.exit(0) if arg_format == "stap": if binary is None: @@ -126,11 +127,11 @@ def main(args): error_opt("--target-name is required for SystemTAP tapset generator") if probe_prefix is None: - probe_prefix = ".".join([ "qemu", target_type, target_name ]) + probe_prefix = ".".join(["qemu", target_type, target_name]) try: - tracetool.generate(sys.stdin, arg_format, arg_backend, - binary = binary, probe_prefix = probe_prefix) + tracetool.generate(sys.stdin, arg_format, arg_backends, + binary=binary, probe_prefix=probe_prefix) except tracetool.TracetoolError, e: error_opt(str(e)) diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py index eccf552..e8e8edc 100644 --- a/scripts/tracetool/__init__.py +++ b/scripts/tracetool/__init__.py @@ -233,9 +233,9 @@ def try_import(mod_name, attr_name=None, attr_default=None): return False, None -def generate(fevents, format, backend, +def generate(fevents, format, backends, binary=None, probe_prefix=None): - """Generate the output for the given (format, backend) pair. + """Generate the output for the given (format, backends) pair. Parameters ---------- @@ -243,8 +243,8 @@ def generate(fevents, format, backend, Event description file. format : str Output format name. - backend : str - Output backend name. + backends : list + Output backend names. binary : str or None See tracetool.backend.dtrace.BINARY. probe_prefix : str or None @@ -258,15 +258,13 @@ def generate(fevents, format, backend, raise TracetoolError("format not set") if not tracetool.format.exists(format): raise TracetoolError("unknown format: %s" % format) - format = format.replace("-", "_") - - backend = str(backend) - if len(backend) is 0: - raise TracetoolError("backend not set") - if not tracetool.backend.exists(backend): - raise TracetoolError("unknown backend: %s" % backend) - backend = backend.replace("-", "_") - backend = tracetool.backend.Wrapper(backend, format) + + if len(backends) is 0: + raise TracetoolError("no backends specified") + for backend in backends: + if not tracetool.backend.exists(backend): + raise TracetoolError("unknown backend: %s" % backend) + backend = tracetool.backend.Wrapper(backends, format) import tracetool.backend.dtrace tracetool.backend.dtrace.BINARY = binary diff --git a/scripts/tracetool/backend/__init__.py b/scripts/tracetool/backend/__init__.py index 5e36f04..5bfa1ef 100644 --- a/scripts/tracetool/backend/__init__.py +++ b/scripts/tracetool/backend/__init__.py @@ -99,17 +99,18 @@ def exists(name): class Wrapper: - def __init__(self, backend, format): - self._backend = backend.replace("-", "_") + def __init__(self, backends, format): + self._backends = [backend.replace("-", "_") for backend in backends] self._format = format.replace("-", "_") - assert exists(self._backend) + assert all(exists(backend) for backend in self._backends) assert tracetool.format.exists(self._format) def _run_function(self, name, *args, **kwargs): - func = tracetool.try_import("tracetool.backend." + self._backend, - name % self._format, None)[1] - if func is not None: - func(*args, **kwargs) + for backend in self._backends: + func = tracetool.try_import("tracetool.backend." + backend, + name % self._format, None)[1] + if func is not None: + func(*args, **kwargs) def generate_begin(self, events): self._run_function("generate_%s_begin", events) diff --git a/trace/Makefile.objs b/trace/Makefile.objs index 6a30467..d7a8696 100644 --- a/trace/Makefile.objs +++ b/trace/Makefile.objs @@ -3,12 +3,12 @@ ###################################################################### # Auto-generated event descriptions for LTTng ust code -ifeq ($(TRACE_BACKEND),ust) +ifeq ($(findstring ust,$(TRACE_BACKENDS)),ust) $(obj)/generated-ust-provider.h: $(obj)/generated-ust-provider.h-timestamp $(obj)/generated-ust-provider.h-timestamp: $(SRC_PATH)/trace-events $(call quiet-command,$(TRACETOOL) \ --format=ust-events-h \ - --backend=$(TRACE_BACKEND) \ + --backends=$(TRACE_BACKENDS) \ < $< > $@," GEN $(patsubst %-timestamp,%,$@)") @cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@) @@ -16,7 +16,7 @@ $(obj)/generated-ust.c: $(obj)/generated-ust.c-timestamp $(BUILD_DIR)/config-hos $(obj)/generated-ust.c-timestamp: $(SRC_PATH)/trace-events $(call quiet-command,$(TRACETOOL) \ --format=ust-events-c \ - --backend=$(TRACE_BACKEND) \ + --backends=$(TRACE_BACKENDS) \ < $< > $@," GEN $(patsubst %-timestamp,%,$@)") @cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@) @@ -31,7 +31,7 @@ $(obj)/generated-events.h: $(obj)/generated-events.h-timestamp $(obj)/generated-events.h-timestamp: $(SRC_PATH)/trace-events $(call quiet-command,$(TRACETOOL) \ --format=events-h \ - --backend=$(TRACE_BACKEND) \ + --backends=$(TRACE_BACKENDS) \ < $< > $@," GEN $(patsubst %-timestamp,%,$@)") @cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@) @@ -39,7 +39,7 @@ $(obj)/generated-events.c: $(obj)/generated-events.c-timestamp $(BUILD_DIR)/conf $(obj)/generated-events.c-timestamp: $(SRC_PATH)/trace-events $(call quiet-command,$(TRACETOOL) \ --format=events-c \ - --backend=$(TRACE_BACKEND) \ + --backends=$(TRACE_BACKENDS) \ < $< > $@," GEN $(patsubst %-timestamp,%,$@)") @cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@) @@ -54,23 +54,21 @@ $(obj)/generated-tracers.h: $(obj)/generated-tracers.h-timestamp $(obj)/generated-tracers.h-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak $(call quiet-command,$(TRACETOOL) \ --format=h \ - --backend=$(TRACE_BACKEND) \ + --backends=$(TRACE_BACKENDS) \ < $< > $@," GEN $(patsubst %-timestamp,%,$@)") ###################################################################### # Auto-generated tracing routines (non-DTrace) -ifneq ($(TRACE_BACKEND),dtrace) $(obj)/generated-tracers.c: $(obj)/generated-tracers.c-timestamp @cmp -s $< $@ || cp $< $@ $(obj)/generated-tracers.c-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak $(call quiet-command,$(TRACETOOL) \ --format=c \ - --backend=$(TRACE_BACKEND) \ + --backends=$(TRACE_BACKENDS) \ < $< > $@," GEN $(patsubst %-timestamp,%,$@)") $(obj)/generated-tracers.o: $(obj)/generated-tracers.c $(obj)/generated-tracers.h -endif ###################################################################### @@ -79,27 +77,27 @@ endif # Normal practice is to name DTrace probe file with a '.d' extension # but that gets picked up by QEMU's Makefile as an external dependency # rule file. So we use '.dtrace' instead -ifeq ($(TRACE_BACKEND),dtrace) -$(obj)/generated-tracers.dtrace: $(obj)/generated-tracers.dtrace-timestamp -$(obj)/generated-tracers.dtrace-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak +ifeq ($(findstring dtrace,$(TRACE_BACKENDS)),dtrace) +$(obj)/generated-tracers-dtrace.dtrace: $(obj)/generated-tracers-dtrace.dtrace-timestamp +$(obj)/generated-tracers-dtrace.dtrace-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak $(call quiet-command,$(TRACETOOL) \ --format=d \ - --backend=$(TRACE_BACKEND) \ + --backends=$(TRACE_BACKENDS) \ < $< > $@," GEN $(patsubst %-timestamp,%,$@)") @cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@) -$(obj)/generated-tracers-dtrace.h: $(obj)/generated-tracers.dtrace +$(obj)/generated-tracers-dtrace.h: $(obj)/generated-tracers-dtrace.dtrace $(call quiet-command,dtrace -o $@ -h -s $<, " GEN $@") -$(obj)/generated-tracers.o: $(obj)/generated-tracers.dtrace +$(obj)/generated-tracers-dtrace.o: $(obj)/generated-tracers-dtrace.dtrace + +util-obj-y += generated-tracers-dtrace.o endif ###################################################################### # Backend code -util-obj-$(CONFIG_TRACE_DEFAULT) += default.o util-obj-$(CONFIG_TRACE_SIMPLE) += simple.o -util-obj-$(CONFIG_TRACE_STDERR) += stderr.o util-obj-$(CONFIG_TRACE_FTRACE) += ftrace.o util-obj-$(CONFIG_TRACE_UST) += generated-ust.o util-obj-y += control.o diff --git a/trace/control-internal.h b/trace/control-internal.h index b3f587e..5a8df28 100644 --- a/trace/control-internal.h +++ b/trace/control-internal.h @@ -1,7 +1,7 @@ /* * Interface for configuring and controlling the state of tracing events. * - * Copyright (C) 2011-2012 Lluís Vilanova <vilanova@ac.upc.edu> + * Copyright (C) 2011-2014 Lluís Vilanova <vilanova@ac.upc.edu> * * This work is licensed under the terms of the GNU GPL, version 2 or later. * See the COPYING file in the top-level directory. @@ -61,7 +61,7 @@ static inline void trace_event_set_state_dynamic(TraceEvent *ev, bool state) { assert(ev != NULL); assert(trace_event_get_state_static(ev)); - return trace_event_set_state_dynamic_backend(ev, state); + ev->dstate = state; } #endif /* TRACE__CONTROL_INTERNAL_H */ diff --git a/trace/control.c b/trace/control.c index 4aa02cf..45e6604 100644 --- a/trace/control.c +++ b/trace/control.c @@ -1,13 +1,19 @@ /* * Interface for configuring and controlling the state of tracing events. * - * Copyright (C) 2011-2012 Lluís Vilanova <vilanova@ac.upc.edu> + * Copyright (C) 2011-2014 Lluís Vilanova <vilanova@ac.upc.edu> * * This work is licensed under the terms of the GNU GPL, version 2 or later. * See the COPYING file in the top-level directory. */ #include "trace/control.h" +#ifdef CONFIG_TRACE_SIMPLE +#include "trace/simple.h" +#endif +#ifdef CONFIG_TRACE_FTRACE +#include "trace/ftrace.h" +#endif TraceEvent *trace_event_name(const char *name) @@ -79,7 +85,20 @@ TraceEvent *trace_event_pattern(const char *pat, TraceEvent *ev) return NULL; } -void trace_backend_init_events(const char *fname) +void trace_print_events(FILE *stream, fprintf_function stream_printf) +{ + TraceEventID i; + + for (i = 0; i < trace_event_count(); i++) { + TraceEvent *ev = trace_event_id(i); + stream_printf(stream, "%s [Event ID %u] : state %u\n", + trace_event_get_name(ev), i, + trace_event_get_state_static(ev) && + trace_event_get_state_dynamic(ev)); + } +} + +static void trace_init_events(const char *fname) { if (fname == NULL) { return; @@ -130,3 +149,29 @@ void trace_backend_init_events(const char *fname) exit(1); } } + +bool trace_init_backends(const char *events, const char *file) +{ +#ifdef CONFIG_TRACE_SIMPLE + if (!st_init(file)) { + fprintf(stderr, "failed to initialize simple tracing backend.\n"); + return false; + } +#else + if (file) { + fprintf(stderr, "error: -trace file=...: " + "option not supported by the selected tracing backends\n"); + return false; + } +#endif + +#ifdef CONFIG_TRACE_FTRACE + if (!ftrace_init()) { + fprintf(stderr, "failed to initialize ftrace backend.\n"); + return false; + } +#endif + + trace_init_events(events); + return true; +} diff --git a/trace/control.h b/trace/control.h index cde8260..e1ec033 100644 --- a/trace/control.h +++ b/trace/control.h @@ -1,7 +1,7 @@ /* * Interface for configuring and controlling the state of tracing events. * - * Copyright (C) 2011-2012 Lluís Vilanova <vilanova@ac.upc.edu> + * Copyright (C) 2011-2014 Lluís Vilanova <vilanova@ac.upc.edu> * * This work is licensed under the terms of the GNU GPL, version 2 or later. * See the COPYING file in the top-level directory. @@ -146,26 +146,17 @@ static bool trace_event_get_state_dynamic(TraceEvent *ev); */ static void trace_event_set_state_dynamic(TraceEvent *ev, bool state); -/** - * trace_event_set_state_dynamic_backend: - * - * Warning: This function must be implemented by each tracing backend. - */ -void trace_event_set_state_dynamic_backend(TraceEvent *ev, bool state); - /** * trace_print_events: * * Print the state of all events. - * - * Warning: This function must be implemented by each tracing backend. */ void trace_print_events(FILE *stream, fprintf_function stream_printf); /** - * trace_backend_init: + * trace_init_backends: * @events: Name of file with events to be enabled at startup; may be NULL. * Corresponds to commandline option "-trace events=...". * @file: Name of trace output file; may be NULL. @@ -173,19 +164,9 @@ void trace_print_events(FILE *stream, fprintf_function stream_printf); * * Initialize the tracing backend. * - * Warning: This function must be implemented by each tracing backend. - * - * Returns: Whether the backend could be successfully initialized. - */ -bool trace_backend_init(const char *events, const char *file); - -/** - * trace_backend_init_events: - * @fname: Name of file with events to enable; may be NULL. - * - * Generic function to initialize the state of events. + * Returns: Whether the backends could be successfully initialized. */ -void trace_backend_init_events(const char *fname); +bool trace_init_backends(const char *events, const char *file); #include "trace/control-internal.h" diff --git a/trace/default.c b/trace/default.c deleted file mode 100644 index 6e07a47..0000000 --- a/trace/default.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Default implementation for backend initialization from commandline. - * - * Copyright (C) 2011-2012 Lluís Vilanova <vilanova@ac.upc.edu> - * - * This work is licensed under the terms of the GNU GPL, version 2. See - * the COPYING file in the top-level directory. - */ - -#include "trace/control.h" - - -void trace_print_events(FILE *stream, fprintf_function stream_printf) -{ - fprintf(stderr, "warning: " - "cannot print the trace events with the current backend\n"); - stream_printf(stream, "error: " - "operation not supported with the current backend\n"); -} - -void trace_event_set_state_dynamic_backend(TraceEvent *ev, bool state) -{ - fprintf(stderr, "warning: " - "cannot set the state of a trace event with the current backend\n"); -} - -bool trace_backend_init(const char *events, const char *file) -{ - if (events) { - fprintf(stderr, "error: -trace events=...: " - "option not supported by the selected tracing backend\n"); - return false; - } - if (file) { - fprintf(stderr, "error: -trace file=...: " - "option not supported by the selected tracing backend\n"); - return false; - } - return true; -} diff --git a/trace/ftrace.c b/trace/ftrace.c index 46b7fdb..a7ae371 100644 --- a/trace/ftrace.c +++ b/trace/ftrace.c @@ -42,35 +42,13 @@ static int find_debugfs(char *debugfs) return 1; } -void trace_print_events(FILE *stream, fprintf_function stream_printf) -{ - TraceEventID i; - - for (i = 0; i < trace_event_count(); i++) { - TraceEvent *ev = trace_event_id(i); - stream_printf(stream, "%s [Event ID %u] : state %u\n", - trace_event_get_name(ev), i, trace_event_get_state_dynamic(ev)); - } -} - -void trace_event_set_state_dynamic_backend(TraceEvent *ev, bool state) -{ - ev->dstate = state; -} - -bool trace_backend_init(const char *events, const char *file) +bool ftrace_init(void) { char debugfs[PATH_MAX]; char path[PATH_MAX]; int debugfs_found; int trace_fd = -1; - if (file) { - fprintf(stderr, "error: -trace file=...: " - "option not supported by the selected tracing backend\n"); - return false; - } - debugfs_found = find_debugfs(debugfs); if (debugfs_found) { snprintf(path, PATH_MAX, "%s/tracing/tracing_on", debugfs); @@ -97,6 +75,5 @@ bool trace_backend_init(const char *events, const char *file) return false; } - trace_backend_init_events(events); return true; } diff --git a/trace/ftrace.h b/trace/ftrace.h index 94cb8d5..863e052 100644 --- a/trace/ftrace.h +++ b/trace/ftrace.h @@ -1,10 +1,15 @@ #ifndef TRACE_FTRACE_H #define TRACE_FTRACE_H +#include <stdbool.h> + + #define MAX_TRACE_STRLEN 512 #define _STR(x) #x #define STR(x) _STR(x) extern int trace_marker_fd; +bool ftrace_init(void); + #endif /* ! TRACE_FTRACE_H */ diff --git a/trace/simple.c b/trace/simple.c index 5a2e188..a8f923c 100644 --- a/trace/simple.c +++ b/trace/simple.c @@ -368,22 +368,6 @@ void st_flush_trace_buffer(void) flush_trace_file(true); } -void trace_print_events(FILE *stream, fprintf_function stream_printf) -{ - unsigned int i; - - for (i = 0; i < trace_event_count(); i++) { - TraceEvent *ev = trace_event_id(i); - stream_printf(stream, "%s [Event ID %u] : state %u\n", - trace_event_get_name(ev), i, trace_event_get_state_dynamic(ev)); - } -} - -void trace_event_set_state_dynamic_backend(TraceEvent *ev, bool state) -{ - ev->dstate = state; -} - /* Helper function to create a thread with signals blocked. Use glib's * portable threads since QEMU abstractions cannot be used due to reentrancy in * the tracer. Also note the signal masking on POSIX hosts so that the thread @@ -412,7 +396,7 @@ static GThread *trace_thread_create(GThreadFunc fn) return thread; } -bool trace_backend_init(const char *events, const char *file) +bool st_init(const char *file) { GThread *thread; @@ -430,7 +414,6 @@ bool trace_backend_init(const char *events, const char *file) } atexit(st_flush_trace_buffer); - trace_backend_init_events(events); st_set_trace_file(file); return true; } diff --git a/trace/simple.h b/trace/simple.h index 5260d9a..6997996 100644 --- a/trace/simple.h +++ b/trace/simple.h @@ -21,6 +21,7 @@ void st_print_trace_file_status(FILE *stream, fprintf_function stream_printf); void st_set_trace_file_enabled(bool enable); bool st_set_trace_file(const char *file); +bool st_init(const char *file); void st_flush_trace_buffer(void); typedef struct { diff --git a/trace/stderr.c b/trace/stderr.c deleted file mode 100644 index e212efd..0000000 --- a/trace/stderr.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "trace.h" -#include "trace/control.h" - - -void trace_print_events(FILE *stream, fprintf_function stream_printf) -{ - TraceEventID i; - - for (i = 0; i < trace_event_count(); i++) { - TraceEvent *ev = trace_event_id(i); - stream_printf(stream, "%s [Event ID %u] : state %u\n", - trace_event_get_name(ev), i, trace_event_get_state_dynamic(ev)); - } -} - -void trace_event_set_state_dynamic_backend(TraceEvent *ev, bool state) -{ - ev->dstate = state; -} - -bool trace_backend_init(const char *events, const char *file) -{ - if (file) { - fprintf(stderr, "error: -trace file=...: " - "option not supported by the selected tracing backend\n"); - return false; - } - trace_backend_init_events(events); - return true; -} diff --git a/vl.c b/vl.c index a3def97..ac0e3d7 100644 --- a/vl.c +++ b/vl.c @@ -4039,7 +4039,7 @@ int main(int argc, char **argv, char **envp) } if (!is_daemonized()) { - if (!trace_backend_init(trace_events, trace_file)) { + if (!trace_init_backends(trace_events, trace_file)) { exit(1); } } @@ -4559,7 +4559,7 @@ int main(int argc, char **argv, char **envp) os_setup_post(); if (is_daemonized()) { - if (!trace_backend_init(trace_events, trace_file)) { + if (!trace_init_backends(trace_events, trace_file)) { exit(1); } } -- 1.9.3 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [PULL 4/5] trace: Multi-backend tracing 2014-06-09 15:23 ` [Qemu-devel] [PULL 4/5] trace: Multi-backend tracing Stefan Hajnoczi @ 2014-06-16 9:58 ` Peter Maydell 0 siblings, 0 replies; 9+ messages in thread From: Peter Maydell @ 2014-06-16 9:58 UTC (permalink / raw) To: Stefan Hajnoczi; +Cc: QEMU Developers, Lluís Vilanova On 9 June 2014 16:23, Stefan Hajnoczi <stefanha@redhat.com> wrote: > From: Lluís Vilanova <vilanova@ac.upc.edu> > > Adds support to compile QEMU with multiple tracing backends at the same time. > > For example, you can compile QEMU with: > > $ ./configure --enable-trace-backends=ftrace,dtrace > > Where 'ftrace' can be handy for having an in-flight record of events, and 'dtrace' can be later used to extract more information from the system. > > This patch allows having both available without recompiling QEMU. Hi. This patch causes QEMU to fail to do a rebuild unless you do a distclean, because: * the trace headers are in GENERATED_HEADERS, and so Makefile depends on them * this means that when Make does its "is any makefile or include out of date and needing a rebuild?" check, as well as possibly running configure (to update config-host.mak) it will also rebuild GENERATED_HEADERS under the "old" config-host.mak regime * if you run the new trace header rules with an old config-host.mak then the tracetool script will barf (printing its usage message) because it has been passed an empty string for the list of backends. Paolo suggested that adding $(GENERATED_HEADERS): config-host.mak to the makefile might fix this. Unfortunately it doesn't help much, because although it ensures that configure gets run first, make won't reread any of its files (including config-host.mak) until it has rebuilt all of them, so we still run the header rules with the old config-host.mak. It does mean that configure gets run first, so you can guarantee that manually rerunning make will work (without the dependency then the headers might get built first and fail before make gets round to running configure). thanks -- PMM ^ permalink raw reply [flat|nested] 9+ messages in thread
* [Qemu-devel] [PULL 5/5] trace: Replace fprintf with error_report and print location 2014-06-09 15:23 [Qemu-devel] [PULL v2 0/5] Tracing pull request Stefan Hajnoczi ` (3 preceding siblings ...) 2014-06-09 15:23 ` [Qemu-devel] [PULL 4/5] trace: Multi-backend tracing Stefan Hajnoczi @ 2014-06-09 15:23 ` Stefan Hajnoczi 2014-06-09 16:03 ` [Qemu-devel] [PULL v2 0/5] Tracing pull request Peter Maydell 5 siblings, 0 replies; 9+ messages in thread From: Stefan Hajnoczi @ 2014-06-09 15:23 UTC (permalink / raw) To: qemu-devel; +Cc: Alexey Kardashevskiy, Peter Maydell, Stefan Hajnoczi From: Alexey Kardashevskiy <aik@ozlabs.ru> This replaces fprintf(stderr) with error_report. This moves local variables to the beginning of the function to comply with QEMU's coding style. Suggested-by: Lluís Vilanova <vilanova@ac.upc.edu> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> --- trace/control.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/trace/control.c b/trace/control.c index 45e6604..9631a40 100644 --- a/trace/control.c +++ b/trace/control.c @@ -14,7 +14,7 @@ #ifdef CONFIG_TRACE_FTRACE #include "trace/ftrace.h" #endif - +#include "qemu/error-report.h" TraceEvent *trace_event_name(const char *name) { @@ -100,18 +100,24 @@ void trace_print_events(FILE *stream, fprintf_function stream_printf) static void trace_init_events(const char *fname) { + Location loc; + FILE *fp; + char line_buf[1024]; + size_t line_idx = 0; + if (fname == NULL) { return; } - FILE *fp = fopen(fname, "r"); + loc_push_none(&loc); + loc_set_file(fname, 0); + fp = fopen(fname, "r"); if (!fp) { - fprintf(stderr, "error: could not open trace events file '%s': %s\n", - fname, strerror(errno)); + error_report("%s", strerror(errno)); exit(1); } - char line_buf[1024]; while (fgets(line_buf, sizeof(line_buf), fp)) { + loc_set_file(fname, ++line_idx); size_t len = strlen(line_buf); if (len > 1) { /* skip empty lines */ line_buf[len - 1] = '\0'; @@ -130,13 +136,11 @@ static void trace_init_events(const char *fname) } else { TraceEvent *ev = trace_event_name(line_ptr); if (ev == NULL) { - fprintf(stderr, - "WARNING: trace event '%s' does not exist\n", - line_ptr); + error_report("WARNING: trace event '%s' does not exist", + line_ptr); } else if (!trace_event_get_state_static(ev)) { - fprintf(stderr, - "WARNING: trace event '%s' is not traceable\n", - line_ptr); + error_report("WARNING: trace event '%s' is not traceable\n", + line_ptr); } else { trace_event_set_state_dynamic(ev, enable); } @@ -144,10 +148,11 @@ static void trace_init_events(const char *fname) } } if (fclose(fp) != 0) { - fprintf(stderr, "error: closing file '%s': %s\n", - fname, strerror(errno)); + loc_set_file(fname, 0); + error_report("%s", strerror(errno)); exit(1); } + loc_pop(&loc); } bool trace_init_backends(const char *events, const char *file) -- 1.9.3 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [PULL v2 0/5] Tracing pull request 2014-06-09 15:23 [Qemu-devel] [PULL v2 0/5] Tracing pull request Stefan Hajnoczi ` (4 preceding siblings ...) 2014-06-09 15:23 ` [Qemu-devel] [PULL 5/5] trace: Replace fprintf with error_report and print location Stefan Hajnoczi @ 2014-06-09 16:03 ` Peter Maydell 5 siblings, 0 replies; 9+ messages in thread From: Peter Maydell @ 2014-06-09 16:03 UTC (permalink / raw) To: Stefan Hajnoczi; +Cc: QEMU Developers On 9 June 2014 16:23, Stefan Hajnoczi <stefanha@redhat.com> wrote: > v2: > * Previous version was interleaved with an older pull request and the email > thread was a mess. Resending. > > The following changes since commit 959e41473f2179850578482052fb73b913bc4e42: > > slirp/arp: do not special-case bogus IP addresses (2014-06-09 01:49:28 +0200) > > are available in the git repository at: > > git://github.com/stefanha/qemu.git tags/tracing-pull-request > > for you to fetch changes up to a35d9be622a85d9ad6be5448e78c8a3f95ee5f00: > > trace: Replace fprintf with error_report and print location (2014-06-09 15:43:40 +0200) > > ---------------------------------------------------------------- > Tracing pull request Applied, thanks. -- PMM ^ permalink raw reply [flat|nested] 9+ messages in thread
* [Qemu-devel] [PULL 0/5] Tracing patches @ 2014-06-09 13:45 Stefan Hajnoczi 2014-06-09 13:45 ` [Qemu-devel] [PULL 4/5] trace: Multi-backend tracing Stefan Hajnoczi 0 siblings, 1 reply; 9+ messages in thread From: Stefan Hajnoczi @ 2014-06-09 13:45 UTC (permalink / raw) To: qemu-devel; +Cc: Peter Maydell, Stefan Hajnoczi The following changes since commit 959e41473f2179850578482052fb73b913bc4e42: slirp/arp: do not special-case bogus IP addresses (2014-06-09 01:49:28 +0200) are available in the git repository at: git://github.com/stefanha/qemu.git tags/tracing-pull-request for you to fetch changes up to a35d9be622a85d9ad6be5448e78c8a3f95ee5f00: trace: Replace fprintf with error_report and print location (2014-06-09 15:43:40 +0200) ---------------------------------------------------------------- Tracing pull request ---------------------------------------------------------------- Alexey Kardashevskiy (2): trace: Replace error with warning if event is not defined trace: Replace fprintf with error_report and print location Lluís Vilanova (1): trace: Multi-backend tracing Stefan Hajnoczi (2): trace: add pid field to simpletrace record simpletrace: add support for trace record pid field .travis.yml | 8 ++-- Makefile | 4 +- Makefile.target | 4 +- configure | 47 ++++++++++--------- docs/tracing.txt | 4 +- qemu-io.c | 2 +- scripts/simpletrace.py | 26 ++++++----- scripts/tracetool.py | 43 +++++++++--------- scripts/tracetool/__init__.py | 24 +++++----- scripts/tracetool/backend/__init__.py | 15 +++--- trace/Makefile.objs | 32 ++++++------- trace/control-internal.h | 4 +- trace/control.c | 86 +++++++++++++++++++++++++++-------- trace/control.h | 27 ++--------- trace/default.c | 40 ---------------- trace/ftrace.c | 25 +--------- trace/ftrace.h | 5 ++ trace/simple.c | 27 +++-------- trace/simple.h | 1 + trace/stderr.c | 30 ------------ vl.c | 4 +- 21 files changed, 195 insertions(+), 263 deletions(-) delete mode 100644 trace/default.c delete mode 100644 trace/stderr.c -- 1.9.3 ^ permalink raw reply [flat|nested] 9+ messages in thread
* [Qemu-devel] [PULL 4/5] trace: Multi-backend tracing 2014-06-09 13:45 [Qemu-devel] [PULL 0/5] Tracing patches Stefan Hajnoczi @ 2014-06-09 13:45 ` Stefan Hajnoczi 0 siblings, 0 replies; 9+ messages in thread From: Stefan Hajnoczi @ 2014-06-09 13:45 UTC (permalink / raw) To: qemu-devel; +Cc: Peter Maydell, Lluís Vilanova, Stefan Hajnoczi From: Lluís Vilanova <vilanova@ac.upc.edu> Adds support to compile QEMU with multiple tracing backends at the same time. For example, you can compile QEMU with: $ ./configure --enable-trace-backends=ftrace,dtrace Where 'ftrace' can be handy for having an in-flight record of events, and 'dtrace' can be later used to extract more information from the system. This patch allows having both available without recompiling QEMU. Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> --- .travis.yml | 8 +++--- Makefile | 4 +-- Makefile.target | 4 +-- configure | 47 ++++++++++++++++----------------- docs/tracing.txt | 4 +-- qemu-io.c | 2 +- scripts/tracetool.py | 43 +++++++++++++++--------------- scripts/tracetool/__init__.py | 24 ++++++++--------- scripts/tracetool/backend/__init__.py | 15 ++++++----- trace/Makefile.objs | 32 +++++++++++------------ trace/control-internal.h | 4 +-- trace/control.c | 49 +++++++++++++++++++++++++++++++++-- trace/control.h | 27 +++---------------- trace/default.c | 40 ---------------------------- trace/ftrace.c | 25 +----------------- trace/ftrace.h | 5 ++++ trace/simple.c | 19 +------------- trace/simple.h | 1 + trace/stderr.c | 30 --------------------- vl.c | 4 +-- 20 files changed, 153 insertions(+), 234 deletions(-) delete mode 100644 trace/default.c delete mode 100644 trace/stderr.c diff --git a/.travis.yml b/.travis.yml index 04da973..89c30ae 100644 --- a/.travis.yml +++ b/.travis.yml @@ -66,16 +66,16 @@ matrix: compiler: gcc # All the trace backends (apart from dtrace) - env: TARGETS=i386-softmmu,x86_64-softmmu - EXTRA_CONFIG="--enable-trace-backend=stderr" + EXTRA_CONFIG="--enable-trace-backends=stderr" compiler: gcc - env: TARGETS=i386-softmmu,x86_64-softmmu - EXTRA_CONFIG="--enable-trace-backend=simple" + EXTRA_CONFIG="--enable-trace-backends=simple" compiler: gcc - env: TARGETS=i386-softmmu,x86_64-softmmu - EXTRA_CONFIG="--enable-trace-backend=ftrace" + EXTRA_CONFIG="--enable-trace-backends=ftrace" TEST_CMD="" compiler: gcc - env: TARGETS=i386-softmmu,x86_64-softmmu EXTRA_PKGS="liblttng-ust-dev liburcu-dev" - EXTRA_CONFIG="--enable-trace-backend=ust" + EXTRA_CONFIG="--enable-trace-backends=ust" compiler: gcc diff --git a/Makefile b/Makefile index d830483..3c8f19c 100644 --- a/Makefile +++ b/Makefile @@ -52,12 +52,12 @@ GENERATED_HEADERS += trace/generated-events.h GENERATED_SOURCES += trace/generated-events.c GENERATED_HEADERS += trace/generated-tracers.h -ifeq ($(TRACE_BACKEND),dtrace) +ifeq ($(findstring dtrace,$(TRACE_BACKENDS)),dtrace) GENERATED_HEADERS += trace/generated-tracers-dtrace.h endif GENERATED_SOURCES += trace/generated-tracers.c -ifeq ($(TRACE_BACKEND),ust) +ifeq ($(findstring ust,$(TRACE_BACKENDS)),ust) GENERATED_HEADERS += trace/generated-ust-provider.h GENERATED_SOURCES += trace/generated-ust.c endif diff --git a/Makefile.target b/Makefile.target index 9986047..8155496 100644 --- a/Makefile.target +++ b/Makefile.target @@ -49,7 +49,7 @@ endif $(QEMU_PROG).stp-installed: $(SRC_PATH)/trace-events $(call quiet-command,$(TRACETOOL) \ --format=stap \ - --backend=$(TRACE_BACKEND) \ + --backends=$(TRACE_BACKENDS) \ --binary=$(bindir)/$(QEMU_PROG) \ --target-name=$(TARGET_NAME) \ --target-type=$(TARGET_TYPE) \ @@ -58,7 +58,7 @@ $(QEMU_PROG).stp-installed: $(SRC_PATH)/trace-events $(QEMU_PROG).stp: $(SRC_PATH)/trace-events $(call quiet-command,$(TRACETOOL) \ --format=stap \ - --backend=$(TRACE_BACKEND) \ + --backends=$(TRACE_BACKENDS) \ --binary=$(realpath .)/$(QEMU_PROG) \ --target-name=$(TARGET_NAME) \ --target-type=$(TARGET_TYPE) \ diff --git a/configure b/configure index 0e516f9..a994f41 100755 --- a/configure +++ b/configure @@ -182,6 +182,10 @@ path_of() { return 1 } +have_backend () { + echo "$trace_backends" | grep "$1" >/dev/null +} + # default parameters source_path=`dirname "$0"` cpu="" @@ -293,7 +297,7 @@ pkgversion="" pie="" zero_malloc="" qom_cast_debug="yes" -trace_backend="nop" +trace_backends="nop" trace_file="trace" spice="" rbd="" @@ -753,7 +757,10 @@ for opt do ;; --target-list=*) target_list="$optarg" ;; - --enable-trace-backend=*) trace_backend="$optarg" + --enable-trace-backends=*) trace_backends="$optarg" + ;; + # XXX: backwards compatibility + --enable-trace-backend=*) trace_backends="$optarg" ;; --with-trace-file=*) trace_file="$optarg" ;; @@ -1320,7 +1327,7 @@ Advanced options (experts only): --disable-docs disable documentation build --disable-vhost-net disable vhost-net acceleration support --enable-vhost-net enable vhost-net acceleration support - --enable-trace-backend=B Set trace backend + --enable-trace-backends=B Set trace backend Available backends: $($python $source_path/scripts/tracetool.py --list-backends) --with-trace-file=NAME Full PATH,NAME of file to store traces Default:trace-<pid> @@ -3666,15 +3673,15 @@ fi ########################################## # check if trace backend exists -$python "$source_path/scripts/tracetool.py" "--backend=$trace_backend" --check-backend > /dev/null 2> /dev/null +$python "$source_path/scripts/tracetool.py" "--backends=$trace_backends" --check-backends > /dev/null 2> /dev/null if test "$?" -ne 0 ; then - error_exit "invalid trace backend" \ - "Please choose a supported trace backend." + error_exit "invalid trace backends" \ + "Please choose supported trace backends." fi ########################################## # For 'ust' backend, test if ust headers are present -if test "$trace_backend" = "ust"; then +if have_backend "ust"; then cat > $TMPC << EOF #include <lttng/tracepoint.h> int main(void) { return 0; } @@ -3700,7 +3707,7 @@ fi ########################################## # For 'dtrace' backend, test if 'dtrace' command is present -if test "$trace_backend" = "dtrace"; then +if have_backend "dtrace"; then if ! has 'dtrace' ; then error_exit "dtrace command is not found in PATH $PATH" fi @@ -4170,7 +4177,7 @@ echo "uuid support $uuid" echo "libcap-ng support $cap_ng" echo "vhost-net support $vhost_net" echo "vhost-scsi support $vhost_scsi" -echo "Trace backend $trace_backend" +echo "Trace backends $trace_backends" if test "$trace_backend" = "simple"; then echo "Trace output file $trace_file-<pid>" fi @@ -4664,43 +4671,35 @@ if test "$tpm" = "yes"; then fi fi -# use default implementation for tracing backend-specific routines -trace_default=yes -echo "TRACE_BACKEND=$trace_backend" >> $config_host_mak -if test "$trace_backend" = "nop"; then +echo "TRACE_BACKENDS=$trace_backends" >> $config_host_mak +if have_backend "nop"; then echo "CONFIG_TRACE_NOP=y" >> $config_host_mak fi -if test "$trace_backend" = "simple"; then +if have_backend "simple"; then echo "CONFIG_TRACE_SIMPLE=y" >> $config_host_mak - trace_default=no # Set the appropriate trace file. trace_file="\"$trace_file-\" FMT_pid" fi -if test "$trace_backend" = "stderr"; then +if have_backend "stderr"; then echo "CONFIG_TRACE_STDERR=y" >> $config_host_mak - trace_default=no fi -if test "$trace_backend" = "ust"; then +if have_backend "ust"; then echo "CONFIG_TRACE_UST=y" >> $config_host_mak fi -if test "$trace_backend" = "dtrace"; then +if have_backend "dtrace"; then echo "CONFIG_TRACE_DTRACE=y" >> $config_host_mak if test "$trace_backend_stap" = "yes" ; then echo "CONFIG_TRACE_SYSTEMTAP=y" >> $config_host_mak fi fi -if test "$trace_backend" = "ftrace"; then +if have_backend "ftrace"; then if test "$linux" = "yes" ; then echo "CONFIG_TRACE_FTRACE=y" >> $config_host_mak - trace_default=no else feature_not_found "ftrace(trace backend)" "ftrace requires Linux" fi fi echo "CONFIG_TRACE_FILE=$trace_file" >> $config_host_mak -if test "$trace_default" = "yes"; then - echo "CONFIG_TRACE_DEFAULT=y" >> $config_host_mak -fi if test "$rdma" = "yes" ; then echo "CONFIG_RDMA=y" >> $config_host_mak diff --git a/docs/tracing.txt b/docs/tracing.txt index bf2e15c..c6ab1c1 100644 --- a/docs/tracing.txt +++ b/docs/tracing.txt @@ -9,7 +9,7 @@ for debugging, profiling, and observing execution. 1. Build with the 'simple' trace backend: - ./configure --enable-trace-backend=simple + ./configure --enable-trace-backends=simple make 2. Create a file with the events you want to trace: @@ -142,7 +142,7 @@ script. The trace backend is chosen at configure time and only one trace backend can be built into the binary: - ./configure --trace-backend=simple + ./configure --trace-backends=simple For a list of supported trace backends, try ./configure --help or see below. diff --git a/qemu-io.c b/qemu-io.c index 795cf46..b55a550 100644 --- a/qemu-io.c +++ b/qemu-io.c @@ -433,7 +433,7 @@ int main(int argc, char **argv) } break; case 'T': - if (!trace_backend_init(optarg, NULL)) { + if (!trace_init_backends(optarg, NULL)) { exit(1); /* error message will have been printed */ } break; diff --git a/scripts/tracetool.py b/scripts/tracetool.py index 5f4890f..83bde7b 100755 --- a/scripts/tracetool.py +++ b/scripts/tracetool.py @@ -6,7 +6,7 @@ Command-line wrapper for the tracetool machinery. """ __author__ = "Lluís Vilanova <vilanova@ac.upc.edu>" -__copyright__ = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>" +__copyright__ = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>" __license__ = "GPL version 2 or (at your option) any later version" __maintainer__ = "Stefan Hajnoczi" @@ -32,7 +32,7 @@ def error_opt(msg = None): format_descr = "\n".join([ " %-15s %s" % (n, d) for n,d in tracetool.format.get_list() ]) error_write("""\ -Usage: %(script)s --format=<format> --backend=<backend> [<options>] +Usage: %(script)s --format=<format> --backends=<backends> [<options>] Backends: %(backends)s @@ -43,7 +43,7 @@ Formats: Options: --help This help message. --list-backends Print list of available backends. - --check-backend Check if the given backend is valid. + --check-backends Check if the given backend is valid. --binary <path> Full path to QEMU binary. --target-type <type> QEMU emulator target type ('system' or 'user'). --target-name <name> QEMU emulator target name. @@ -65,16 +65,17 @@ def main(args): global _SCRIPT _SCRIPT = args[0] - long_opts = [ "backend=", "format=", "help", "list-backends", "check-backend" ] - long_opts += [ "binary=", "target-type=", "target-name=", "probe-prefix=" ] + long_opts = ["backends=", "format=", "help", "list-backends", + "check-backends"] + long_opts += ["binary=", "target-type=", "target-name=", "probe-prefix="] try: opts, args = getopt.getopt(args[1:], "", long_opts) except getopt.GetoptError, err: error_opt(str(err)) - check_backend = False - arg_backend = "" + check_backends = False + arg_backends = [] arg_format = "" binary = None target_type = None @@ -84,8 +85,8 @@ def main(args): if opt == "--help": error_opt() - elif opt == "--backend": - arg_backend = arg + elif opt == "--backends": + arg_backends = arg.split(",") elif opt == "--format": arg_format = arg @@ -93,8 +94,8 @@ def main(args): public_backends = tracetool.backend.get_list(only_public = True) out(", ".join([ b for b,_ in public_backends ])) sys.exit(0) - elif opt == "--check-backend": - check_backend = True + elif opt == "--check-backends": + check_backends = True elif opt == "--binary": binary = arg @@ -108,14 +109,14 @@ def main(args): else: error_opt("unhandled option: %s" % opt) - if arg_backend is None: - error_opt("backend not set") + if len(arg_backends) == 0: + error_opt("no backends specified") - if check_backend: - if tracetool.backend.exists(arg_backend): - sys.exit(0) - else: - sys.exit(1) + if check_backends: + for backend in arg_backends: + if not tracetool.backend.exists(backend): + sys.exit(1) + sys.exit(0) if arg_format == "stap": if binary is None: @@ -126,11 +127,11 @@ def main(args): error_opt("--target-name is required for SystemTAP tapset generator") if probe_prefix is None: - probe_prefix = ".".join([ "qemu", target_type, target_name ]) + probe_prefix = ".".join(["qemu", target_type, target_name]) try: - tracetool.generate(sys.stdin, arg_format, arg_backend, - binary = binary, probe_prefix = probe_prefix) + tracetool.generate(sys.stdin, arg_format, arg_backends, + binary=binary, probe_prefix=probe_prefix) except tracetool.TracetoolError, e: error_opt(str(e)) diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py index eccf552..e8e8edc 100644 --- a/scripts/tracetool/__init__.py +++ b/scripts/tracetool/__init__.py @@ -233,9 +233,9 @@ def try_import(mod_name, attr_name=None, attr_default=None): return False, None -def generate(fevents, format, backend, +def generate(fevents, format, backends, binary=None, probe_prefix=None): - """Generate the output for the given (format, backend) pair. + """Generate the output for the given (format, backends) pair. Parameters ---------- @@ -243,8 +243,8 @@ def generate(fevents, format, backend, Event description file. format : str Output format name. - backend : str - Output backend name. + backends : list + Output backend names. binary : str or None See tracetool.backend.dtrace.BINARY. probe_prefix : str or None @@ -258,15 +258,13 @@ def generate(fevents, format, backend, raise TracetoolError("format not set") if not tracetool.format.exists(format): raise TracetoolError("unknown format: %s" % format) - format = format.replace("-", "_") - - backend = str(backend) - if len(backend) is 0: - raise TracetoolError("backend not set") - if not tracetool.backend.exists(backend): - raise TracetoolError("unknown backend: %s" % backend) - backend = backend.replace("-", "_") - backend = tracetool.backend.Wrapper(backend, format) + + if len(backends) is 0: + raise TracetoolError("no backends specified") + for backend in backends: + if not tracetool.backend.exists(backend): + raise TracetoolError("unknown backend: %s" % backend) + backend = tracetool.backend.Wrapper(backends, format) import tracetool.backend.dtrace tracetool.backend.dtrace.BINARY = binary diff --git a/scripts/tracetool/backend/__init__.py b/scripts/tracetool/backend/__init__.py index 5e36f04..5bfa1ef 100644 --- a/scripts/tracetool/backend/__init__.py +++ b/scripts/tracetool/backend/__init__.py @@ -99,17 +99,18 @@ def exists(name): class Wrapper: - def __init__(self, backend, format): - self._backend = backend.replace("-", "_") + def __init__(self, backends, format): + self._backends = [backend.replace("-", "_") for backend in backends] self._format = format.replace("-", "_") - assert exists(self._backend) + assert all(exists(backend) for backend in self._backends) assert tracetool.format.exists(self._format) def _run_function(self, name, *args, **kwargs): - func = tracetool.try_import("tracetool.backend." + self._backend, - name % self._format, None)[1] - if func is not None: - func(*args, **kwargs) + for backend in self._backends: + func = tracetool.try_import("tracetool.backend." + backend, + name % self._format, None)[1] + if func is not None: + func(*args, **kwargs) def generate_begin(self, events): self._run_function("generate_%s_begin", events) diff --git a/trace/Makefile.objs b/trace/Makefile.objs index 6a30467..d7a8696 100644 --- a/trace/Makefile.objs +++ b/trace/Makefile.objs @@ -3,12 +3,12 @@ ###################################################################### # Auto-generated event descriptions for LTTng ust code -ifeq ($(TRACE_BACKEND),ust) +ifeq ($(findstring ust,$(TRACE_BACKENDS)),ust) $(obj)/generated-ust-provider.h: $(obj)/generated-ust-provider.h-timestamp $(obj)/generated-ust-provider.h-timestamp: $(SRC_PATH)/trace-events $(call quiet-command,$(TRACETOOL) \ --format=ust-events-h \ - --backend=$(TRACE_BACKEND) \ + --backends=$(TRACE_BACKENDS) \ < $< > $@," GEN $(patsubst %-timestamp,%,$@)") @cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@) @@ -16,7 +16,7 @@ $(obj)/generated-ust.c: $(obj)/generated-ust.c-timestamp $(BUILD_DIR)/config-hos $(obj)/generated-ust.c-timestamp: $(SRC_PATH)/trace-events $(call quiet-command,$(TRACETOOL) \ --format=ust-events-c \ - --backend=$(TRACE_BACKEND) \ + --backends=$(TRACE_BACKENDS) \ < $< > $@," GEN $(patsubst %-timestamp,%,$@)") @cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@) @@ -31,7 +31,7 @@ $(obj)/generated-events.h: $(obj)/generated-events.h-timestamp $(obj)/generated-events.h-timestamp: $(SRC_PATH)/trace-events $(call quiet-command,$(TRACETOOL) \ --format=events-h \ - --backend=$(TRACE_BACKEND) \ + --backends=$(TRACE_BACKENDS) \ < $< > $@," GEN $(patsubst %-timestamp,%,$@)") @cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@) @@ -39,7 +39,7 @@ $(obj)/generated-events.c: $(obj)/generated-events.c-timestamp $(BUILD_DIR)/conf $(obj)/generated-events.c-timestamp: $(SRC_PATH)/trace-events $(call quiet-command,$(TRACETOOL) \ --format=events-c \ - --backend=$(TRACE_BACKEND) \ + --backends=$(TRACE_BACKENDS) \ < $< > $@," GEN $(patsubst %-timestamp,%,$@)") @cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@) @@ -54,23 +54,21 @@ $(obj)/generated-tracers.h: $(obj)/generated-tracers.h-timestamp $(obj)/generated-tracers.h-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak $(call quiet-command,$(TRACETOOL) \ --format=h \ - --backend=$(TRACE_BACKEND) \ + --backends=$(TRACE_BACKENDS) \ < $< > $@," GEN $(patsubst %-timestamp,%,$@)") ###################################################################### # Auto-generated tracing routines (non-DTrace) -ifneq ($(TRACE_BACKEND),dtrace) $(obj)/generated-tracers.c: $(obj)/generated-tracers.c-timestamp @cmp -s $< $@ || cp $< $@ $(obj)/generated-tracers.c-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak $(call quiet-command,$(TRACETOOL) \ --format=c \ - --backend=$(TRACE_BACKEND) \ + --backends=$(TRACE_BACKENDS) \ < $< > $@," GEN $(patsubst %-timestamp,%,$@)") $(obj)/generated-tracers.o: $(obj)/generated-tracers.c $(obj)/generated-tracers.h -endif ###################################################################### @@ -79,27 +77,27 @@ endif # Normal practice is to name DTrace probe file with a '.d' extension # but that gets picked up by QEMU's Makefile as an external dependency # rule file. So we use '.dtrace' instead -ifeq ($(TRACE_BACKEND),dtrace) -$(obj)/generated-tracers.dtrace: $(obj)/generated-tracers.dtrace-timestamp -$(obj)/generated-tracers.dtrace-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak +ifeq ($(findstring dtrace,$(TRACE_BACKENDS)),dtrace) +$(obj)/generated-tracers-dtrace.dtrace: $(obj)/generated-tracers-dtrace.dtrace-timestamp +$(obj)/generated-tracers-dtrace.dtrace-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak $(call quiet-command,$(TRACETOOL) \ --format=d \ - --backend=$(TRACE_BACKEND) \ + --backends=$(TRACE_BACKENDS) \ < $< > $@," GEN $(patsubst %-timestamp,%,$@)") @cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@) -$(obj)/generated-tracers-dtrace.h: $(obj)/generated-tracers.dtrace +$(obj)/generated-tracers-dtrace.h: $(obj)/generated-tracers-dtrace.dtrace $(call quiet-command,dtrace -o $@ -h -s $<, " GEN $@") -$(obj)/generated-tracers.o: $(obj)/generated-tracers.dtrace +$(obj)/generated-tracers-dtrace.o: $(obj)/generated-tracers-dtrace.dtrace + +util-obj-y += generated-tracers-dtrace.o endif ###################################################################### # Backend code -util-obj-$(CONFIG_TRACE_DEFAULT) += default.o util-obj-$(CONFIG_TRACE_SIMPLE) += simple.o -util-obj-$(CONFIG_TRACE_STDERR) += stderr.o util-obj-$(CONFIG_TRACE_FTRACE) += ftrace.o util-obj-$(CONFIG_TRACE_UST) += generated-ust.o util-obj-y += control.o diff --git a/trace/control-internal.h b/trace/control-internal.h index b3f587e..5a8df28 100644 --- a/trace/control-internal.h +++ b/trace/control-internal.h @@ -1,7 +1,7 @@ /* * Interface for configuring and controlling the state of tracing events. * - * Copyright (C) 2011-2012 Lluís Vilanova <vilanova@ac.upc.edu> + * Copyright (C) 2011-2014 Lluís Vilanova <vilanova@ac.upc.edu> * * This work is licensed under the terms of the GNU GPL, version 2 or later. * See the COPYING file in the top-level directory. @@ -61,7 +61,7 @@ static inline void trace_event_set_state_dynamic(TraceEvent *ev, bool state) { assert(ev != NULL); assert(trace_event_get_state_static(ev)); - return trace_event_set_state_dynamic_backend(ev, state); + ev->dstate = state; } #endif /* TRACE__CONTROL_INTERNAL_H */ diff --git a/trace/control.c b/trace/control.c index 4aa02cf..45e6604 100644 --- a/trace/control.c +++ b/trace/control.c @@ -1,13 +1,19 @@ /* * Interface for configuring and controlling the state of tracing events. * - * Copyright (C) 2011-2012 Lluís Vilanova <vilanova@ac.upc.edu> + * Copyright (C) 2011-2014 Lluís Vilanova <vilanova@ac.upc.edu> * * This work is licensed under the terms of the GNU GPL, version 2 or later. * See the COPYING file in the top-level directory. */ #include "trace/control.h" +#ifdef CONFIG_TRACE_SIMPLE +#include "trace/simple.h" +#endif +#ifdef CONFIG_TRACE_FTRACE +#include "trace/ftrace.h" +#endif TraceEvent *trace_event_name(const char *name) @@ -79,7 +85,20 @@ TraceEvent *trace_event_pattern(const char *pat, TraceEvent *ev) return NULL; } -void trace_backend_init_events(const char *fname) +void trace_print_events(FILE *stream, fprintf_function stream_printf) +{ + TraceEventID i; + + for (i = 0; i < trace_event_count(); i++) { + TraceEvent *ev = trace_event_id(i); + stream_printf(stream, "%s [Event ID %u] : state %u\n", + trace_event_get_name(ev), i, + trace_event_get_state_static(ev) && + trace_event_get_state_dynamic(ev)); + } +} + +static void trace_init_events(const char *fname) { if (fname == NULL) { return; @@ -130,3 +149,29 @@ void trace_backend_init_events(const char *fname) exit(1); } } + +bool trace_init_backends(const char *events, const char *file) +{ +#ifdef CONFIG_TRACE_SIMPLE + if (!st_init(file)) { + fprintf(stderr, "failed to initialize simple tracing backend.\n"); + return false; + } +#else + if (file) { + fprintf(stderr, "error: -trace file=...: " + "option not supported by the selected tracing backends\n"); + return false; + } +#endif + +#ifdef CONFIG_TRACE_FTRACE + if (!ftrace_init()) { + fprintf(stderr, "failed to initialize ftrace backend.\n"); + return false; + } +#endif + + trace_init_events(events); + return true; +} diff --git a/trace/control.h b/trace/control.h index cde8260..e1ec033 100644 --- a/trace/control.h +++ b/trace/control.h @@ -1,7 +1,7 @@ /* * Interface for configuring and controlling the state of tracing events. * - * Copyright (C) 2011-2012 Lluís Vilanova <vilanova@ac.upc.edu> + * Copyright (C) 2011-2014 Lluís Vilanova <vilanova@ac.upc.edu> * * This work is licensed under the terms of the GNU GPL, version 2 or later. * See the COPYING file in the top-level directory. @@ -146,26 +146,17 @@ static bool trace_event_get_state_dynamic(TraceEvent *ev); */ static void trace_event_set_state_dynamic(TraceEvent *ev, bool state); -/** - * trace_event_set_state_dynamic_backend: - * - * Warning: This function must be implemented by each tracing backend. - */ -void trace_event_set_state_dynamic_backend(TraceEvent *ev, bool state); - /** * trace_print_events: * * Print the state of all events. - * - * Warning: This function must be implemented by each tracing backend. */ void trace_print_events(FILE *stream, fprintf_function stream_printf); /** - * trace_backend_init: + * trace_init_backends: * @events: Name of file with events to be enabled at startup; may be NULL. * Corresponds to commandline option "-trace events=...". * @file: Name of trace output file; may be NULL. @@ -173,19 +164,9 @@ void trace_print_events(FILE *stream, fprintf_function stream_printf); * * Initialize the tracing backend. * - * Warning: This function must be implemented by each tracing backend. - * - * Returns: Whether the backend could be successfully initialized. - */ -bool trace_backend_init(const char *events, const char *file); - -/** - * trace_backend_init_events: - * @fname: Name of file with events to enable; may be NULL. - * - * Generic function to initialize the state of events. + * Returns: Whether the backends could be successfully initialized. */ -void trace_backend_init_events(const char *fname); +bool trace_init_backends(const char *events, const char *file); #include "trace/control-internal.h" diff --git a/trace/default.c b/trace/default.c deleted file mode 100644 index 6e07a47..0000000 --- a/trace/default.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Default implementation for backend initialization from commandline. - * - * Copyright (C) 2011-2012 Lluís Vilanova <vilanova@ac.upc.edu> - * - * This work is licensed under the terms of the GNU GPL, version 2. See - * the COPYING file in the top-level directory. - */ - -#include "trace/control.h" - - -void trace_print_events(FILE *stream, fprintf_function stream_printf) -{ - fprintf(stderr, "warning: " - "cannot print the trace events with the current backend\n"); - stream_printf(stream, "error: " - "operation not supported with the current backend\n"); -} - -void trace_event_set_state_dynamic_backend(TraceEvent *ev, bool state) -{ - fprintf(stderr, "warning: " - "cannot set the state of a trace event with the current backend\n"); -} - -bool trace_backend_init(const char *events, const char *file) -{ - if (events) { - fprintf(stderr, "error: -trace events=...: " - "option not supported by the selected tracing backend\n"); - return false; - } - if (file) { - fprintf(stderr, "error: -trace file=...: " - "option not supported by the selected tracing backend\n"); - return false; - } - return true; -} diff --git a/trace/ftrace.c b/trace/ftrace.c index 46b7fdb..a7ae371 100644 --- a/trace/ftrace.c +++ b/trace/ftrace.c @@ -42,35 +42,13 @@ static int find_debugfs(char *debugfs) return 1; } -void trace_print_events(FILE *stream, fprintf_function stream_printf) -{ - TraceEventID i; - - for (i = 0; i < trace_event_count(); i++) { - TraceEvent *ev = trace_event_id(i); - stream_printf(stream, "%s [Event ID %u] : state %u\n", - trace_event_get_name(ev), i, trace_event_get_state_dynamic(ev)); - } -} - -void trace_event_set_state_dynamic_backend(TraceEvent *ev, bool state) -{ - ev->dstate = state; -} - -bool trace_backend_init(const char *events, const char *file) +bool ftrace_init(void) { char debugfs[PATH_MAX]; char path[PATH_MAX]; int debugfs_found; int trace_fd = -1; - if (file) { - fprintf(stderr, "error: -trace file=...: " - "option not supported by the selected tracing backend\n"); - return false; - } - debugfs_found = find_debugfs(debugfs); if (debugfs_found) { snprintf(path, PATH_MAX, "%s/tracing/tracing_on", debugfs); @@ -97,6 +75,5 @@ bool trace_backend_init(const char *events, const char *file) return false; } - trace_backend_init_events(events); return true; } diff --git a/trace/ftrace.h b/trace/ftrace.h index 94cb8d5..863e052 100644 --- a/trace/ftrace.h +++ b/trace/ftrace.h @@ -1,10 +1,15 @@ #ifndef TRACE_FTRACE_H #define TRACE_FTRACE_H +#include <stdbool.h> + + #define MAX_TRACE_STRLEN 512 #define _STR(x) #x #define STR(x) _STR(x) extern int trace_marker_fd; +bool ftrace_init(void); + #endif /* ! TRACE_FTRACE_H */ diff --git a/trace/simple.c b/trace/simple.c index 5a2e188..a8f923c 100644 --- a/trace/simple.c +++ b/trace/simple.c @@ -368,22 +368,6 @@ void st_flush_trace_buffer(void) flush_trace_file(true); } -void trace_print_events(FILE *stream, fprintf_function stream_printf) -{ - unsigned int i; - - for (i = 0; i < trace_event_count(); i++) { - TraceEvent *ev = trace_event_id(i); - stream_printf(stream, "%s [Event ID %u] : state %u\n", - trace_event_get_name(ev), i, trace_event_get_state_dynamic(ev)); - } -} - -void trace_event_set_state_dynamic_backend(TraceEvent *ev, bool state) -{ - ev->dstate = state; -} - /* Helper function to create a thread with signals blocked. Use glib's * portable threads since QEMU abstractions cannot be used due to reentrancy in * the tracer. Also note the signal masking on POSIX hosts so that the thread @@ -412,7 +396,7 @@ static GThread *trace_thread_create(GThreadFunc fn) return thread; } -bool trace_backend_init(const char *events, const char *file) +bool st_init(const char *file) { GThread *thread; @@ -430,7 +414,6 @@ bool trace_backend_init(const char *events, const char *file) } atexit(st_flush_trace_buffer); - trace_backend_init_events(events); st_set_trace_file(file); return true; } diff --git a/trace/simple.h b/trace/simple.h index 5260d9a..6997996 100644 --- a/trace/simple.h +++ b/trace/simple.h @@ -21,6 +21,7 @@ void st_print_trace_file_status(FILE *stream, fprintf_function stream_printf); void st_set_trace_file_enabled(bool enable); bool st_set_trace_file(const char *file); +bool st_init(const char *file); void st_flush_trace_buffer(void); typedef struct { diff --git a/trace/stderr.c b/trace/stderr.c deleted file mode 100644 index e212efd..0000000 --- a/trace/stderr.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "trace.h" -#include "trace/control.h" - - -void trace_print_events(FILE *stream, fprintf_function stream_printf) -{ - TraceEventID i; - - for (i = 0; i < trace_event_count(); i++) { - TraceEvent *ev = trace_event_id(i); - stream_printf(stream, "%s [Event ID %u] : state %u\n", - trace_event_get_name(ev), i, trace_event_get_state_dynamic(ev)); - } -} - -void trace_event_set_state_dynamic_backend(TraceEvent *ev, bool state) -{ - ev->dstate = state; -} - -bool trace_backend_init(const char *events, const char *file) -{ - if (file) { - fprintf(stderr, "error: -trace file=...: " - "option not supported by the selected tracing backend\n"); - return false; - } - trace_backend_init_events(events); - return true; -} diff --git a/vl.c b/vl.c index a3def97..ac0e3d7 100644 --- a/vl.c +++ b/vl.c @@ -4039,7 +4039,7 @@ int main(int argc, char **argv, char **envp) } if (!is_daemonized()) { - if (!trace_backend_init(trace_events, trace_file)) { + if (!trace_init_backends(trace_events, trace_file)) { exit(1); } } @@ -4559,7 +4559,7 @@ int main(int argc, char **argv, char **envp) os_setup_post(); if (is_daemonized()) { - if (!trace_backend_init(trace_events, trace_file)) { + if (!trace_init_backends(trace_events, trace_file)) { exit(1); } } -- 1.9.3 ^ permalink raw reply related [flat|nested] 9+ messages in thread
end of thread, other threads:[~2014-06-16 9:59 UTC | newest] Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2014-06-09 15:23 [Qemu-devel] [PULL v2 0/5] Tracing pull request Stefan Hajnoczi 2014-06-09 15:23 ` [Qemu-devel] [PULL 1/5] trace: add pid field to simpletrace record Stefan Hajnoczi 2014-06-09 15:23 ` [Qemu-devel] [PULL 2/5] simpletrace: add support for trace record pid field Stefan Hajnoczi 2014-06-09 15:23 ` [Qemu-devel] [PULL 3/5] trace: Replace error with warning if event is not defined Stefan Hajnoczi 2014-06-09 15:23 ` [Qemu-devel] [PULL 4/5] trace: Multi-backend tracing Stefan Hajnoczi 2014-06-16 9:58 ` Peter Maydell 2014-06-09 15:23 ` [Qemu-devel] [PULL 5/5] trace: Replace fprintf with error_report and print location Stefan Hajnoczi 2014-06-09 16:03 ` [Qemu-devel] [PULL v2 0/5] Tracing pull request Peter Maydell -- strict thread matches above, loose matches on Subject: below -- 2014-06-09 13:45 [Qemu-devel] [PULL 0/5] Tracing patches Stefan Hajnoczi 2014-06-09 13:45 ` [Qemu-devel] [PULL 4/5] trace: Multi-backend tracing Stefan Hajnoczi
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.