diff --git a/Makefile b/Makefile index b33aaacde6..f5052026da 100644 --- a/Makefile +++ b/Makefile @@ -418,6 +418,7 @@ endif set -e; for x in $(KEYMAPS); do \ $(INSTALL_DATA) $(SRC_PATH)/pc-bios/keymaps/$$x "$(DESTDIR)$(qemu_datadir)/keymaps"; \ done + $(INSTALL_DATA) $(SRC_PATH)/trace-events "$(DESTDIR)$(qemu_datadir)/trace-events" for d in $(TARGET_DIRS); do \ $(MAKE) $(SUBDIR_MAKEFLAGS) TARGET_DIR=$$d/ -C $$d $@ || exit 1 ; \ done diff --git a/block/iscsi.c b/block/iscsi.c index 3c1b416704..5c72ffeb31 100644 --- a/block/iscsi.c +++ b/block/iscsi.c @@ -34,7 +34,6 @@ #include "qemu/bitops.h" #include "qemu/bitmap.h" #include "block/block_int.h" -#include "trace.h" #include "block/scsi.h" #include "qemu/iov.h" #include "sysemu/sysemu.h" diff --git a/docs/tracing.txt b/docs/tracing.txt index 2e035a5b3c..7d38926394 100644 --- a/docs/tracing.txt +++ b/docs/tracing.txt @@ -23,7 +23,7 @@ for debugging, profiling, and observing execution. 4. Pretty-print the binary trace file: - ./scripts/simpletrace.py trace-events trace-* + ./scripts/simpletrace.py trace-events trace-* # Override * with QEMU == Trace events == diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c index 7ea871ddf2..9a84eb6950 100644 --- a/hw/usb/hcd-ohci.c +++ b/hw/usb/hcd-ohci.c @@ -723,11 +723,13 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed, trace_usb_ohci_iso_td_head( ed->head & OHCI_DPTR_MASK, ed->tail & OHCI_DPTR_MASK, iso_td.flags, iso_td.bp, iso_td.next, iso_td.be, - iso_td.offset[0], iso_td.offset[1], iso_td.offset[2], iso_td.offset[3], - iso_td.offset[4], iso_td.offset[5], iso_td.offset[6], iso_td.offset[7], - ohci->frame_number, starting_frame, - frame_count, relative_frame_number, - OHCI_BM(iso_td.flags, TD_DI), OHCI_BM(iso_td.flags, TD_CC)); + ohci->frame_number, starting_frame, + frame_count, relative_frame_number); + trace_usb_ohci_iso_td_head_offset( + iso_td.offset[0], iso_td.offset[1], + iso_td.offset[2], iso_td.offset[3], + iso_td.offset[4], iso_td.offset[5], + iso_td.offset[6], iso_td.offset[7]); if (relative_frame_number < 0) { trace_usb_ohci_iso_td_relative_frame_number_neg(relative_frame_number); @@ -1199,13 +1201,14 @@ static int ohci_service_ed_list(OHCIState *ohci, uint32_t head, int completion) } while ((ed.head & OHCI_DPTR_MASK) != ed.tail) { - trace_usb_ohci_ed_pkt(cur, + trace_usb_ohci_ed_pkt(cur, (ed.head & OHCI_ED_H) != 0, + (ed.head & OHCI_ED_C) != 0, ed.head & OHCI_DPTR_MASK, + ed.tail & OHCI_DPTR_MASK, ed.next & OHCI_DPTR_MASK); + trace_usb_ohci_ed_pkt_flags( OHCI_BM(ed.flags, ED_FA), OHCI_BM(ed.flags, ED_EN), OHCI_BM(ed.flags, ED_D), (ed.flags & OHCI_ED_S)!= 0, (ed.flags & OHCI_ED_K) != 0, (ed.flags & OHCI_ED_F) != 0, - OHCI_BM(ed.flags, ED_MPS), (ed.head & OHCI_ED_H) != 0, - (ed.head & OHCI_ED_C) != 0, ed.head & OHCI_DPTR_MASK, - ed.tail & OHCI_DPTR_MASK, ed.next & OHCI_DPTR_MASK); + OHCI_BM(ed.flags, ED_MPS)); active = 1; diff --git a/monitor.c b/monitor.c index 667efb7a64..b96710e212 100644 --- a/monitor.c +++ b/monitor.c @@ -886,19 +886,12 @@ static void do_trace_event_set_state(Monitor *mon, const QDict *qdict) { const char *tp_name = qdict_get_str(qdict, "name"); bool new_state = qdict_get_bool(qdict, "option"); + Error *local_err = NULL; - bool found = false; - TraceEvent *ev = NULL; - while ((ev = trace_event_pattern(tp_name, ev)) != NULL) { - found = true; - if (!trace_event_get_state_static(ev)) { - monitor_printf(mon, "event \"%s\" is not traceable\n", tp_name); - } else { - trace_event_set_state_dynamic(ev, new_state); - } - } - if (!trace_event_is_pattern(tp_name) && !found) { - monitor_printf(mon, "unknown event name \"%s\"\n", tp_name); + qmp_trace_event_set_state(tp_name, new_state, true, true, &local_err); + if (local_err) { + qerror_report_err(local_err); + error_free(local_err); } } @@ -1079,7 +1072,15 @@ static void do_info_cpu_stats(Monitor *mon, const QDict *qdict) static void do_trace_print_events(Monitor *mon, const QDict *qdict) { - trace_print_events((FILE *)mon, &monitor_fprintf); + TraceEventInfoList *events = qmp_trace_event_get_state("*", NULL); + TraceEventInfoList *elem; + + for (elem = events; elem != NULL; elem = elem->next) { + monitor_printf(mon, "%s : state %u\n", + elem->value->name, + elem->value->state == TRACE_EVENT_STATE_ENABLED ? 1 : 0); + } + qapi_free_TraceEventInfoList(events); } static int client_migrate_info(Monitor *mon, const QDict *qdict, diff --git a/qapi-schema.json b/qapi-schema.json index 689b548abf..4bfaf20ebe 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -11,6 +11,9 @@ # QAPI event definitions { 'include': 'qapi/event.json' } +# Tracing commands +{ 'include': 'qapi/trace.json' } + ## # LostTickPolicy: # diff --git a/qapi/trace.json b/qapi/trace.json new file mode 100644 index 0000000000..06c613c213 --- /dev/null +++ b/qapi/trace.json @@ -0,0 +1,65 @@ +# -*- mode: python -*- +# +# Copyright (C) 2011-2014 Lluís Vilanova +# +# This work is licensed under the terms of the GNU GPL, version 2 or later. +# See the COPYING file in the top-level directory. + + +## +# @TraceEventState: +# +# State of a tracing event. +# +# @unavailable: The event is statically disabled. +# +# @disabled: The event is dynamically disabled. +# +# @enabled: The event is dynamically enabled. +# +# Since 2.2 +## +{ 'enum': 'TraceEventState', + 'data': ['unavailable', 'disabled', 'enabled'] } + +## +# @TraceEventInfo: +# +# Information of a tracing event. +# +# @name: Event name. +# @state: Tracing state. +# +# Since 2.2 +## +{ 'type': 'TraceEventInfo', + 'data': {'name': 'str', 'state': 'TraceEventState'} } + +## +# @trace-event-get-state: +# +# Query the state of events. +# +# @name: Event name pattern (case-sensitive glob). +# +# Returns: a list of @TraceEventInfo for the matching events +# +# Since 2.2 +## +{ 'command': 'trace-event-get-state', + 'data': {'name': 'str'}, + 'returns': ['TraceEventInfo'] } + +## +# @trace-event-set-state: +# +# Set the dynamic tracing state of events. +# +# @name: Event name pattern (case-sensitive glob). +# @enable: Whether to enable tracing. +# @ignore-unavailable: #optional Do not match unavailable events with @name. +# +# Since 2.2 +## +{ 'command': 'trace-event-set-state', + 'data': {'name': 'str', 'enable': 'bool', '*ignore-unavailable': 'bool'} } diff --git a/qmp-commands.hx b/qmp-commands.hx index 76656cc074..f581813fde 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -3752,5 +3752,40 @@ Example: -> { "execute": "rtc-reset-reinjection" } <- { "return": {} } - +EQMP + + { + .name = "trace-event-get-state", + .args_type = "name:s", + .mhandler.cmd_new = qmp_marshal_input_trace_event_get_state, + }, + +SQMP +trace-event-get-state +--------------------- + +Query the state of events. + +Example: + +-> { "execute": "trace-event-get-state", "arguments": { "name": "qemu_memalign" } } +<- { "return": [ { "name": "qemu_memalign", "state": "disabled" } ] } +EQMP + + { + .name = "trace-event-set-state", + .args_type = "name:s,enable:b,ignore-unavailable:b?", + .mhandler.cmd_new = qmp_marshal_input_trace_event_set_state, + }, + +SQMP +trace-event-set-state +--------------------- + +Set the state of events. + +Example: + +-> { "execute": "trace-event-set-state", "arguments": { "name": "qemu_memalign", "enable": "true" } } +<- { "return": {} } EQMP diff --git a/scripts/cleanup-trace-events.pl b/scripts/cleanup-trace-events.pl index cffbf165dc..7e808efb6a 100755 --- a/scripts/cleanup-trace-events.pl +++ b/scripts/cleanup-trace-events.pl @@ -25,7 +25,7 @@ sub out { while (<>) { if (/^(disable )?([a-z_0-9]+)\(/) { - open GREP, '-|', 'git', 'grep', '-l', "trace_$2" + open GREP, '-|', 'git', 'grep', '-lw', "trace_$2" or die "run git grep: $!"; my $fname; while ($fname = ) { diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py index 36c789de8f..3d5743f93e 100644 --- a/scripts/tracetool/__init__.py +++ b/scripts/tracetool/__init__.py @@ -136,21 +136,19 @@ class Event(object): Properties of the event. args : Arguments The event arguments. - arg_fmts : str - The format strings for each argument. + """ - _CRE = re.compile("((?P.*)\s+)?" - "(?P[^(\s]+)" + _CRE = re.compile("((?P[\w\s]+)\s+)?" + "(?P\w+)" "\((?P[^)]*)\)" "\s*" "(?:(?:(?P\".+),)?\s*(?P\".+))?" "\s*") - _FMT = re.compile("(%\w+|%.*PRI\S+)") _VALID_PROPS = set(["disable", "tcg", "tcg-trans", "tcg-exec"]) - def __init__(self, name, props, fmt, args, arg_fmts, orig=None): + def __init__(self, name, props, fmt, args, orig=None): """ Parameters ---------- @@ -162,8 +160,6 @@ class Event(object): Event printing format (or formats). args : Arguments Event arguments. - arg_fmts : list of str - Format strings for each argument. orig : Event or None Original Event before transformation. @@ -172,7 +168,6 @@ class Event(object): self.properties = props self.fmt = fmt self.args = args - self.arg_fmts = arg_fmts if orig is None: self.original = weakref.ref(self) @@ -210,7 +205,6 @@ class Event(object): if len(fmt_trans) > 0: fmt = [fmt_trans, fmt] args = Arguments.build(groups["args"]) - arg_fmts = Event._FMT.findall(fmt) if "tcg-trans" in props: raise ValueError("Invalid property 'tcg-trans'") @@ -221,7 +215,7 @@ class Event(object): if "tcg" in props and isinstance(fmt, str): raise ValueError("Events with 'tcg' property must have two formats") - return Event(name, props, fmt, args, arg_fmts) + return Event(name, props, fmt, args) def __repr__(self): """Evaluable string representation for this object.""" @@ -234,6 +228,13 @@ class Event(object): self.args, fmt) + _FMT = re.compile("(%[\d\.]*\w+|%.*PRI\S+)") + + def formats(self): + """List of argument print formats.""" + assert not isinstance(self.fmt, list) + return self._FMT.findall(self.fmt) + QEMU_TRACE = "trace_%(name)s" QEMU_TRACE_TCG = QEMU_TRACE + "_tcg" diff --git a/scripts/tracetool/format/ust_events_h.py b/scripts/tracetool/format/ust_events_h.py index d18989942a..3e8a7cdf19 100644 --- a/scripts/tracetool/format/ust_events_h.py +++ b/scripts/tracetool/format/ust_events_h.py @@ -65,7 +65,7 @@ def generate(events, backend): types = e.args.types() names = e.args.names() - fmts = e.arg_fmts + fmts = e.formats() for t,n,f in zip(types, names, fmts): if ('char *' in t) or ('char*' in t): out(' ctf_string(' + n + ', ' + n + ')') diff --git a/trace-events b/trace-events index 1bb0fa92a6..9153f983f4 100644 --- a/trace-events +++ b/trace-events @@ -121,7 +121,6 @@ virtio_blk_handle_read(void *req, uint64_t sector, size_t nsectors) "req %p sect virtio_blk_data_plane_start(void *s) "dataplane %p" virtio_blk_data_plane_stop(void *s) "dataplane %p" virtio_blk_data_plane_process_request(void *s, unsigned int out_num, unsigned int in_num, unsigned int head) "dataplane %p out_num %u in_num %u head %u" -virtio_blk_data_plane_complete_request(void *s, unsigned int head, int ret) "dataplane %p head %u ret %d" # hw/virtio/dataplane/vring.c vring_setup(uint64_t physical, void *desc, void *avail, void *used) "vring physical %#"PRIx64" desc %p avail %p used %p" @@ -297,7 +296,8 @@ usb_port_release(int bus, const char *port) "bus %d, port %s" # hw/usb/hcd-ohci.c usb_ohci_iso_td_read_failed(uint32_t addr) "ISO_TD read error at %x" -usb_ohci_iso_td_head(uint32_t head, uint32_t tail, uint32_t flags, uint32_t bp, uint32_t next, uint32_t be, uint32_t o0, uint32_t o1, uint32_t o2, uint32_t o3, uint32_t o4, uint32_t o5, uint32_t o6, uint32_t o7, uint32_t framenum, uint32_t startframe, uint32_t framecount, int rel_frame_num, uint32_t bm_di, uint32_t td_cc) "ISO_TD ED head 0x%.8x tailp 0x%.8x\n0x%.8x 0x%.8x 0x%.8x 0x%.8x\n0x%.8x 0x%.8x 0x%.8x 0x%.8x\n0x%.8x 0x%.8x 0x%.8x 0x%.8x\nframe_number 0x%.8x starting_frame 0x%.8x\nframe_count 0x%.8x relative %d\ndi 0x%.8x cc 0x%.8x" +usb_ohci_iso_td_head(uint32_t head, uint32_t tail, uint32_t flags, uint32_t bp, uint32_t next, uint32_t be, uint32_t framenum, uint32_t startframe, uint32_t framecount, int rel_frame_num) "ISO_TD ED head 0x%.8x tailp 0x%.8x\n0x%.8x 0x%.8x 0x%.8x 0x%.8x\nframe_number 0x%.8x starting_frame 0x%.8x\nframe_count 0x%.8x relative %d" +usb_ohci_iso_td_head_offset(uint32_t o0, uint32_t o1, uint32_t o2, uint32_t o3, uint32_t o4, uint32_t o5, uint32_t o6, uint32_t o7) "0x%.8x 0x%.8x 0x%.8x 0x%.8x 0x%.8x 0x%.8x 0x%.8x 0x%.8x" usb_ohci_iso_td_relative_frame_number_neg(int rel) "ISO_TD R=%d < 0" usb_ohci_iso_td_relative_frame_number_big(int rel, int count) "ISO_TD R=%d > FC=%d" usb_ohci_iso_td_bad_direction(int dir) "Bad direction %d" @@ -336,7 +336,8 @@ usb_ohci_td_pkt_full(const char *dir, const char *buf) "%s data: %s" usb_ohci_td_too_many_pending(void) "" usb_ohci_td_packet_status(int status) "status=%d" usb_ohci_ed_read_error(uint32_t addr) "ED read error at %x" -usb_ohci_ed_pkt(uint32_t cur, uint32_t fa, uint32_t en, uint32_t d, int s, int k, int f, uint32_t mps, int h, int c, uint32_t head, uint32_t tail, uint32_t next) "ED @ 0x%.8x fa=%u en=%u d=%u s=%u k=%u f=%u mps=%u h=%u c=%u\n head=0x%.8x tailp=0x%.8x next=0x%.8x" +usb_ohci_ed_pkt(uint32_t cur, int h, int c, uint32_t head, uint32_t tail, uint32_t next) "ED @ 0x%.8x h=%u c=%u\n head=0x%.8x tailp=0x%.8x next=0x%.8x" +usb_ohci_ed_pkt_flags(uint32_t fa, uint32_t en, uint32_t d, int s, int k, int f, uint32_t mps) "fa=%u en=%u d=%u s=%u k=%u f=%u mps=%u" usb_ohci_hcca_read_error(uint32_t addr) "HCCA read error at %x" usb_ohci_mem_read_unaligned(uint32_t addr) "at %x" usb_ohci_mem_read_bad_offset(uint32_t addr) "%x" @@ -503,7 +504,6 @@ usb_mtp_command(int dev, uint16_t code, uint32_t trans, uint32_t arg0, uint32_t usb_mtp_success(int dev, uint32_t trans, uint32_t arg0, uint32_t arg1) "dev %d, trans 0x%x, args 0x%x, 0x%x" usb_mtp_error(int dev, uint16_t code, uint32_t trans, uint32_t arg0, uint32_t arg1) "dev %d, code 0x%x, trans 0x%x, args 0x%x, 0x%x" usb_mtp_data_in(int dev, uint32_t trans, uint32_t len) "dev %d, trans 0x%x, len %d" -usb_mtp_data_out(int dev, uint32_t trans, uint32_t len) "dev %d, trans 0x%x, len %d" usb_mtp_xfer(int dev, uint32_t ep, uint32_t dlen, uint32_t plen) "dev %d, ep %d, %d/%d" usb_mtp_nak(int dev, uint32_t ep) "dev %d, ep %d" usb_mtp_stall(int dev, const char *reason) "dev %d, reason: %s" @@ -726,8 +726,6 @@ megasas_io_target_not_present(int cmd, const char *frame, int dev, int lun) "scm megasas_io_read_start(int cmd, unsigned long lba, unsigned long count, unsigned long len) "scmd %d: start LBA %lx %lu blocks (%lu bytes)" megasas_io_write_start(int cmd, unsigned long lba, unsigned long count, unsigned long len) "scmd %d: start LBA %lx %lu blocks (%lu bytes)" megasas_io_complete(int cmd, uint32_t len) "scmd %d: %d bytes completed" -megasas_io_read(int cmd, int bytes, int len, unsigned long offset) "scmd %d: %d/%d bytes, iov offset %lu" -megasas_io_write(int cmd, int bytes, int len, unsigned long offset) "scmd %d: %d/%d bytes, iov offset %lu" megasas_iovec_sgl_overflow(int cmd, int index, int limit) "scmd %d: iovec count %d limit %d" megasas_iovec_sgl_underflow(int cmd, int index) "scmd %d: iovec count %d" megasas_iovec_sgl_invalid(int cmd, int index, uint64_t pa, uint32_t len) "scmd %d: element %d pa %" PRIx64 " len %u" @@ -894,7 +892,7 @@ pvscsi_state(const char* state) "starting %s ..." pvscsi_tx_rings_ppn(const char* label, uint64_t ppn) "%s page: %"PRIx64"" pvscsi_tx_rings_num_pages(const char* label, uint32_t num) "Number of %s pages: %u" -# xen-all.c +# xen-hvm.c xen_ram_alloc(unsigned long ram_addr, unsigned long size) "requested: %#lx, size %#lx" xen_client_set_memory(uint64_t start_addr, unsigned long size, bool log_dirty) "%#"PRIx64" size %#lx, log_dirty %i" @@ -903,7 +901,7 @@ xen_map_cache(uint64_t phys_addr) "want %#"PRIx64 xen_remap_bucket(uint64_t index) "index %#"PRIx64 xen_map_cache_return(void* ptr) "%p" -# hw/xen/xen_platform.c +# hw/i386/xen/xen_platform.c xen_platform_log(char *s) "xen platform: %s" # qemu-coroutine.c @@ -934,12 +932,6 @@ escc_sunkbd_event_out(int ch) "Translated keycode 0x%2.2x" escc_kbd_command(int val) "Command %d" escc_sunmouse_event(int dx, int dy, int buttons_state) "dx=%d dy=%d buttons=%01x" -# block/iscsi.c -iscsi_aio_write16_cb(void *iscsi, int status, void *acb, int canceled) "iscsi %p status %d acb %p canceled %d" -iscsi_aio_writev(void *iscsi, int64_t sector_num, int nb_sectors, void *opaque, void *acb) "iscsi %p sector_num %"PRId64" nb_sectors %d opaque %p acb %p" -iscsi_aio_read16_cb(void *iscsi, int status, void *acb, int canceled) "iscsi %p status %d acb %p canceled %d" -iscsi_aio_readv(void *iscsi, int64_t sector_num, int nb_sectors, void *opaque, void *acb) "iscsi %p sector_num %"PRId64" nb_sectors %d opaque %p acb %p" - # hw/scsi/esp.c esp_error_fifo_overrun(void) "FIFO overrun" esp_error_unhandled_command(uint32_t val) "unhandled command (%2.2x)" @@ -993,7 +985,6 @@ esp_pci_sbac_write(uint32_t reg, uint32_t val) "sbac: 0x%8.8x -> 0x%8.8x" # monitor.c handle_qmp_command(void *mon, const char *cmd_name) "mon %p cmd_name \"%s\"" monitor_protocol_emitter(void *mon) "mon %p" -monitor_protocol_event(uint32_t event, const char *evname, void *data) "event=%d name \"%s\" data %p" monitor_protocol_event_handler(uint32_t event, void *data, uint64_t last, uint64_t now) "event=%d data=%p last=%" PRId64 " now=%" PRId64 monitor_protocol_event_emit(uint32_t event, void *data) "event=%d data=%p" monitor_protocol_event_queue(uint32_t event, void *data, uint64_t rate, uint64_t last, uint64_t now) "event=%d data=%p rate=%" PRId64 " last=%" PRId64 " now=%" PRId64 @@ -1148,9 +1139,11 @@ savevm_state_complete(void) "" savevm_state_cancel(void) "" vmstate_save(const char *idstr, const char *vmsd_name) "%s, %s" vmstate_load(const char *idstr, const char *vmsd_name) "%s, %s" -vmstate_load_field_error(const char *field, int ret) "field \"%s\" load failed, ret = %d" qemu_announce_self_iter(const char *mac) "%s" +# vmstate.c +vmstate_load_field_error(const char *field, int ret) "field \"%s\" load failed, ret = %d" + # qemu-file.c qemu_file_fclose(void) "" @@ -1305,7 +1298,7 @@ css_adapter_interrupt(uint8_t isc) "CSS: adapter I/O interrupt (isc %x)" virtio_ccw_interpret_ccw(int cssid, int ssid, int schid, int cmd_code) "VIRTIO-CCW: %x.%x.%04x: interpret command %x" virtio_ccw_new_device(int cssid, int ssid, int schid, int devno, const char *devno_mode) "VIRTIO-CCW: add subchannel %x.%x.%04x, devno %04x (%s)" -# hw/intc/s390_flic.c +# hw/intc/s390_flic_kvm.c flic_create_device(int err) "flic: create device failed %d" flic_no_device_api(int err) "flic: no Device Contral API support %d" flic_reset_failed(int err) "flic: reset failed %d" @@ -1324,11 +1317,13 @@ kvm_vm_ioctl(int type, void *arg) "type 0x%x, arg %p" kvm_vcpu_ioctl(int cpu_index, int type, void *arg) "cpu_index %d, type 0x%x, arg %p" kvm_run_exit(int cpu_index, uint32_t reason) "cpu_index %d, reason %d" kvm_device_ioctl(int fd, int type, void *arg) "dev fd %d, type 0x%x, arg %p" -kvm_failed_spr_set(int str, const char *msg) "Warning: Unable to set SPR %d to KVM: %s" -kvm_failed_spr_get(int str, const char *msg) "Warning: Unable to retrieve SPR %d from KVM: %s" kvm_failed_reg_get(uint64_t id, const char *msg) "Warning: Unable to retrieve ONEREG %" PRIu64 " from KVM: %s" kvm_failed_reg_set(uint64_t id, const char *msg) "Warning: Unable to set ONEREG %" PRIu64 " to KVM: %s" +# target-ppc/kvm.c +kvm_failed_spr_set(int str, const char *msg) "Warning: Unable to set SPR %d to KVM: %s" +kvm_failed_spr_get(int str, const char *msg) "Warning: Unable to retrieve SPR %d from KVM: %s" + # TCG related tracing (mostly disabled by default) # cpu-exec.c disable exec_tb(void *tb, uintptr_t pc) "tb:%p pc=0x%"PRIxPTR @@ -1346,7 +1341,7 @@ memory_region_ops_write(void *mr, uint64_t addr, uint64_t value, unsigned size) object_dynamic_cast_assert(const char *type, const char *target, const char *file, int line, const char *func) "%s->%s (%s:%d:%s)" object_class_dynamic_cast_assert(const char *type, const char *target, const char *file, int line, const char *func) "%s->%s (%s:%d:%s)" -# hw/xen/xen_pvdevice.c +# hw/i386/xen/xen_pvdevice.c xen_pv_mmio_read(uint64_t addr) "WARNING: read from Xen PV Device MMIO space (address %"PRIx64")" xen_pv_mmio_write(uint64_t addr) "WARNING: write to Xen PV Device MMIO space (address %"PRIx64")" @@ -1354,7 +1349,7 @@ xen_pv_mmio_write(uint64_t addr) "WARNING: write to Xen PV Device MMIO space (ad pci_cfg_read(const char *dev, unsigned devid, unsigned fnid, unsigned offs, unsigned val) "%s %02u:%u @0x%x -> 0x%x" pci_cfg_write(const char *dev, unsigned devid, unsigned fnid, unsigned offs, unsigned val) "%s %02u:%u @0x%x <- 0x%x" -#hw/acpi/memory_hotplug.c +# hw/acpi/memory_hotplug.c mhp_acpi_invalid_slot_selected(uint32_t slot) "0x%"PRIx32 mhp_acpi_read_addr_lo(uint32_t slot, uint32_t addr) "slot[0x%"PRIx32"] addr lo: 0x%"PRIx32 mhp_acpi_read_addr_hi(uint32_t slot, uint32_t addr) "slot[0x%"PRIx32"] addr hi: 0x%"PRIx32 @@ -1367,7 +1362,7 @@ mhp_acpi_write_ost_ev(uint32_t slot, uint32_t ev) "slot[0x%"PRIx32"] OST EVENT: mhp_acpi_write_ost_status(uint32_t slot, uint32_t st) "slot[0x%"PRIx32"] OST STATUS: 0x%"PRIx32 mhp_acpi_clear_insert_evt(uint32_t slot) "slot[0x%"PRIx32"] clear insert event" -#hw/i386/pc.c +# hw/i386/pc.c mhp_pc_dimm_assigned_slot(int slot) "0x%d" mhp_pc_dimm_assigned_address(uint64_t addr) "0x%"PRIx64 diff --git a/trace/Makefile.objs b/trace/Makefile.objs index 46de95c1a6..32f7a32ce2 100644 --- a/trace/Makefile.objs +++ b/trace/Makefile.objs @@ -144,3 +144,4 @@ util-obj-$(CONFIG_TRACE_SIMPLE) += simple.o generated-tracers.o util-obj-$(CONFIG_TRACE_FTRACE) += ftrace.o util-obj-$(CONFIG_TRACE_UST) += generated-ust.o util-obj-y += control.o +util-obj-y += qmp.o diff --git a/trace/control.c b/trace/control.c index 9631a40eff..0d308011a2 100644 --- a/trace/control.c +++ b/trace/control.c @@ -85,19 +85,6 @@ TraceEvent *trace_event_pattern(const char *pat, TraceEvent *ev) return NULL; } -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) { Location loc; diff --git a/trace/control.h b/trace/control.h index e1ec033705..da9bb6b774 100644 --- a/trace/control.h +++ b/trace/control.h @@ -148,13 +148,6 @@ static void trace_event_set_state_dynamic(TraceEvent *ev, bool state); -/** - * trace_print_events: - * - * Print the state of all events. - */ -void trace_print_events(FILE *stream, fprintf_function stream_printf); - /** * trace_init_backends: * @events: Name of file with events to be enabled at startup; may be NULL. diff --git a/trace/qmp.c b/trace/qmp.c new file mode 100644 index 0000000000..0b19489528 --- /dev/null +++ b/trace/qmp.c @@ -0,0 +1,75 @@ +/* + * QMP commands for tracing events. + * + * Copyright (C) 2014 Lluís Vilanova + * + * 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 "qemu/typedefs.h" +#include "qmp-commands.h" +#include "trace/control.h" + + +TraceEventInfoList *qmp_trace_event_get_state(const char *name, Error **errp) +{ + TraceEventInfoList *events = NULL; + bool found = false; + TraceEvent *ev; + + ev = NULL; + while ((ev = trace_event_pattern(name, ev)) != NULL) { + TraceEventInfoList *elem = g_new(TraceEventInfoList, 1); + elem->value = g_new(TraceEventInfo, 1); + elem->value->name = g_strdup(trace_event_get_name(ev)); + if (!trace_event_get_state_static(ev)) { + elem->value->state = TRACE_EVENT_STATE_UNAVAILABLE; + } else if (!trace_event_get_state_dynamic(ev)) { + elem->value->state = TRACE_EVENT_STATE_DISABLED; + } else { + elem->value->state = TRACE_EVENT_STATE_ENABLED; + } + elem->next = events; + events = elem; + found = true; + } + + if (!found && !trace_event_is_pattern(name)) { + error_setg(errp, "unknown event \"%s\"", name); + } + + return events; +} + +void qmp_trace_event_set_state(const char *name, bool enable, + bool has_ignore_unavailable, + bool ignore_unavailable, Error **errp) +{ + bool found = false; + TraceEvent *ev; + + /* Check all selected events are dynamic */ + ev = NULL; + while ((ev = trace_event_pattern(name, ev)) != NULL) { + found = true; + if (!(has_ignore_unavailable && ignore_unavailable) && + !trace_event_get_state_static(ev)) { + error_setg(errp, "cannot set dynamic tracing state for \"%s\"", + trace_event_get_name(ev)); + return; + } + } + if (!found && !trace_event_is_pattern(name)) { + error_setg(errp, "unknown event \"%s\"", name); + return; + } + + /* Apply changes */ + ev = NULL; + while ((ev = trace_event_pattern(name, ev)) != NULL) { + if (trace_event_get_state_static(ev)) { + trace_event_set_state_dynamic(ev, enable); + } + } +}