Pull request

Daniel's updated tracetool test suite that doesn't break Windows CI.
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEEhpWov9P5fNqsNXdanKSrs4Grc8gFAmjJo2gACgkQnKSrs4Gr
 c8gAWggAmFCi3KyeoJYLdw8ANZ46lDPV+GCtTKtCM68LtcSZKfrlNROWE/9UDI7V
 P3U/Xog01mqyWw4RX+SC90ckSWchMcLSN+TT8mZNfOTn8mcelyQkh4TDlguBLxlE
 Qz8PMwIxrKljP0bV9evZ1gk1CHkB8u1jPKLckiZRdI9rbjuxNkYTMyVSezCdfIhV
 dTDO1xf3oTDZq94591D0jSLHuF58MNXJHlA/q5OIdPCqu80Vo6cc8A8B5E1ZGKA5
 wzXaMY72GlX8RYwebXudHI0Sen6XyE3It+iWQYD8o6kgJ6kxBc0ljLxJCRE9O/d4
 D5hBgEgJ5S1ul4ggkBf5UKazF86EIQ==
 =YODs
 -----END PGP SIGNATURE-----

Merge tag 'tracing-pull-request' of https://gitlab.com/stefanha/qemu into staging

Pull request

Daniel's updated tracetool test suite that doesn't break Windows CI.

# -----BEGIN PGP SIGNATURE-----
#
# iQEzBAABCgAdFiEEhpWov9P5fNqsNXdanKSrs4Grc8gFAmjJo2gACgkQnKSrs4Gr
# c8gAWggAmFCi3KyeoJYLdw8ANZ46lDPV+GCtTKtCM68LtcSZKfrlNROWE/9UDI7V
# P3U/Xog01mqyWw4RX+SC90ckSWchMcLSN+TT8mZNfOTn8mcelyQkh4TDlguBLxlE
# Qz8PMwIxrKljP0bV9evZ1gk1CHkB8u1jPKLckiZRdI9rbjuxNkYTMyVSezCdfIhV
# dTDO1xf3oTDZq94591D0jSLHuF58MNXJHlA/q5OIdPCqu80Vo6cc8A8B5E1ZGKA5
# wzXaMY72GlX8RYwebXudHI0Sen6XyE3It+iWQYD8o6kgJ6kxBc0ljLxJCRE9O/d4
# D5hBgEgJ5S1ul4ggkBf5UKazF86EIQ==
# =YODs
# -----END PGP SIGNATURE-----
# gpg: Signature made Tue 16 Sep 2025 10:50:32 AM PDT
# gpg:                using RSA key 8695A8BFD3F97CDAAC35775A9CA4ABB381AB73C8
# gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>" [unknown]
# gpg:                 aka "Stefan Hajnoczi <stefanha@gmail.com>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 8695 A8BF D3F9 7CDA AC35  775A 9CA4 ABB3 81AB 73C8

* tag 'tracing-pull-request' of https://gitlab.com/stefanha/qemu:
  tracetool-test: allow to run in parallel
  qapi: switch to use QEMU_TEST_REGENERATE env var
  tracetool: drop the probe "__nocheck__" wrapping
  tracetool: add test suite for tracetool with reference output
  tracetool: include SPDX-License-Identifier in generated files
  tracetool: avoid space after "*" in arg types
  tracetool: eliminate trailing whitespace in C format
  checkpatch: cull trailing '*/' in SPDX check

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2025-09-17 09:46:42 -07:00
commit 6be998b986
36 changed files with 826 additions and 21 deletions

View file

@ -3562,6 +3562,7 @@ F: scripts/tracetool/
F: scripts/qemu-trace-stap*
F: docs/tools/qemu-trace-stap.rst
F: docs/devel/tracing.rst
F: tests/tracetool/
T: git https://github.com/stefanha/qemu.git tracing
Simpletrace

View file

@ -178,6 +178,46 @@ parser (either fixing a bug or extending/modifying the syntax). To do this:
``qapi-schema += foo.json``
The reference output can be automatically updated to match the latest QAPI
code generator by running the tests with the QEMU_TEST_REGENERATE environment
variable set.
.. code::
QEMU_TEST_REGENERATE=1 make check-qapi-schema
The resulting changes must be reviewed by the author to ensure they match
the intended results before adding the updated reference output to the
same commit that alters the generator code.
.. _tracetool-tests:
Tracetool tests
~~~~~~~~~~~~~~~
The tracetool tests validate the generated source files used for defining
probes for various tracing backends and source formats. The test operates
by running the tracetool program against a sample trace-events file, and
comparing the generated output against known good reference output. The
tests can be run with:
.. code::
make check-tracetool
The reference output is stored in files under tests/tracetool, and when
the tracetool backend/format output is intentionally changed, the reference
files need to be updated. This can be automated by setting the
QEMU_TEST_REGENERATE=1 environment variable:
.. code::
QEMU_TEST_REGENERATE=1 make check-tracetool
The resulting changes must be reviewed by the author to ensure they match
the intended results, before adding the updated reference output to the
same commit that alters the generator code.
check-block
~~~~~~~~~~~

View file

@ -1368,6 +1368,9 @@ sub checkspdx {
$expr =~ s/^\s*//g;
$expr =~ s/\s*$//g;
# Cull C comment end
$expr =~ s/\*\/.*//;
my @bits = split / +/, $expr;
my $prefer = "GPL-2.0-or-later";

View file

@ -170,10 +170,16 @@ class Arguments:
def __str__(self):
"""String suitable for declaring function arguments."""
def onearg(t, n):
if t[-1] == '*':
return "".join([t, n])
else:
return " ".join([t, n])
if len(self._args) == 0:
return "void"
else:
return ", ".join([ " ".join([t, n]) for t,n in self._args ])
return ", ".join([ onearg(t, n) for t,n in self._args ])
def __repr__(self):
"""Evaluable string representation for this object."""
@ -332,7 +338,6 @@ class Event(object):
return self._FMT.findall(self.fmt)
QEMU_TRACE = "trace_%(name)s"
QEMU_TRACE_NOCHECK = "_nocheck__" + QEMU_TRACE
QEMU_TRACE_TCG = QEMU_TRACE + "_tcg"
QEMU_DSTATE = "_TRACE_%(NAME)s_DSTATE"
QEMU_BACKEND_DSTATE = "TRACE_%(NAME)s_BACKEND_DSTATE"

View file

@ -22,6 +22,7 @@ def generate(events, backend, group):
header = "trace-" + group + ".h"
out('/* This file is autogenerated by tracetool, do not edit. */',
'/* SPDX-License-Identifier: GPL-2.0-or-later */',
'',
'#include "qemu/osdep.h"',
'#include "qemu/module.h"',
@ -36,7 +37,7 @@ def generate(events, backend, group):
' .id = 0,',
' .name = \"%(name)s\",',
' .sstate = %(sstate)s,',
' .dstate = &%(dstate)s ',
' .dstate = &%(dstate)s',
'};',
event = e.api(e.QEMU_EVENT),
name = e.name,

View file

@ -39,7 +39,8 @@ def generate(events, backend, group):
if not events and platform != "darwin":
return
out('/* This file is autogenerated by tracetool, do not edit. */'
out('/* This file is autogenerated by tracetool, do not edit. */',
'/* SPDX-License-Identifier: GPL-2.0-or-later */',
'',
'provider qemu {')

View file

@ -19,6 +19,7 @@ def generate(events, backend, group):
header = "trace/control.h"
out('/* This file is autogenerated by tracetool, do not edit. */',
'/* SPDX-License-Identifier: GPL-2.0-or-later */',
'',
'#ifndef TRACE_%s_GENERATED_TRACERS_H' % group.upper(),
'#define TRACE_%s_GENERATED_TRACERS_H' % group.upper(),
@ -63,7 +64,7 @@ def generate(events, backend, group):
out('',
'static inline void %(api)s(%(args)s)',
'{',
api=e.api(e.QEMU_TRACE_NOCHECK),
api=e.api(),
args=e.args)
if "disable" not in e.properties:
@ -71,20 +72,6 @@ def generate(events, backend, group):
out('}')
cond = "true"
out('',
'static inline void %(api)s(%(args)s)',
'{',
' if (%(cond)s) {',
' %(api_nocheck)s(%(names)s);',
' }',
'}',
api=e.api(),
api_nocheck=e.api(e.QEMU_TRACE_NOCHECK),
args=e.args,
names=", ".join(e.args.names()),
cond=cond)
backend.generate_end(events, group)

View file

@ -88,6 +88,7 @@ def c_fmt_to_stap(fmt):
def generate(events, backend, group):
out('/* This file is autogenerated by tracetool, do not edit. */',
'/* SPDX-License-Identifier: GPL-2.0-or-later */',
'')
for event_id, e in enumerate(events):

View file

@ -22,6 +22,7 @@ def global_var_name(name):
def generate(events, backend, group):
out('/* This file is autogenerated by tracetool, do not edit. */',
'/* SPDX-License-Identifier: GPL-2.0-or-later */',
'')
for event_id, e in enumerate(events):

View file

@ -38,6 +38,7 @@ def generate(events, backend, group):
if "disable" not in e.properties]
out('/* This file is autogenerated by tracetool, do not edit. */',
'/* SPDX-License-Identifier: GPL-2.0-or-later */',
'')
for e in events:

View file

@ -20,6 +20,7 @@ def generate(events, backend, group):
if "disabled" not in e.properties]
out('/* This file is autogenerated by tracetool, do not edit. */',
'/* SPDX-License-Identifier: GPL-2.0-or-later */',
'',
'#include "qemu/osdep.h"',
'',

View file

@ -25,6 +25,7 @@ def generate(events, backend, group):
include = "trace-ust.h"
out('/* This file is autogenerated by tracetool, do not edit. */',
'/* SPDX-License-Identifier: GPL-2.0-or-later */',
'',
'#undef TRACEPOINT_PROVIDER',
'#define TRACEPOINT_PROVIDER qemu',

View file

@ -13,6 +13,7 @@ check-help:
@echo " $(MAKE) check-functional-TARGET Run functional tests for a given target"
@echo " $(MAKE) check-unit Run qobject tests"
@echo " $(MAKE) check-qapi-schema Run QAPI schema tests"
@echo " $(MAKE) check-tracetool Run tracetool generator tests"
@echo " $(MAKE) check-block Run block tests"
ifneq ($(filter $(all-check-targets), check-softfloat),)
@echo " $(MAKE) check-tcg Run TCG tests"

View file

@ -88,3 +88,4 @@ subdir('qapi-schema')
subdir('qtest')
subdir('migration-stress')
subdir('functional')
subdir('tracetool')

View file

@ -165,7 +165,7 @@ def test_and_diff(test_name, dir_name, update):
if actual_out == expected_out and actual_err == expected_err:
return 0
print("%s %s" % (test_name, 'UPDATE' if update else 'FAIL'),
print("%s: %s" % (test_name, 'UPDATE' if update else 'FAIL'),
file=sys.stderr)
out_diff = difflib.unified_diff(expected_out, actual_out, outfp.name)
err_diff = difflib.unified_diff(expected_err, actual_err, errfp.name)
@ -173,6 +173,9 @@ def test_and_diff(test_name, dir_name, update):
sys.stdout.writelines(err_diff)
if not update:
print(("\n%s: set QEMU_TEST_REGENERATE=1 to recreate reference output" +
"if the QAPI schema generator was intentionally changed") % test_name,
file=sys.stderr)
return 1
try:
@ -197,7 +200,7 @@ def main(argv):
parser.add_argument('-d', '--dir', action='store', default='',
help="directory containing tests")
parser.add_argument('-u', '--update', action='store_true',
default='QAPI_TEST_UPDATE' in os.environ,
default='QEMU_TEST_REGENERATE' in os.environ,
help="update expected test results")
parser.add_argument('tests', nargs='*', metavar='TEST', action='store')
args = parser.parse_args()

32
tests/tracetool/dtrace.c Normal file
View file

@ -0,0 +1,32 @@
/* This file is autogenerated by tracetool, do not edit. */
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "qemu/osdep.h"
#include "qemu/module.h"
#include "trace-testsuite.h"
uint16_t _TRACE_TEST_BLAH_DSTATE;
uint16_t _TRACE_TEST_WIBBLE_DSTATE;
TraceEvent _TRACE_TEST_BLAH_EVENT = {
.id = 0,
.name = "test_blah",
.sstate = TRACE_TEST_BLAH_ENABLED,
.dstate = &_TRACE_TEST_BLAH_DSTATE
};
TraceEvent _TRACE_TEST_WIBBLE_EVENT = {
.id = 0,
.name = "test_wibble",
.sstate = TRACE_TEST_WIBBLE_ENABLED,
.dstate = &_TRACE_TEST_WIBBLE_DSTATE
};
TraceEvent *testsuite_trace_events[] = {
&_TRACE_TEST_BLAH_EVENT,
&_TRACE_TEST_WIBBLE_EVENT,
NULL,
};
static void trace_testsuite_register_events(void)
{
trace_event_register_group(testsuite_trace_events);
}
trace_init(trace_testsuite_register_events)

10
tests/tracetool/dtrace.d Normal file
View file

@ -0,0 +1,10 @@
/* This file is autogenerated by tracetool, do not edit. */
/* SPDX-License-Identifier: GPL-2.0-or-later */
provider qemu {
probe test_blah(void * context,const char * filename);
probe test_wibble(void * context,int value);
};

45
tests/tracetool/dtrace.h Normal file
View file

@ -0,0 +1,45 @@
/* This file is autogenerated by tracetool, do not edit. */
/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef TRACE_TESTSUITE_GENERATED_TRACERS_H
#define TRACE_TESTSUITE_GENERATED_TRACERS_H
#include "trace/control.h"
extern TraceEvent _TRACE_TEST_BLAH_EVENT;
extern TraceEvent _TRACE_TEST_WIBBLE_EVENT;
extern uint16_t _TRACE_TEST_BLAH_DSTATE;
extern uint16_t _TRACE_TEST_WIBBLE_DSTATE;
#define TRACE_TEST_BLAH_ENABLED 1
#define TRACE_TEST_WIBBLE_ENABLED 1
#ifndef SDT_USE_VARIADIC
#define SDT_USE_VARIADIC 1
#endif
#include "trace-dtrace-testsuite.h"
#undef SDT_USE_VARIADIC
#ifndef QEMU_TEST_BLAH_ENABLED
#define QEMU_TEST_BLAH_ENABLED() true
#endif
#ifndef QEMU_TEST_WIBBLE_ENABLED
#define QEMU_TEST_WIBBLE_ENABLED() true
#endif
#define TRACE_TEST_BLAH_BACKEND_DSTATE() ( \
QEMU_TEST_BLAH_ENABLED() || \
false)
static inline void trace_test_blah(void *context, const char *filename)
{
QEMU_TEST_BLAH(context, filename);
}
#define TRACE_TEST_WIBBLE_BACKEND_DSTATE() ( \
QEMU_TEST_WIBBLE_ENABLED() || \
false)
static inline void trace_test_wibble(void *context, int value)
{
QEMU_TEST_WIBBLE(context, value);
}
#endif /* TRACE_TESTSUITE_GENERATED_TRACERS_H */

View file

@ -0,0 +1,15 @@
/* This file is autogenerated by tracetool, do not edit. */
/* SPDX-License-Identifier: GPL-2.0-or-later */
probe qemu.log.test_blah = qemu.test_blah ?
{
try {
argfilename_str = filename ? user_string_n(filename, 512) : "<null>"
} catch {}
printf("%d@%d test_blah Blah context=%p filename=%s\n", pid(), gettimeofday_ns(), context, argfilename_str)
}
probe qemu.log.test_wibble = qemu.test_wibble ?
{
printf("%d@%d test_wibble Wibble context=%p value=%d\n", pid(), gettimeofday_ns(), context, value)
}

View file

@ -0,0 +1,16 @@
/* This file is autogenerated by tracetool, do not edit. */
/* SPDX-License-Identifier: GPL-2.0-or-later */
probe qemu.simpletrace.test_blah = qemu.test_blah ?
{
try {
argfilename_str = filename ? user_string_n(filename, 512) : "<null>"
} catch {}
argfilename_len = strlen(argfilename_str)
printf("%8b%8b%8b%4b%4b%8b%4b%.*s", 1, 0, gettimeofday_ns(), 24 + 8 + 4 + argfilename_len, pid(), context, argfilename_len, argfilename_len, argfilename_str)
}
probe qemu.simpletrace.test_wibble = qemu.test_wibble ?
{
printf("%8b%8b%8b%4b%4b%8b%8b", 1, 1, gettimeofday_ns(), 24 + 8 + 8, pid(), context, value)
}

View file

@ -0,0 +1,14 @@
/* This file is autogenerated by tracetool, do not edit. */
/* SPDX-License-Identifier: GPL-2.0-or-later */
probe qemu.test_blah = process("qemu").mark("test_blah")
{
context = $arg1;
filename = $arg2;
}
probe qemu.test_wibble = process("qemu").mark("test_wibble")
{
context = $arg1;
value = $arg2;
}

32
tests/tracetool/ftrace.c Normal file
View file

@ -0,0 +1,32 @@
/* This file is autogenerated by tracetool, do not edit. */
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "qemu/osdep.h"
#include "qemu/module.h"
#include "trace-testsuite.h"
uint16_t _TRACE_TEST_BLAH_DSTATE;
uint16_t _TRACE_TEST_WIBBLE_DSTATE;
TraceEvent _TRACE_TEST_BLAH_EVENT = {
.id = 0,
.name = "test_blah",
.sstate = TRACE_TEST_BLAH_ENABLED,
.dstate = &_TRACE_TEST_BLAH_DSTATE
};
TraceEvent _TRACE_TEST_WIBBLE_EVENT = {
.id = 0,
.name = "test_wibble",
.sstate = TRACE_TEST_WIBBLE_ENABLED,
.dstate = &_TRACE_TEST_WIBBLE_DSTATE
};
TraceEvent *testsuite_trace_events[] = {
&_TRACE_TEST_BLAH_EVENT,
&_TRACE_TEST_WIBBLE_EVENT,
NULL,
};
static void trace_testsuite_register_events(void)
{
trace_event_register_group(testsuite_trace_events);
}
trace_init(trace_testsuite_register_events)

59
tests/tracetool/ftrace.h Normal file
View file

@ -0,0 +1,59 @@
/* This file is autogenerated by tracetool, do not edit. */
/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef TRACE_TESTSUITE_GENERATED_TRACERS_H
#define TRACE_TESTSUITE_GENERATED_TRACERS_H
#include "trace/control.h"
extern TraceEvent _TRACE_TEST_BLAH_EVENT;
extern TraceEvent _TRACE_TEST_WIBBLE_EVENT;
extern uint16_t _TRACE_TEST_BLAH_DSTATE;
extern uint16_t _TRACE_TEST_WIBBLE_DSTATE;
#define TRACE_TEST_BLAH_ENABLED 1
#define TRACE_TEST_WIBBLE_ENABLED 1
#include "trace/ftrace.h"
#define TRACE_TEST_BLAH_BACKEND_DSTATE() ( \
trace_event_get_state_dynamic_by_id(TRACE_TEST_BLAH) || \
false)
static inline void trace_test_blah(void *context, const char *filename)
{
{
char ftrace_buf[MAX_TRACE_STRLEN];
int unused __attribute__ ((unused));
int trlen;
if (trace_event_get_state(TRACE_TEST_BLAH)) {
#line 4 "trace-events"
trlen = snprintf(ftrace_buf, MAX_TRACE_STRLEN,
"test_blah " "Blah context=%p filename=%s" "\n" , context, filename);
#line 33 "ftrace.h"
trlen = MIN(trlen, MAX_TRACE_STRLEN - 1);
unused = write(trace_marker_fd, ftrace_buf, trlen);
}
}
}
#define TRACE_TEST_WIBBLE_BACKEND_DSTATE() ( \
trace_event_get_state_dynamic_by_id(TRACE_TEST_WIBBLE) || \
false)
static inline void trace_test_wibble(void *context, int value)
{
{
char ftrace_buf[MAX_TRACE_STRLEN];
int unused __attribute__ ((unused));
int trlen;
if (trace_event_get_state(TRACE_TEST_WIBBLE)) {
#line 5 "trace-events"
trlen = snprintf(ftrace_buf, MAX_TRACE_STRLEN,
"test_wibble " "Wibble context=%p value=%d" "\n" , context, value);
#line 54 "ftrace.h"
trlen = MIN(trlen, MAX_TRACE_STRLEN - 1);
unused = write(trace_marker_fd, ftrace_buf, trlen);
}
}
}
#endif /* TRACE_TESTSUITE_GENERATED_TRACERS_H */

32
tests/tracetool/log.c Normal file
View file

@ -0,0 +1,32 @@
/* This file is autogenerated by tracetool, do not edit. */
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "qemu/osdep.h"
#include "qemu/module.h"
#include "trace-testsuite.h"
uint16_t _TRACE_TEST_BLAH_DSTATE;
uint16_t _TRACE_TEST_WIBBLE_DSTATE;
TraceEvent _TRACE_TEST_BLAH_EVENT = {
.id = 0,
.name = "test_blah",
.sstate = TRACE_TEST_BLAH_ENABLED,
.dstate = &_TRACE_TEST_BLAH_DSTATE
};
TraceEvent _TRACE_TEST_WIBBLE_EVENT = {
.id = 0,
.name = "test_wibble",
.sstate = TRACE_TEST_WIBBLE_ENABLED,
.dstate = &_TRACE_TEST_WIBBLE_DSTATE
};
TraceEvent *testsuite_trace_events[] = {
&_TRACE_TEST_BLAH_EVENT,
&_TRACE_TEST_WIBBLE_EVENT,
NULL,
};
static void trace_testsuite_register_events(void)
{
trace_event_register_group(testsuite_trace_events);
}
trace_init(trace_testsuite_register_events)

43
tests/tracetool/log.h Normal file
View file

@ -0,0 +1,43 @@
/* This file is autogenerated by tracetool, do not edit. */
/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef TRACE_TESTSUITE_GENERATED_TRACERS_H
#define TRACE_TESTSUITE_GENERATED_TRACERS_H
#include "trace/control.h"
extern TraceEvent _TRACE_TEST_BLAH_EVENT;
extern TraceEvent _TRACE_TEST_WIBBLE_EVENT;
extern uint16_t _TRACE_TEST_BLAH_DSTATE;
extern uint16_t _TRACE_TEST_WIBBLE_DSTATE;
#define TRACE_TEST_BLAH_ENABLED 1
#define TRACE_TEST_WIBBLE_ENABLED 1
#include "qemu/log-for-trace.h"
#define TRACE_TEST_BLAH_BACKEND_DSTATE() ( \
trace_event_get_state_dynamic_by_id(TRACE_TEST_BLAH) || \
false)
static inline void trace_test_blah(void *context, const char *filename)
{
if (trace_event_get_state(TRACE_TEST_BLAH) && qemu_loglevel_mask(LOG_TRACE)) {
#line 4 "trace-events"
qemu_log("test_blah " "Blah context=%p filename=%s" "\n", context, filename);
#line 28 "log.h"
}
}
#define TRACE_TEST_WIBBLE_BACKEND_DSTATE() ( \
trace_event_get_state_dynamic_by_id(TRACE_TEST_WIBBLE) || \
false)
static inline void trace_test_wibble(void *context, int value)
{
if (trace_event_get_state(TRACE_TEST_WIBBLE) && qemu_loglevel_mask(LOG_TRACE)) {
#line 5 "trace-events"
qemu_log("test_wibble " "Wibble context=%p value=%d" "\n", context, value);
#line 41 "log.h"
}
}
#endif /* TRACE_TESTSUITE_GENERATED_TRACERS_H */

View file

@ -0,0 +1,28 @@
# SPDX-License-Identifier: GPL-2.0-or-later
test_env = environment()
test_env.set('PYTHONPATH', meson.project_source_root() / 'scripts')
test_env.set('PYTHONIOENCODING', 'utf-8')
backends = [
'dtrace',
'ftrace',
'log',
'simple',
'syslog',
'ust'
]
# The tracetool-test.py program has portability problems on Windows.
if host_machine.system() != 'windows'
foreach backend: backends
test(backend,
python,
args: [meson.current_source_dir() / 'tracetool-test.py',
meson.project_source_root() / 'scripts' / 'tracetool.py',
backend,
meson.current_source_dir(),
meson.current_build_dir()],
suite: ['tracetool'])
endforeach
endif

61
tests/tracetool/simple.c Normal file
View file

@ -0,0 +1,61 @@
/* This file is autogenerated by tracetool, do not edit. */
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "qemu/osdep.h"
#include "qemu/module.h"
#include "trace-testsuite.h"
uint16_t _TRACE_TEST_BLAH_DSTATE;
uint16_t _TRACE_TEST_WIBBLE_DSTATE;
TraceEvent _TRACE_TEST_BLAH_EVENT = {
.id = 0,
.name = "test_blah",
.sstate = TRACE_TEST_BLAH_ENABLED,
.dstate = &_TRACE_TEST_BLAH_DSTATE
};
TraceEvent _TRACE_TEST_WIBBLE_EVENT = {
.id = 0,
.name = "test_wibble",
.sstate = TRACE_TEST_WIBBLE_ENABLED,
.dstate = &_TRACE_TEST_WIBBLE_DSTATE
};
TraceEvent *testsuite_trace_events[] = {
&_TRACE_TEST_BLAH_EVENT,
&_TRACE_TEST_WIBBLE_EVENT,
NULL,
};
static void trace_testsuite_register_events(void)
{
trace_event_register_group(testsuite_trace_events);
}
trace_init(trace_testsuite_register_events)
#include "qemu/osdep.h"
#include "trace/control.h"
#include "trace/simple.h"
void _simple_trace_test_blah(void *context, const char *filename)
{
TraceBufferRecord rec;
size_t argfilename_len = filename ? MIN(strlen(filename), MAX_TRACE_STRLEN) : 0;
if (trace_record_start(&rec, _TRACE_TEST_BLAH_EVENT.id, 8 + 4 + argfilename_len)) {
return; /* Trace Buffer Full, Event Dropped ! */
}
trace_record_write_u64(&rec, (uintptr_t)(uint64_t *)context);
trace_record_write_str(&rec, filename, argfilename_len);
trace_record_finish(&rec);
}
void _simple_trace_test_wibble(void *context, int value)
{
TraceBufferRecord rec;
if (trace_record_start(&rec, _TRACE_TEST_WIBBLE_EVENT.id, 8 + 8)) {
return; /* Trace Buffer Full, Event Dropped ! */
}
trace_record_write_u64(&rec, (uintptr_t)(uint64_t *)context);
trace_record_write_u64(&rec, (uint64_t)value);
trace_record_finish(&rec);
}

40
tests/tracetool/simple.h Normal file
View file

@ -0,0 +1,40 @@
/* This file is autogenerated by tracetool, do not edit. */
/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef TRACE_TESTSUITE_GENERATED_TRACERS_H
#define TRACE_TESTSUITE_GENERATED_TRACERS_H
#include "trace/control.h"
extern TraceEvent _TRACE_TEST_BLAH_EVENT;
extern TraceEvent _TRACE_TEST_WIBBLE_EVENT;
extern uint16_t _TRACE_TEST_BLAH_DSTATE;
extern uint16_t _TRACE_TEST_WIBBLE_DSTATE;
#define TRACE_TEST_BLAH_ENABLED 1
#define TRACE_TEST_WIBBLE_ENABLED 1
void _simple_trace_test_blah(void *context, const char *filename);
void _simple_trace_test_wibble(void *context, int value);
#define TRACE_TEST_BLAH_BACKEND_DSTATE() ( \
trace_event_get_state_dynamic_by_id(TRACE_TEST_BLAH) || \
false)
static inline void trace_test_blah(void *context, const char *filename)
{
if (trace_event_get_state(TRACE_TEST_BLAH)) {
_simple_trace_test_blah(context, filename);
}
}
#define TRACE_TEST_WIBBLE_BACKEND_DSTATE() ( \
trace_event_get_state_dynamic_by_id(TRACE_TEST_WIBBLE) || \
false)
static inline void trace_test_wibble(void *context, int value)
{
if (trace_event_get_state(TRACE_TEST_WIBBLE)) {
_simple_trace_test_wibble(context, value);
}
}
#endif /* TRACE_TESTSUITE_GENERATED_TRACERS_H */

32
tests/tracetool/syslog.c Normal file
View file

@ -0,0 +1,32 @@
/* This file is autogenerated by tracetool, do not edit. */
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "qemu/osdep.h"
#include "qemu/module.h"
#include "trace-testsuite.h"
uint16_t _TRACE_TEST_BLAH_DSTATE;
uint16_t _TRACE_TEST_WIBBLE_DSTATE;
TraceEvent _TRACE_TEST_BLAH_EVENT = {
.id = 0,
.name = "test_blah",
.sstate = TRACE_TEST_BLAH_ENABLED,
.dstate = &_TRACE_TEST_BLAH_DSTATE
};
TraceEvent _TRACE_TEST_WIBBLE_EVENT = {
.id = 0,
.name = "test_wibble",
.sstate = TRACE_TEST_WIBBLE_ENABLED,
.dstate = &_TRACE_TEST_WIBBLE_DSTATE
};
TraceEvent *testsuite_trace_events[] = {
&_TRACE_TEST_BLAH_EVENT,
&_TRACE_TEST_WIBBLE_EVENT,
NULL,
};
static void trace_testsuite_register_events(void)
{
trace_event_register_group(testsuite_trace_events);
}
trace_init(trace_testsuite_register_events)

43
tests/tracetool/syslog.h Normal file
View file

@ -0,0 +1,43 @@
/* This file is autogenerated by tracetool, do not edit. */
/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef TRACE_TESTSUITE_GENERATED_TRACERS_H
#define TRACE_TESTSUITE_GENERATED_TRACERS_H
#include "trace/control.h"
extern TraceEvent _TRACE_TEST_BLAH_EVENT;
extern TraceEvent _TRACE_TEST_WIBBLE_EVENT;
extern uint16_t _TRACE_TEST_BLAH_DSTATE;
extern uint16_t _TRACE_TEST_WIBBLE_DSTATE;
#define TRACE_TEST_BLAH_ENABLED 1
#define TRACE_TEST_WIBBLE_ENABLED 1
#include <syslog.h>
#define TRACE_TEST_BLAH_BACKEND_DSTATE() ( \
trace_event_get_state_dynamic_by_id(TRACE_TEST_BLAH) || \
false)
static inline void trace_test_blah(void *context, const char *filename)
{
if (trace_event_get_state(TRACE_TEST_BLAH)) {
#line 4 "trace-events"
syslog(LOG_INFO, "test_blah " "Blah context=%p filename=%s" , context, filename);
#line 28 "syslog.h"
}
}
#define TRACE_TEST_WIBBLE_BACKEND_DSTATE() ( \
trace_event_get_state_dynamic_by_id(TRACE_TEST_WIBBLE) || \
false)
static inline void trace_test_wibble(void *context, int value)
{
if (trace_event_get_state(TRACE_TEST_WIBBLE)) {
#line 5 "trace-events"
syslog(LOG_INFO, "test_wibble " "Wibble context=%p value=%d" , context, value);
#line 41 "syslog.h"
}
}
#endif /* TRACE_TESTSUITE_GENERATED_TRACERS_H */

View file

@ -0,0 +1,5 @@
# See docs/devel/tracing.rst for syntax documentation.
# SPDX-License-Identifier: GPL-2.0-or-later
test_blah(void *context, const char *filename) "Blah context=%p filename=%s"
test_wibble(void *context, int value) "Wibble context=%p value=%d"

107
tests/tracetool/tracetool-test.py Executable file
View file

@ -0,0 +1,107 @@
#!/usr/bin/python3
# SPDX-License-Identifier: GPL-2.0-or-later
import os
from pathlib import Path
from shutil import copyfile
from subprocess import check_call
import sys
import tempfile
def get_formats(backend):
formats = [
"c",
"h",
]
if backend == "dtrace":
formats += [
"d",
"log-stap",
"simpletrace-stap",
"stap",
]
if backend == "ust":
formats += [
"ust-events-c",
"ust-events-h",
]
return formats
def test_tracetool_one(tracetool, backend, fmt, src_dir, build_dir):
rel_filename = backend + "." + fmt
actual_file = Path(build_dir, rel_filename)
expect_file = Path(src_dir, rel_filename)
args = [tracetool, f"--format={fmt}", f"--backends={backend}", "--group=testsuite"]
if fmt.find("stap") != -1:
args += ["--binary=qemu", "--probe-prefix=qemu"]
# Use relative files for both, as these filenames end
# up in '#line' statements in the output
args += ["trace-events", rel_filename]
try:
check_call(args, cwd=build_dir)
actual = actual_file.read_text()
finally:
actual_file.unlink()
if os.getenv("QEMU_TEST_REGENERATE", False):
print(f"# regenerate {expect_file}")
expect_file.write_text(actual)
expect = expect_file.read_text()
assert expect == actual
def test_tracetool(tracetool, backend, source_dir, build_dir):
fail = False
scenarios = len(get_formats(backend))
print(f"1..{scenarios}")
src_events = Path(source_dir, "trace-events")
build_events = Path(build_dir, "trace-events")
try:
# We need a stable relative filename under build dir
# for the '#line' statements, so copy over the input
copyfile(src_events, build_events)
num = 1
for fmt in get_formats(backend):
status = "not ok"
hint = ""
try:
test_tracetool_one(tracetool, backend, fmt, source_dir, build_dir)
status = "ok"
except Exception as e:
print(f"# {e}")
fail = True
hint = (
" (set QEMU_TEST_REGENERATE=1 to recreate reference "
+ "output if tracetool generator was intentionally changed)"
)
finally:
print(f"{status} {num} - {backend}.{fmt}{hint}")
finally:
build_events.unlink()
return fail
if __name__ == "__main__":
if len(sys.argv) != 5:
argv0 = sys.argv[0]
print("syntax: {argv0} TRACE-TOOL BACKEND SRC-DIR BUILD-DIR", file=sys.stderr)
sys.exit(1)
with tempfile.TemporaryDirectory(prefix=sys.argv[4]) as tmpdir:
fail = test_tracetool(sys.argv[1], sys.argv[2], sys.argv[3], tmpdir)
if fail:
sys.exit(1)
sys.exit(0)

32
tests/tracetool/ust.c Normal file
View file

@ -0,0 +1,32 @@
/* This file is autogenerated by tracetool, do not edit. */
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "qemu/osdep.h"
#include "qemu/module.h"
#include "trace-testsuite.h"
uint16_t _TRACE_TEST_BLAH_DSTATE;
uint16_t _TRACE_TEST_WIBBLE_DSTATE;
TraceEvent _TRACE_TEST_BLAH_EVENT = {
.id = 0,
.name = "test_blah",
.sstate = TRACE_TEST_BLAH_ENABLED,
.dstate = &_TRACE_TEST_BLAH_DSTATE
};
TraceEvent _TRACE_TEST_WIBBLE_EVENT = {
.id = 0,
.name = "test_wibble",
.sstate = TRACE_TEST_WIBBLE_ENABLED,
.dstate = &_TRACE_TEST_WIBBLE_DSTATE
};
TraceEvent *testsuite_trace_events[] = {
&_TRACE_TEST_BLAH_EVENT,
&_TRACE_TEST_WIBBLE_EVENT,
NULL,
};
static void trace_testsuite_register_events(void)
{
trace_event_register_group(testsuite_trace_events);
}
trace_init(trace_testsuite_register_events)

41
tests/tracetool/ust.h Normal file
View file

@ -0,0 +1,41 @@
/* This file is autogenerated by tracetool, do not edit. */
/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef TRACE_TESTSUITE_GENERATED_TRACERS_H
#define TRACE_TESTSUITE_GENERATED_TRACERS_H
#include "trace/control.h"
extern TraceEvent _TRACE_TEST_BLAH_EVENT;
extern TraceEvent _TRACE_TEST_WIBBLE_EVENT;
extern uint16_t _TRACE_TEST_BLAH_DSTATE;
extern uint16_t _TRACE_TEST_WIBBLE_DSTATE;
#define TRACE_TEST_BLAH_ENABLED 1
#define TRACE_TEST_WIBBLE_ENABLED 1
#include <lttng/tracepoint.h>
#include "trace-ust-testsuite.h"
/* tracepoint_enabled() was introduced in LTTng UST 2.7 */
#ifndef tracepoint_enabled
#define tracepoint_enabled(a, b) true
#endif
#define TRACE_TEST_BLAH_BACKEND_DSTATE() ( \
tracepoint_enabled(qemu, test_blah) || \
false)
static inline void trace_test_blah(void *context, const char *filename)
{
tracepoint(qemu, test_blah, context, filename);
}
#define TRACE_TEST_WIBBLE_BACKEND_DSTATE() ( \
tracepoint_enabled(qemu, test_wibble) || \
false)
static inline void trace_test_wibble(void *context, int value)
{
tracepoint(qemu, test_wibble, context, value);
}
#endif /* TRACE_TESTSUITE_GENERATED_TRACERS_H */

View file

@ -0,0 +1,14 @@
/* This file is autogenerated by tracetool, do not edit. */
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "qemu/osdep.h"
#define TRACEPOINT_DEFINE
#define TRACEPOINT_CREATE_PROBES
/* If gcc version 4.7 or older is used, LTTng ust gives a warning when compiling with
-Wredundant-decls.
*/
#pragma GCC diagnostic ignored "-Wredundant-decls"
#include "trace-ust-all.h"

View file

@ -0,0 +1,56 @@
/* This file is autogenerated by tracetool, do not edit. */
/* SPDX-License-Identifier: GPL-2.0-or-later */
#undef TRACEPOINT_PROVIDER
#define TRACEPOINT_PROVIDER qemu
#undef TRACEPOINT_INCLUDE
#define TRACEPOINT_INCLUDE "./trace-ust.h"
#if !defined (TRACE_TESTSUITE_GENERATED_UST_H) || \
defined(TRACEPOINT_HEADER_MULTI_READ)
#define TRACE_TESTSUITE_GENERATED_UST_H
#include <lttng/tracepoint.h>
/*
* LTTng ust 2.0 does not allow you to use TP_ARGS(void) for tracepoints
* requiring no arguments. We define these macros introduced in more recent * versions of LTTng ust as a workaround
*/
#ifndef _TP_EXPROTO1
#define _TP_EXPROTO1(a) void
#endif
#ifndef _TP_EXDATA_PROTO1
#define _TP_EXDATA_PROTO1(a) void *__tp_data
#endif
#ifndef _TP_EXDATA_VAR1
#define _TP_EXDATA_VAR1(a) __tp_data
#endif
#ifndef _TP_EXVAR1
#define _TP_EXVAR1(a)
#endif
TRACEPOINT_EVENT(
qemu,
test_blah,
TP_ARGS(void *, context, const char *, filename),
TP_FIELDS(
ctf_integer_hex(void *, context, context)
ctf_string(filename, filename)
)
)
TRACEPOINT_EVENT(
qemu,
test_wibble,
TP_ARGS(void *, context, int, value),
TP_FIELDS(
ctf_integer_hex(void *, context, context)
ctf_integer(int, value, value)
)
)
#endif /* TRACE_TESTSUITE_GENERATED_UST_H */
/* This part must be outside ifdef protection */
#include <lttng/tracepoint-event.h>