Pull request

Show trace-events filename/lineno in fmt string errors and send -d trace:help
 output to stdout for consistency.
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCAAdFiEEhpWov9P5fNqsNXdanKSrs4Grc8gFAl/zJbIACgkQnKSrs4Gr
 c8jKZAf9G2TyZACfZMVBYUec5mN+1AYMx9DK3asIiwZoX+iVmEVwQRisBFnUWCWR
 39I32Wl2Gu5ySFugYlB07jFvamiyUj7t8hDEr0JWbCzo3oietgcFkyxkeDyy/pqy
 1rzdj2PU2aIess7GDM9LEqLqitxJ+iXW53JDL5zQODwHXjIWvBTlV5Krnm3fr/TD
 z0r82z4XCbblPIX2DkFg3/iE7LPtfxECvjumGN3/aXfKYO/FDYeptXxRKUeMd8Rf
 iSLv4KcxieSnK+iACG70unB44LX/oJ2UoGO50WH3Vwk1U2cUsBqxZf0qwO8hvGi+
 TZvvBCfs87uRB5w5MZ18B1mQy95toQ==
 =ZhGS
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/stefanha-gitlab/tags/tracing-pull-request' into staging

Pull request

Show trace-events filename/lineno in fmt string errors and send -d trace:help
output to stdout for consistency.

# gpg: Signature made Mon 04 Jan 2021 14:26:58 GMT
# gpg:                using RSA key 8695A8BFD3F97CDAAC35775A9CA4ABB381AB73C8
# gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>" [full]
# gpg:                 aka "Stefan Hajnoczi <stefanha@gmail.com>" [full]
# Primary key fingerprint: 8695 A8BF D3F9 7CDA AC35  775A 9CA4 ABB3 81AB 73C8

* remotes/stefanha-gitlab/tags/tracing-pull-request:
  tracetool: show trace-events filename/lineno in fmt string errors
  tracetool: add input filename and line number to Event
  tracetool: add out_lineno and out_next_lineno to out()
  tracetool: add output filename command-line argument
  trace: Send "-d trace:help" output to stdout

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2021-01-05 13:09:10 +00:00
commit 74a0a6fcec
10 changed files with 83 additions and 36 deletions

View File

@ -318,7 +318,8 @@ probes:
--target-type system \ --target-type system \
--target-name x86_64 \ --target-name x86_64 \
--group=all \ --group=all \
trace-events-all >qemu.stp trace-events-all \
qemu.stp
To facilitate simple usage of systemtap where there merely needs to be printf To facilitate simple usage of systemtap where there merely needs to be printf
logging of certain probes, a helper script "qemu-trace-stap" is provided. logging of certain probes, a helper script "qemu-trace-stap" is provided.

View File

@ -1901,7 +1901,6 @@ foreach target : target_dirs
custom_target(exe['name'] + stp['ext'], custom_target(exe['name'] + stp['ext'],
input: trace_events_all, input: trace_events_all,
output: exe['name'] + stp['ext'], output: exe['name'] + stp['ext'],
capture: true,
install: stp['install'], install: stp['install'],
install_dir: get_option('datadir') / 'systemtap/tapset', install_dir: get_option('datadir') / 'systemtap/tapset',
command: [ command: [
@ -1910,7 +1909,7 @@ foreach target : target_dirs
'--target-name=' + target_name, '--target-name=' + target_name,
'--target-type=' + target_type, '--target-type=' + target_type,
'--probe-prefix=qemu.' + target_type + '.' + target_name, '--probe-prefix=qemu.' + target_type + '.' + target_name,
'@INPUT@', '@INPUT@', '@OUTPUT@'
]) ])
endforeach endforeach
endif endif

View File

@ -16,7 +16,7 @@ __email__ = "stefanha@redhat.com"
import sys import sys
import getopt import getopt
from tracetool import error_write, out from tracetool import error_write, out, out_open
import tracetool.backend import tracetool.backend
import tracetool.format import tracetool.format
@ -32,7 +32,7 @@ def error_opt(msg = None):
format_descr = "\n".join([ " %-15s %s" % (n, d) format_descr = "\n".join([ " %-15s %s" % (n, d)
for n,d in tracetool.format.get_list() ]) for n,d in tracetool.format.get_list() ])
error_write("""\ error_write("""\
Usage: %(script)s --format=<format> --backends=<backends> [<options>] Usage: %(script)s --format=<format> --backends=<backends> [<options>] <trace-events> ... <output>
Backends: Backends:
%(backends)s %(backends)s
@ -135,13 +135,15 @@ def main(args):
if probe_prefix is None: if probe_prefix is None:
probe_prefix = ".".join(["qemu", target_type, target_name]) probe_prefix = ".".join(["qemu", target_type, target_name])
if len(args) < 1: if len(args) < 2:
error_opt("missing trace-events filepath") error_opt("missing trace-events and output filepaths")
events = [] events = []
for arg in args: for arg in args[:-1]:
with open(arg, "r") as fh: with open(arg, "r") as fh:
events.extend(tracetool.read_events(fh, arg)) events.extend(tracetool.read_events(fh, arg))
out_open(args[-1])
try: try:
tracetool.generate(events, arg_group, arg_format, arg_backends, tracetool.generate(events, arg_group, arg_format, arg_backends,
binary=binary, probe_prefix=probe_prefix) binary=binary, probe_prefix=probe_prefix)

View File

@ -31,14 +31,36 @@ def error(*lines):
sys.exit(1) sys.exit(1)
out_lineno = 1
out_filename = '<none>'
out_fobj = sys.stdout
def out_open(filename):
global out_filename, out_fobj
out_filename = filename
out_fobj = open(filename, 'wt')
def out(*lines, **kwargs): def out(*lines, **kwargs):
"""Write a set of output lines. """Write a set of output lines.
You can use kwargs as a shorthand for mapping variables when formatting all You can use kwargs as a shorthand for mapping variables when formatting all
the strings in lines. the strings in lines.
The 'out_lineno' kwarg is automatically added to reflect the current output
file line number. The 'out_next_lineno' kwarg is also automatically added
with the next output line number. The 'out_filename' kwarg is automatically
added with the output filename.
""" """
lines = [ l % kwargs for l in lines ] global out_lineno
sys.stdout.writelines("\n".join(lines) + "\n") output = []
for l in lines:
kwargs['out_lineno'] = out_lineno
kwargs['out_next_lineno'] = out_lineno + 1
kwargs['out_filename'] = out_filename
output.append(l % kwargs)
out_lineno += 1
out_fobj.writelines("\n".join(output) + "\n")
# We only want to allow standard C types or fixed sized # We only want to allow standard C types or fixed sized
# integer types. We don't want QEMU specific types # integer types. We don't want QEMU specific types
@ -196,6 +218,10 @@ class Event(object):
Properties of the event. Properties of the event.
args : Arguments args : Arguments
The event arguments. The event arguments.
lineno : int
The line number in the input file.
filename : str
The path to the input file.
""" """
@ -208,7 +234,7 @@ class Event(object):
_VALID_PROPS = set(["disable", "tcg", "tcg-trans", "tcg-exec", "vcpu"]) _VALID_PROPS = set(["disable", "tcg", "tcg-trans", "tcg-exec", "vcpu"])
def __init__(self, name, props, fmt, args, orig=None, def __init__(self, name, props, fmt, args, lineno, filename, orig=None,
event_trans=None, event_exec=None): event_trans=None, event_exec=None):
""" """
Parameters Parameters
@ -221,6 +247,10 @@ class Event(object):
Event printing format string(s). Event printing format string(s).
args : Arguments args : Arguments
Event arguments. Event arguments.
lineno : int
The line number in the input file.
filename : str
The path to the input file.
orig : Event or None orig : Event or None
Original Event before transformation/generation. Original Event before transformation/generation.
event_trans : Event or None event_trans : Event or None
@ -233,6 +263,8 @@ class Event(object):
self.properties = props self.properties = props
self.fmt = fmt self.fmt = fmt
self.args = args self.args = args
self.lineno = int(lineno)
self.filename = str(filename)
self.event_trans = event_trans self.event_trans = event_trans
self.event_exec = event_exec self.event_exec = event_exec
@ -254,16 +286,21 @@ class Event(object):
def copy(self): def copy(self):
"""Create a new copy.""" """Create a new copy."""
return Event(self.name, list(self.properties), self.fmt, return Event(self.name, list(self.properties), self.fmt,
self.args.copy(), self, self.event_trans, self.event_exec) self.args.copy(), self.lineno, self.filename,
self, self.event_trans, self.event_exec)
@staticmethod @staticmethod
def build(line_str): def build(line_str, lineno, filename):
"""Build an Event instance from a string. """Build an Event instance from a string.
Parameters Parameters
---------- ----------
line_str : str line_str : str
Line describing the event. Line describing the event.
lineno : int
Line number in input file.
filename : str
Path to input file.
""" """
m = Event._CRE.match(line_str) m = Event._CRE.match(line_str)
assert m is not None assert m is not None
@ -293,7 +330,7 @@ class Event(object):
if "tcg" in props and isinstance(fmt, str): if "tcg" in props and isinstance(fmt, str):
raise ValueError("Events with 'tcg' property must have two format strings") raise ValueError("Events with 'tcg' property must have two format strings")
event = Event(name, props, fmt, args) event = Event(name, props, fmt, args, lineno, filename)
# add implicit arguments when using the 'vcpu' property # add implicit arguments when using the 'vcpu' property
import tracetool.vcpu import tracetool.vcpu
@ -338,6 +375,8 @@ class Event(object):
list(self.properties), list(self.properties),
self.fmt, self.fmt,
self.args.transform(*trans), self.args.transform(*trans),
self.lineno,
self.filename,
self) self)
@ -364,7 +403,7 @@ def read_events(fobj, fname):
continue continue
try: try:
event = Event.build(line) event = Event.build(line, lineno, fname)
except ValueError as e: except ValueError as e:
arg0 = 'Error at %s:%d: %s' % (fname, lineno, e.args[0]) arg0 = 'Error at %s:%d: %s' % (fname, lineno, e.args[0])
e.args = (arg0,) + e.args[1:] e.args = (arg0,) + e.args[1:]

View File

@ -33,8 +33,10 @@ def generate_h(event, group):
' int unused __attribute__ ((unused));', ' int unused __attribute__ ((unused));',
' int trlen;', ' int trlen;',
' if (trace_event_get_state(%(event_id)s)) {', ' if (trace_event_get_state(%(event_id)s)) {',
'#line %(event_lineno)d "%(event_filename)s"',
' trlen = snprintf(ftrace_buf, MAX_TRACE_STRLEN,', ' trlen = snprintf(ftrace_buf, MAX_TRACE_STRLEN,',
' "%(name)s " %(fmt)s "\\n" %(argnames)s);', ' "%(name)s " %(fmt)s "\\n" %(argnames)s);',
'#line %(out_next_lineno)d "%(out_filename)s"',
' trlen = MIN(trlen, MAX_TRACE_STRLEN - 1);', ' trlen = MIN(trlen, MAX_TRACE_STRLEN - 1);',
' unused = write(trace_marker_fd, ftrace_buf, trlen);', ' unused = write(trace_marker_fd, ftrace_buf, trlen);',
' }', ' }',
@ -42,6 +44,8 @@ def generate_h(event, group):
name=event.name, name=event.name,
args=event.args, args=event.args,
event_id="TRACE_" + event.name.upper(), event_id="TRACE_" + event.name.upper(),
event_lineno=event.lineno,
event_filename=event.filename,
fmt=event.fmt.rstrip("\n"), fmt=event.fmt.rstrip("\n"),
argnames=argnames) argnames=argnames)

View File

@ -37,12 +37,16 @@ def generate_h(event, group):
out(' if (%(cond)s && qemu_loglevel_mask(LOG_TRACE)) {', out(' if (%(cond)s && qemu_loglevel_mask(LOG_TRACE)) {',
' struct timeval _now;', ' struct timeval _now;',
' gettimeofday(&_now, NULL);', ' gettimeofday(&_now, NULL);',
'#line %(event_lineno)d "%(event_filename)s"',
' qemu_log("%%d@%%zu.%%06zu:%(name)s " %(fmt)s "\\n",', ' qemu_log("%%d@%%zu.%%06zu:%(name)s " %(fmt)s "\\n",',
' qemu_get_thread_id(),', ' qemu_get_thread_id(),',
' (size_t)_now.tv_sec, (size_t)_now.tv_usec', ' (size_t)_now.tv_sec, (size_t)_now.tv_usec',
' %(argnames)s);', ' %(argnames)s);',
'#line %(out_next_lineno)d "%(out_filename)s"',
' }', ' }',
cond=cond, cond=cond,
event_lineno=event.lineno,
event_filename=event.filename,
name=event.name, name=event.name,
fmt=event.fmt.rstrip("\n"), fmt=event.fmt.rstrip("\n"),
argnames=argnames) argnames=argnames)

View File

@ -35,9 +35,13 @@ def generate_h(event, group):
cond = "trace_event_get_state(%s)" % ("TRACE_" + event.name.upper()) cond = "trace_event_get_state(%s)" % ("TRACE_" + event.name.upper())
out(' if (%(cond)s) {', out(' if (%(cond)s) {',
'#line %(event_lineno)d "%(event_filename)s"',
' syslog(LOG_INFO, "%(name)s " %(fmt)s %(argnames)s);', ' syslog(LOG_INFO, "%(name)s " %(fmt)s %(argnames)s);',
'#line %(out_next_lineno)d "%(out_filename)s"',
' }', ' }',
cond=cond, cond=cond,
event_lineno=event.lineno,
event_filename=event.filename,
name=event.name, name=event.name,
fmt=event.fmt.rstrip("\n"), fmt=event.fmt.rstrip("\n"),
argnames=argnames) argnames=argnames)

View File

@ -125,16 +125,16 @@ TraceEvent *trace_event_iter_next(TraceEventIter *iter)
return NULL; return NULL;
} }
void trace_list_events(void) void trace_list_events(FILE *f)
{ {
TraceEventIter iter; TraceEventIter iter;
TraceEvent *ev; TraceEvent *ev;
trace_event_iter_init(&iter, NULL); trace_event_iter_init(&iter, NULL);
while ((ev = trace_event_iter_next(&iter)) != NULL) { while ((ev = trace_event_iter_next(&iter)) != NULL) {
fprintf(stderr, "%s\n", trace_event_get_name(ev)); fprintf(f, "%s\n", trace_event_get_name(ev));
} }
#ifdef CONFIG_TRACE_DTRACE #ifdef CONFIG_TRACE_DTRACE
fprintf(stderr, "This list of names of trace points may be incomplete " fprintf(f, "This list of names of trace points may be incomplete "
"when using the DTrace/SystemTap backends.\n" "when using the DTrace/SystemTap backends.\n"
"Run 'qemu-trace-stap list %s' to print the full list.\n", "Run 'qemu-trace-stap list %s' to print the full list.\n",
error_get_progname()); error_get_progname());
@ -176,7 +176,7 @@ static void do_trace_enable_events(const char *line_buf)
void trace_enable_events(const char *line_buf) void trace_enable_events(const char *line_buf)
{ {
if (is_help_option(line_buf)) { if (is_help_option(line_buf)) {
trace_list_events(); trace_list_events(stdout);
if (monitor_cur() == NULL) { if (monitor_cur() == NULL) {
exit(0); exit(0);
} }

View File

@ -201,10 +201,11 @@ void trace_fini_vcpu(CPUState *vcpu);
/** /**
* trace_list_events: * trace_list_events:
* @f: Where to send output.
* *
* List all available events. * List all available events.
*/ */
void trace_list_events(void); void trace_list_events(FILE *f);
/** /**
* trace_enable_events: * trace_enable_events:

View File

@ -11,20 +11,17 @@ foreach dir : [ '.' ] + trace_events_subdirs
trace_h = custom_target(fmt.format('trace', 'h'), trace_h = custom_target(fmt.format('trace', 'h'),
output: fmt.format('trace', 'h'), output: fmt.format('trace', 'h'),
input: trace_events_file, input: trace_events_file,
command: [ tracetool, group, '--format=h', '@INPUT@' ], command: [ tracetool, group, '--format=h', '@INPUT@', '@OUTPUT@' ])
capture: true)
genh += trace_h genh += trace_h
trace_c = custom_target(fmt.format('trace', 'c'), trace_c = custom_target(fmt.format('trace', 'c'),
output: fmt.format('trace', 'c'), output: fmt.format('trace', 'c'),
input: trace_events_file, input: trace_events_file,
command: [ tracetool, group, '--format=c', '@INPUT@' ], command: [ tracetool, group, '--format=c', '@INPUT@', '@OUTPUT@' ])
capture: true)
if 'CONFIG_TRACE_UST' in config_host if 'CONFIG_TRACE_UST' in config_host
trace_ust_h = custom_target(fmt.format('trace-ust', 'h'), trace_ust_h = custom_target(fmt.format('trace-ust', 'h'),
output: fmt.format('trace-ust', 'h'), output: fmt.format('trace-ust', 'h'),
input: trace_events_file, input: trace_events_file,
command: [ tracetool, group, '--format=ust-events-h', '@INPUT@' ], command: [ tracetool, group, '--format=ust-events-h', '@INPUT@', '@OUTPUT@' ])
capture: true)
trace_ss.add(trace_ust_h, lttng, urcubp) trace_ss.add(trace_ust_h, lttng, urcubp)
genh += trace_ust_h genh += trace_ust_h
endif endif
@ -33,8 +30,7 @@ foreach dir : [ '.' ] + trace_events_subdirs
trace_dtrace = custom_target(fmt.format('trace-dtrace', 'dtrace'), trace_dtrace = custom_target(fmt.format('trace-dtrace', 'dtrace'),
output: fmt.format('trace-dtrace', 'dtrace'), output: fmt.format('trace-dtrace', 'dtrace'),
input: trace_events_file, input: trace_events_file,
command: [ tracetool, group, '--format=d', '@INPUT@' ], command: [ tracetool, group, '--format=d', '@INPUT@', '@OUTPUT@' ])
capture: true)
trace_dtrace_h = custom_target(fmt.format('trace-dtrace', 'h'), trace_dtrace_h = custom_target(fmt.format('trace-dtrace', 'h'),
output: fmt.format('trace-dtrace', 'h'), output: fmt.format('trace-dtrace', 'h'),
input: trace_dtrace, input: trace_dtrace,
@ -69,8 +65,7 @@ foreach d : [
gen = custom_target(d[0], gen = custom_target(d[0],
output: d[0], output: d[0],
input: meson.source_root() / 'trace-events', input: meson.source_root() / 'trace-events',
command: [ tracetool, '--group=root', '--format=@0@'.format(d[1]), '@INPUT@' ], command: [ tracetool, '--group=root', '--format=@0@'.format(d[1]), '@INPUT@', '@OUTPUT@' ])
capture: true)
specific_ss.add(gen) specific_ss.add(gen)
endforeach endforeach
@ -78,13 +73,11 @@ if 'CONFIG_TRACE_UST' in config_host
trace_ust_all_h = custom_target('trace-ust-all.h', trace_ust_all_h = custom_target('trace-ust-all.h',
output: 'trace-ust-all.h', output: 'trace-ust-all.h',
input: trace_events_files, input: trace_events_files,
command: [ tracetool, '--group=all', '--format=ust-events-h', '@INPUT@' ], command: [ tracetool, '--group=all', '--format=ust-events-h', '@INPUT@', '@OUTPUT@' ])
capture: true)
trace_ust_all_c = custom_target('trace-ust-all.c', trace_ust_all_c = custom_target('trace-ust-all.c',
output: 'trace-ust-all.c', output: 'trace-ust-all.c',
input: trace_events_files, input: trace_events_files,
command: [ tracetool, '--group=all', '--format=ust-events-c', '@INPUT@' ], command: [ tracetool, '--group=all', '--format=ust-events-c', '@INPUT@', '@OUTPUT@' ])
capture: true)
trace_ss.add(trace_ust_all_h, trace_ust_all_c) trace_ss.add(trace_ust_all_h, trace_ust_all_c)
genh += trace_ust_all_h genh += trace_ust_all_h
endif endif