From patchwork Mon Sep 6 15:14:06 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 63935 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id DC5AFB70E8 for ; Tue, 7 Sep 2010 01:22:46 +1000 (EST) Received: from localhost ([127.0.0.1]:33852 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OsdWo-0001XY-Ua for incoming@patchwork.ozlabs.org; Mon, 06 Sep 2010 11:22:39 -0400 Received: from [140.186.70.92] (port=48004 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OsdPa-00057s-FQ for qemu-devel@nongnu.org; Mon, 06 Sep 2010 11:15:27 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1OsdPN-0003yw-VP for qemu-devel@nongnu.org; Mon, 06 Sep 2010 11:15:10 -0400 Received: from mtagate2.de.ibm.com ([195.212.17.162]:33240) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1OsdPN-0003xm-Fo for qemu-devel@nongnu.org; Mon, 06 Sep 2010 11:14:57 -0400 Received: from d12nrmr1607.megacenter.de.ibm.com (d12nrmr1607.megacenter.de.ibm.com [9.149.167.49]) by mtagate2.de.ibm.com (8.13.1/8.13.1) with ESMTP id o86FEuJs011635 for ; Mon, 6 Sep 2010 15:14:56 GMT Received: from d12av02.megacenter.de.ibm.com (d12av02.megacenter.de.ibm.com [9.149.165.228]) by d12nrmr1607.megacenter.de.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id o86FEsQx3215596 for ; Mon, 6 Sep 2010 17:14:55 +0200 Received: from d12av02.megacenter.de.ibm.com (loopback [127.0.0.1]) by d12av02.megacenter.de.ibm.com (8.12.11.20060308/8.13.3) with ESMTP id o86FErGq018158 for ; Mon, 6 Sep 2010 17:14:54 +0200 Received: from stefan-thinkpad.manchester-maybrook.uk.ibm.com (dyn-9-174-219-60.manchester-maybrook.uk.ibm.com [9.174.219.60]) by d12av02.megacenter.de.ibm.com (8.12.11.20060308/8.12.11) with ESMTP id o86FEmNf017891; Mon, 6 Sep 2010 17:14:53 +0200 From: Stefan Hajnoczi To: Date: Mon, 6 Sep 2010 16:14:06 +0100 Message-Id: <1283786051-29530-10-git-send-email-stefanha@linux.vnet.ibm.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1283786051-29530-1-git-send-email-stefanha@linux.vnet.ibm.com> References: <1283786051-29530-1-git-send-email-stefanha@linux.vnet.ibm.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6, seldom 2.4 (older, 4) Cc: Blue Swirl , Anthony Liguori , "Michael S. Tsirkin" , Stefan Hajnoczi , Prerna Saxena Subject: [Qemu-devel] [PATCH 09/14] trace: Add user documentation X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Signed-off-by: Stefan Hajnoczi --- docs/tracing.txt | 177 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 177 insertions(+), 0 deletions(-) create mode 100644 docs/tracing.txt diff --git a/docs/tracing.txt b/docs/tracing.txt new file mode 100644 index 0000000..ae01ff1 --- /dev/null +++ b/docs/tracing.txt @@ -0,0 +1,177 @@ += Tracing = + +== Introduction == + +This document describes the tracing infrastructure in QEMU and how to use it +for debugging, profiling, and observing execution. + +== Quickstart == + +1. Build with the 'simple' trace backend: + + ./configure --trace-backend=simple + make + +2. Enable trace events you are interested in: + + $EDITOR trace-events # remove "disable" from events you want + +3. Run the virtual machine to produce a trace file: + + qemu ... # your normal QEMU invocation + +4. Pretty-print the binary trace file: + + ./simpletrace.py trace-events trace-* + +== Trace events == + +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 +generate code for the trace events. Trace events are invoked directly from +source code like this: + + #include "trace.h" /* needed for trace event prototype */ + + void *qemu_malloc(size_t size) + { + void *ptr; + if (!size && !allow_zero_malloc()) { + abort(); + } + ptr = oom_check(malloc(size ? size : 1)); + trace_qemu_malloc(size, ptr); /* <-- trace event */ + return ptr; + } + +=== Declaring trace events === + +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 events should use types as follows: + + * Use stdint.h types for fixed-size types. Most offsets and guest memory + addresses are best represented with uint32_t or uint64_t. Use fixed-size + types over primitive types whose size may change depending on the host + (32-bit versus 64-bit) so trace events don't truncate values or break + the build. + + * Use void * for pointers to structs or for arrays. The trace.h header + cannot include all user-defined struct declarations and it is therefore + necessary to use void * for pointers to structs. + + * For everything else, use primitive scalar types (char, int, long) with the + appropriate signedness. + +=== Hints for adding new trace events === + +1. Trace state changes in the code. Interesting points in the code usually + involve a state change like starting, stopping, allocating, freeing. State + changes are good trace events because they can be used to understand the + execution of the system. + +2. Trace guest operations. Guest I/O accesses like reading device registers + are good trace events because they can be used to understand guest + interactions. + +3. Use correlator fields so the context of an individual line of trace output + can be understood. For example, trace the pointer returned by malloc and + used as an argument to free. This way mallocs and frees can be matched up. + Trace events with no context are not very useful. + +4. Name trace events after their function. If there are multiple trace events + in one function, append a unique distinguisher at the end of the name. + +5. Declare trace events with the "disable" keyword. Some trace events can + produce a lot of output and users are typically only interested in a subset + of trace events. Marking trace events disabled by default saves the user + from having to manually disable noisy trace events. + +== Trace backends == + +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 +script. + +The trace backend is chosen at configure time and only one trace backend can +be built into the binary: + + ./configure --trace-backend=simple + +For a list of supported trace backends, try ./configure --help or see below. + +The following subsections describe the supported trace backends. + +=== Nop === + +The "nop" backend generates empty trace event functions so that the compiler +can optimize out trace events completely. This is the default and imposes no +performance penalty. + +=== Simpletrace === + +The "simple" backend supports common use cases and comes as part of the QEMU +source tree. It may not be as powerful as platform-specific or third-party +trace backends but it is portable. This is the recommended trace backend +unless you have specific needs for more advanced backends. + +==== Monitor commands ==== + +* info trace + Display the contents of trace buffer. This command dumps the trace buffer + with simple formatting. For full pretty-printing, use the simpletrace.py + script on a binary trace file. + + The trace buffer is written into until full. The full trace buffer is + flushed and emptied. This means the 'info trace' will display few or no + entries if the buffer has just been flushed. + +* info trace-events + View available trace events and their state. State 1 means enabled, state 0 + means disabled. + +* trace-event NAME on|off + Enable/disable a given trace event. + +* trace-file on|off|flush|set + Enable/disable/flush the trace file or set the trace file name. + +==== Enabling/disabling trace events programmatically ==== + +The st_change_trace_event_state() function can be used to enable or disable trace +events at runtime inside QEMU: + + #include "trace.h" + + st_change_trace_event_state("virtio_irq", true); /* enable */ + [...] + st_change_trace_event_state("virtio_irq", false); /* disable */ + +==== 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 +trace: + + ./simpletrace.py trace-events trace-12345 + +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. + +=== LTTng Userspace Tracer === + +The "ust" backend uses the LTTng Userspace Tracer library. There are no +monitor commands built into QEMU, instead UST utilities should be used to list, +enable/disable, and dump traces.