From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 8324BCF34AC for ; Wed, 19 Nov 2025 19:37:18 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vLnzN-0003lN-VP; Wed, 19 Nov 2025 14:37:14 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vLnzJ-0003jz-49 for qemu-rust@nongnu.org; Wed, 19 Nov 2025 14:37:09 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vLnzF-0007Bc-8F for qemu-rust@nongnu.org; Wed, 19 Nov 2025 14:37:08 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1763581023; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=S7WF8ImQWZDIpLHMaA0pPvtG3C2qF+ifFTWB2DA+A4c=; b=Vq62st0U0qnJ0MOgAGhNBGFYQdDZtNIhxiXdSIqeB+OqKeKd/PJFZCba2pQuMThM9SyOLw aIoUcwTk/xSChqwNTbvGJ/54RJzgri+RpYudSWFYjkkrlu05spMrBW66fGnXatm1QXgyi5 lDNa4Q4xFEW0qoLds9QsBJn8WzOb9JI= Received: from mail-wm1-f69.google.com (mail-wm1-f69.google.com [209.85.128.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-20-u3P4L5mfNQSLle4hux-PLw-1; Wed, 19 Nov 2025 14:37:00 -0500 X-MC-Unique: u3P4L5mfNQSLle4hux-PLw-1 X-Mimecast-MFC-AGG-ID: u3P4L5mfNQSLle4hux-PLw_1763581020 Received: by mail-wm1-f69.google.com with SMTP id 5b1f17b1804b1-47788165c97so726955e9.0 for ; Wed, 19 Nov 2025 11:37:00 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763581019; x=1764185819; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=S7WF8ImQWZDIpLHMaA0pPvtG3C2qF+ifFTWB2DA+A4c=; b=Sw0YRXMkhOoqPca12dvqohSneVDOLsWQPnDG7q9X2fH2kJeprT+l0UGqz5L3oo+L2F w/0ikYTTto//YjumPhk4e0Yx9b5FpFlRwZHYLT1pNHqKAEtaSFIpbSDFemenIz67FuPU DNywZgnXoPXMoePIz+IG6XkGVD2aL9cbgo74UJgpLlkpaoOrBG0a3jtOjRZkwCeaQu6S IzYrWCybAjSBCqfd8COBkFRkkey+eFqTGhQEXEcLK7G/QokM2aZTWBX9jvkyA8ekN4kZ J6B5GaAnAHGetqJSYK7tKy8iQReHY1g6Z7f9XmACm6BMz91OwIwQn7v+R3PN4J9tRhFE 9kyw== X-Forwarded-Encrypted: i=1; AJvYcCWzNhha62P/m3S1sRCot6OnoqkKllKYvCBKwtrT6jRy0WPEuuTiRIXqUizyfos+r+ds4JZcKtsOHL4=@nongnu.org X-Gm-Message-State: AOJu0YwZHQaNJQ0tg1d8ujI769BGsc4u9dM6TxBY+e5wX7maeptLXnFb dL1/c8HMOc15mwHY3auOED9nFjZrrwulNc6lUbv1N66uS2bqTPqR7be/qMhupcOuPxmIx8hrb5n JpCiimBZBLVHUDwzK2AVICAQiICV8EVRSCiL91A11c0GoYfGkWRc6F7gEcf30osDie1v8qt1za7 4koEm29JmpSl3k04WYXixI/3Jc70aXfw== X-Gm-Gg: ASbGncticuoxApUFF/byvxXMxu/iKWVAY88Lz6bRmhblcP5xJwq5j6s/MIBfgTXNCbj 79mrP2WCCh0c66ULo5OSin0sAiJa00zc+b9uyWSia/T32YsHUGky45TTrgedTVL3A2IqwHyEO9j BDSsM5usQTcluoOBMIwtCspe1Ohj6CLs/oyqd7bfuyDF/t5eV+Fn7M6N6E8gaQBbtRdtLJjIA+S KcRMlnBf2FavLFWu3zxD7mQneeIPgzhykhKvoXkpzwJsKAyWBWXHlsWWF/0N+xs+P3JH8A= X-Received: by 2002:a05:600c:628f:b0:477:9a28:b09a with SMTP id 5b1f17b1804b1-477b8357dd3mr6517145e9.0.1763581019439; Wed, 19 Nov 2025 11:36:59 -0800 (PST) X-Google-Smtp-Source: AGHT+IFD+bjbxE1xstP/r9p4Q6yU8hTsBEzpaReR7ZByVIRGp4ge7XuRx2PYSWhapA44NnUPOsv/McOH5E/p7vwbBO4= X-Received: by 2002:a05:600c:628f:b0:477:9a28:b09a with SMTP id 5b1f17b1804b1-477b8357dd3mr6516845e9.0.1763581018866; Wed, 19 Nov 2025 11:36:58 -0800 (PST) MIME-Version: 1.0 References: <20251119181821.154833-1-stefanha@redhat.com> <20251119181821.154833-3-stefanha@redhat.com> In-Reply-To: <20251119181821.154833-3-stefanha@redhat.com> From: Paolo Bonzini Date: Wed, 19 Nov 2025 20:36:49 +0100 X-Gm-Features: AWmQ_bn21LkPAFOGTgO7m1ZAcV2oGy16UaGh_fUYMIgQPu5y-r9Ghro-peokgPc Message-ID: Subject: Re: [PATCH 2/2] tracetool: add Rust DTrace/SystemTap SDT support To: Stefan Hajnoczi Cc: qemu-devel , Mads Ynddal , "open list:Rust-related patc..." , Josh Stone , =?UTF-8?Q?Philippe_Mathieu=2DDaud=C3=A9?= , Manos Pitsidianakis , Thomas Huth , =?UTF-8?B?QWxleCBCZW5uw6ll?= X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: mb1nTmdSWtdsPkkeSjDq5KYX5kyjct22J4xBAJqPDiQ_1763581020 X-Mimecast-Originator: redhat.com Content-Type: multipart/alternative; boundary="0000000000002992c50643f7b450" Received-SPF: pass client-ip=170.10.133.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-rust@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: QEMU Rust-related patches and discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-rust-bounces+qemu-rust=archiver.kernel.org@nongnu.org Sender: qemu-rust-bounces+qemu-rust=archiver.kernel.org@nongnu.org --0000000000002992c50643f7b450 Content-Type: text/plain; charset="UTF-8" Il mer 19 nov 2025, 19:18 Stefan Hajnoczi ha scritto: > Implement DTrace/SystemTap SDT by emitting the following: > - The probe crate's probe!() macro is used to emit a DTrace/SystemTap > SDT probe. > - Every trace event gets a corresponding trace__enabled() -> bool > generated function that Rust code can use to avoid expensive > computation when a trace event is disabled. This API works for other > trace backends too. > > `#[allow(dead_code)]` additions are necessary for QEMU's dstate in > generated trace-.rs files since they are unused by the dtrace > backend. `./configure --enable-trace-backends=` can enable multiple > backends, so keep it simple and just silence the warning instead of > trying to detect the condition when generating the dstate code can be > skipped. > > The tracetool tests are updated. Take a look at > tests/tracetool/dtrace.rs to see what the new generated code looks like. > > Signed-off-by: Stefan Hajnoczi > --- > I'm not sure if Cargo.toml, Cargo.lock, and meson.build are in > sync/consistent, but it builds successfully. I find the Rust build > system integration confusing because I'm not an expert in cargo or > meson. Please review the build system changes carefully. > The only change I'd make, is to re-export probe::probe from the trace crate, like it already does for libc. This way you don't need the change to rust/hw/char/pl011/meson.build. Otherwise it works great, and it's nice that we can reuse the C semaphore to avoid changes to the probe crate. Hopefully within a few months all the subprojects will not need anymore the current boilerplate. Paolo --- > rust/Cargo.lock | 6 +++ > rust/hw/char/pl011/meson.build | 1 + > rust/hw/timer/hpet/meson.build | 1 + > rust/trace/Cargo.toml | 1 + > rust/trace/meson.build | 2 +- > scripts/tracetool/__init__.py | 1 + > scripts/tracetool/backend/dtrace.py | 32 ++++++++++++++ > scripts/tracetool/format/rs.py | 27 ++++++++++-- > tests/tracetool/dtrace.rs | 65 +++++++++++++++++++++++++++++ > tests/tracetool/ftrace.rs | 21 ++++++++++ > tests/tracetool/log.rs | 21 ++++++++++ > tests/tracetool/simple.rs | 21 ++++++++++ > tests/tracetool/syslog.rs | 21 ++++++++++ > tests/tracetool/tracetool-test.py | 2 +- > 14 files changed, 216 insertions(+), 6 deletions(-) > create mode 100644 tests/tracetool/dtrace.rs > > diff --git a/rust/Cargo.lock b/rust/Cargo.lock > index 0c1df625df..5bd768cb0d 100644 > --- a/rust/Cargo.lock > +++ b/rust/Cargo.lock > @@ -144,6 +144,7 @@ dependencies = [ > "migration", > "qom", > "system", > + "trace", > "util", > ] > > @@ -229,6 +230,10 @@ dependencies = [ > "util", > ] > > +[[package]] > +name = "probe" > +version = "0.5.2" > + > [[package]] > name = "proc-macro-error" > version = "1.0.4" > @@ -429,6 +434,7 @@ name = "trace" > version = "0.1.0" > dependencies = [ > "libc", > + "probe", > ] > > [[package]] > diff --git a/rust/hw/char/pl011/meson.build > b/rust/hw/char/pl011/meson.build > index 33b91f2191..5b6ea274a2 100644 > --- a/rust/hw/char/pl011/meson.build > +++ b/rust/hw/char/pl011/meson.build > @@ -37,6 +37,7 @@ _libpl011_rs = static_library( > util_rs, > migration_rs, > bql_rs, > + probe_rs, > qom_rs, > chardev_rs, > system_rs, > diff --git a/rust/hw/timer/hpet/meson.build > b/rust/hw/timer/hpet/meson.build > index 465995bb5a..4e95754b20 100644 > --- a/rust/hw/timer/hpet/meson.build > +++ b/rust/hw/timer/hpet/meson.build > @@ -8,6 +8,7 @@ _libhpet_rs = static_library( > util_rs, > migration_rs, > bql_rs, > + probe_rs, > qom_rs, > system_rs, > hwcore_rs, > diff --git a/rust/trace/Cargo.toml b/rust/trace/Cargo.toml > index fc81bce580..11e27f8d28 100644 > --- a/rust/trace/Cargo.toml > +++ b/rust/trace/Cargo.toml > @@ -14,6 +14,7 @@ rust-version.workspace = true > > [dependencies] > libc = { workspace = true } > +probe = "0.5" > > [lints] > workspace = true > diff --git a/rust/trace/meson.build b/rust/trace/meson.build > index adca57e550..cf6b0355a8 100644 > --- a/rust/trace/meson.build > +++ b/rust/trace/meson.build > @@ -12,7 +12,7 @@ _trace_rs = static_library( > lib_rs, > trace_rs_targets, # List of generated `.rs` custom targets > override_options: ['rust_std=2021', 'build.rust_std=2021'], > - dependencies: [libc_rs], > + dependencies: [libc_rs, probe_rs], > rust_abi: 'rust', > ) > > diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py > index 74062d21a7..61ba6f1ba8 100644 > --- a/scripts/tracetool/__init__.py > +++ b/scripts/tracetool/__init__.py > @@ -461,6 +461,7 @@ def formats(self): > > QEMU_TRACE = "trace_%(name)s" > QEMU_TRACE_TCG = QEMU_TRACE + "_tcg" > + QEMU_RUST_DSTATE = "trace_%(name)s_enabled" > QEMU_DSTATE = "_TRACE_%(NAME)s_DSTATE" > QEMU_BACKEND_DSTATE = "TRACE_%(NAME)s_BACKEND_DSTATE" > QEMU_EVENT = "_TRACE_%(NAME)s_EVENT" > diff --git a/scripts/tracetool/backend/dtrace.py > b/scripts/tracetool/backend/dtrace.py > index b4af403025..548e228c81 100644 > --- a/scripts/tracetool/backend/dtrace.py > +++ b/scripts/tracetool/backend/dtrace.py > @@ -70,3 +70,35 @@ def generate_h(event, group): > def generate_h_backend_dstate(event, group): > out(' QEMU_%(uppername)s_ENABLED() || \\', > uppername=event.name.upper()) > + > + > +def generate_rs_begin(events, group): > + out('use probe::probe;', > + 'use std::cell::UnsafeCell;', > + '', > + 'extern "C" {') > + # These are the Rust declarations of the .probes section semaphores > + # generated by dtrace(1) in its .o file output. > + for e in events: > + if 'disable' in e.properties: > + continue > + out(' #[allow(dead_code)]', > + f' static qemu_{e.name}_semaphore: UnsafeCell;') > + out('}', > + '') > + > + > +def generate_rs(event, group): > + args = event.args.rust_call_extern() > + if args: > + args = ', ' + args > + > + out(f' probe!(qemu, {event.name}{args});') > + > + > +def generate_rs_backend_dstate(event, group): > + # Rust does not have access to the __ENABLED() macro > from > + # the dtrace(1) generated .h file. Use the matching semaphore > declarations > + # generated by generate_rs_begin() instead. > + out(' (unsafe {qemu_%(n)s_semaphore.get().read_volatile()}) != 0 > ||', > + n=event.name) > diff --git a/scripts/tracetool/format/rs.py > b/scripts/tracetool/format/rs.py > index 32ac4e5977..7d9af7edfe 100644 > --- a/scripts/tracetool/format/rs.py > +++ b/scripts/tracetool/format/rs.py > @@ -24,25 +24,43 @@ def generate(events, backend, group): > '#[allow(unused_imports)]', > 'use util::bindings;', > '', > + '#[allow(dead_code)]', > '#[inline(always)]', > 'fn trace_event_state_is_enabled(dstate: u16) -> bool {', > ' (unsafe { trace_events_enabled_count }) != 0 && dstate != 0', > '}', > '', > 'extern "C" {', > + ' #[allow(dead_code)]', > ' static mut trace_events_enabled_count: u32;', > '}',) > > out('extern "C" {') > > for e in events: > - out(' static mut %s: u16;' % e.api(e.QEMU_DSTATE)) > - out('}') > + out(' #[allow(dead_code)]', > + ' static mut %s: u16;' % e.api(e.QEMU_DSTATE)) > + out('}', > + '') > > backend.generate_begin(events, group) > > for e in events: > - out('', > + out('#[inline(always)]', > + '#[allow(dead_code)]', > + 'pub fn %(api)s() -> bool', > + '{', > + api=e.api(e.QEMU_RUST_DSTATE)) > + > + if "disable" not in e.properties: > + backend.generate_backend_dstate(e, group) > + if backend.check_trace_event_get_state: > + out(' trace_event_state_is_enabled(unsafe { > _%(event_id)s_DSTATE}) ||', > + event_id = 'TRACE_' + e.name.upper()) > + > + out(' false', > + '}', > + '', > '#[inline(always)]', > '#[allow(dead_code)]', > 'pub fn %(api)s(%(args)s)', > @@ -59,6 +77,7 @@ def generate(events, backend, group): > api=e.api()) > backend.generate(e, group, > check_trace_event_get_state=True) > out(' }') > - out('}') > + out('}', > + '') > > backend.generate_end(events, group) > diff --git a/tests/tracetool/dtrace.rs b/tests/tracetool/dtrace.rs > new file mode 100644 > index 0000000000..233c2ef159 > --- /dev/null > +++ b/tests/tracetool/dtrace.rs > @@ -0,0 +1,65 @@ > +// SPDX-License-Identifier: GPL-2.0-or-later > +// This file is @generated by tracetool, do not edit. > + > +#[allow(unused_imports)] > +use std::ffi::c_char; > +#[allow(unused_imports)] > +use util::bindings; > + > +#[allow(dead_code)] > +#[inline(always)] > +fn trace_event_state_is_enabled(dstate: u16) -> bool { > + (unsafe { trace_events_enabled_count }) != 0 && dstate != 0 > +} > + > +extern "C" { > + #[allow(dead_code)] > + static mut trace_events_enabled_count: u32; > +} > +extern "C" { > + #[allow(dead_code)] > + static mut _TRACE_TEST_BLAH_DSTATE: u16; > + #[allow(dead_code)] > + static mut _TRACE_TEST_WIBBLE_DSTATE: u16; > +} > + > +use probe::probe; > +use std::cell::UnsafeCell; > + > +extern "C" { > + #[allow(dead_code)] > + static qemu_test_blah_semaphore: UnsafeCell; > + #[allow(dead_code)] > + static qemu_test_wibble_semaphore: UnsafeCell; > +} > + > +#[inline(always)] > +#[allow(dead_code)] > +pub fn trace_test_blah_enabled() -> bool > +{ > + (unsafe {qemu_test_blah_semaphore.get().read_volatile()}) != 0 || > + false > +} > + > +#[inline(always)] > +#[allow(dead_code)] > +pub fn trace_test_blah(_context: *mut (), _filename: &std::ffi::CStr) > +{ > + probe!(qemu, test_blah, _context, _filename.as_ptr()); > +} > + > +#[inline(always)] > +#[allow(dead_code)] > +pub fn trace_test_wibble_enabled() -> bool > +{ > + (unsafe {qemu_test_wibble_semaphore.get().read_volatile()}) != 0 || > + false > +} > + > +#[inline(always)] > +#[allow(dead_code)] > +pub fn trace_test_wibble(_context: *mut (), _value: std::ffi::c_int) > +{ > + probe!(qemu, test_wibble, _context, _value); > +} > + > diff --git a/tests/tracetool/ftrace.rs b/tests/tracetool/ftrace.rs > index 07b9259cf2..34f6600490 100644 > --- a/tests/tracetool/ftrace.rs > +++ b/tests/tracetool/ftrace.rs > @@ -6,19 +6,31 @@ > #[allow(unused_imports)] > use util::bindings; > > +#[allow(dead_code)] > #[inline(always)] > fn trace_event_state_is_enabled(dstate: u16) -> bool { > (unsafe { trace_events_enabled_count }) != 0 && dstate != 0 > } > > extern "C" { > + #[allow(dead_code)] > static mut trace_events_enabled_count: u32; > } > extern "C" { > + #[allow(dead_code)] > static mut _TRACE_TEST_BLAH_DSTATE: u16; > + #[allow(dead_code)] > static mut _TRACE_TEST_WIBBLE_DSTATE: u16; > } > > +#[inline(always)] > +#[allow(dead_code)] > +pub fn trace_test_blah_enabled() -> bool > +{ > + trace_event_state_is_enabled(unsafe { _TRACE_TEST_BLAH_DSTATE}) || > + false > +} > + > #[inline(always)] > #[allow(dead_code)] > pub fn trace_test_blah(_context: *mut (), _filename: &std::ffi::CStr) > @@ -29,6 +41,14 @@ pub fn trace_test_blah(_context: *mut (), _filename: > &std::ffi::CStr) > } > } > > +#[inline(always)] > +#[allow(dead_code)] > +pub fn trace_test_wibble_enabled() -> bool > +{ > + trace_event_state_is_enabled(unsafe { _TRACE_TEST_WIBBLE_DSTATE}) || > + false > +} > + > #[inline(always)] > #[allow(dead_code)] > pub fn trace_test_wibble(_context: *mut (), _value: std::ffi::c_int) > @@ -38,3 +58,4 @@ pub fn trace_test_wibble(_context: *mut (), _value: > std::ffi::c_int) > unsafe {bindings::ftrace_write(format_string.as_ptr() as *const > c_char, _context /* as *mut () */, _value /* as std::ffi::c_int */);} > } > } > + > diff --git a/tests/tracetool/log.rs b/tests/tracetool/log.rs > index c191895c8f..770758611d 100644 > --- a/tests/tracetool/log.rs > +++ b/tests/tracetool/log.rs > @@ -6,19 +6,31 @@ > #[allow(unused_imports)] > use util::bindings; > > +#[allow(dead_code)] > #[inline(always)] > fn trace_event_state_is_enabled(dstate: u16) -> bool { > (unsafe { trace_events_enabled_count }) != 0 && dstate != 0 > } > > extern "C" { > + #[allow(dead_code)] > static mut trace_events_enabled_count: u32; > } > extern "C" { > + #[allow(dead_code)] > static mut _TRACE_TEST_BLAH_DSTATE: u16; > + #[allow(dead_code)] > static mut _TRACE_TEST_WIBBLE_DSTATE: u16; > } > > +#[inline(always)] > +#[allow(dead_code)] > +pub fn trace_test_blah_enabled() -> bool > +{ > + trace_event_state_is_enabled(unsafe { _TRACE_TEST_BLAH_DSTATE}) || > + false > +} > + > #[inline(always)] > #[allow(dead_code)] > pub fn trace_test_blah(_context: *mut (), _filename: &std::ffi::CStr) > @@ -31,6 +43,14 @@ pub fn trace_test_blah(_context: *mut (), _filename: > &std::ffi::CStr) > } > } > > +#[inline(always)] > +#[allow(dead_code)] > +pub fn trace_test_wibble_enabled() -> bool > +{ > + trace_event_state_is_enabled(unsafe { _TRACE_TEST_WIBBLE_DSTATE}) || > + false > +} > + > #[inline(always)] > #[allow(dead_code)] > pub fn trace_test_wibble(_context: *mut (), _value: std::ffi::c_int) > @@ -42,3 +62,4 @@ pub fn trace_test_wibble(_context: *mut (), _value: > std::ffi::c_int) > } > } > } > + > diff --git a/tests/tracetool/simple.rs b/tests/tracetool/simple.rs > index 9ee39495e3..92f896ef17 100644 > --- a/tests/tracetool/simple.rs > +++ b/tests/tracetool/simple.rs > @@ -6,19 +6,31 @@ > #[allow(unused_imports)] > use util::bindings; > > +#[allow(dead_code)] > #[inline(always)] > fn trace_event_state_is_enabled(dstate: u16) -> bool { > (unsafe { trace_events_enabled_count }) != 0 && dstate != 0 > } > > extern "C" { > + #[allow(dead_code)] > static mut trace_events_enabled_count: u32; > } > extern "C" { > + #[allow(dead_code)] > static mut _TRACE_TEST_BLAH_DSTATE: u16; > + #[allow(dead_code)] > static mut _TRACE_TEST_WIBBLE_DSTATE: u16; > } > > +#[inline(always)] > +#[allow(dead_code)] > +pub fn trace_test_blah_enabled() -> bool > +{ > + trace_event_state_is_enabled(unsafe { _TRACE_TEST_BLAH_DSTATE}) || > + false > +} > + > #[inline(always)] > #[allow(dead_code)] > pub fn trace_test_blah(_context: *mut (), _filename: &std::ffi::CStr) > @@ -29,6 +41,14 @@ pub fn trace_test_blah(_context: *mut (), _filename: > &std::ffi::CStr) > } > } > > +#[inline(always)] > +#[allow(dead_code)] > +pub fn trace_test_wibble_enabled() -> bool > +{ > + trace_event_state_is_enabled(unsafe { _TRACE_TEST_WIBBLE_DSTATE}) || > + false > +} > + > #[inline(always)] > #[allow(dead_code)] > pub fn trace_test_wibble(_context: *mut (), _value: std::ffi::c_int) > @@ -38,3 +58,4 @@ pub fn trace_test_wibble(_context: *mut (), _value: > std::ffi::c_int) > unsafe { _simple_trace_test_wibble(_context, _value); } > } > } > + > diff --git a/tests/tracetool/syslog.rs b/tests/tracetool/syslog.rs > index 9d3675a0b5..378d03d34b 100644 > --- a/tests/tracetool/syslog.rs > +++ b/tests/tracetool/syslog.rs > @@ -6,19 +6,31 @@ > #[allow(unused_imports)] > use util::bindings; > > +#[allow(dead_code)] > #[inline(always)] > fn trace_event_state_is_enabled(dstate: u16) -> bool { > (unsafe { trace_events_enabled_count }) != 0 && dstate != 0 > } > > extern "C" { > + #[allow(dead_code)] > static mut trace_events_enabled_count: u32; > } > extern "C" { > + #[allow(dead_code)] > static mut _TRACE_TEST_BLAH_DSTATE: u16; > + #[allow(dead_code)] > static mut _TRACE_TEST_WIBBLE_DSTATE: u16; > } > > +#[inline(always)] > +#[allow(dead_code)] > +pub fn trace_test_blah_enabled() -> bool > +{ > + trace_event_state_is_enabled(unsafe { _TRACE_TEST_BLAH_DSTATE}) || > + false > +} > + > #[inline(always)] > #[allow(dead_code)] > pub fn trace_test_blah(_context: *mut (), _filename: &std::ffi::CStr) > @@ -29,6 +41,14 @@ pub fn trace_test_blah(_context: *mut (), _filename: > &std::ffi::CStr) > } > } > > +#[inline(always)] > +#[allow(dead_code)] > +pub fn trace_test_wibble_enabled() -> bool > +{ > + trace_event_state_is_enabled(unsafe { _TRACE_TEST_WIBBLE_DSTATE}) || > + false > +} > + > #[inline(always)] > #[allow(dead_code)] > pub fn trace_test_wibble(_context: *mut (), _value: std::ffi::c_int) > @@ -38,3 +58,4 @@ pub fn trace_test_wibble(_context: *mut (), _value: > std::ffi::c_int) > unsafe {::trace::syslog(::trace::LOG_INFO, format_string.as_ptr() > as *const c_char, _context /* as *mut () */, _value /* as std::ffi::c_int > */);} > } > } > + > diff --git a/tests/tracetool/tracetool-test.py > b/tests/tracetool/tracetool-test.py > index 786083ad7f..30006a9919 100755 > --- a/tests/tracetool/tracetool-test.py > +++ b/tests/tracetool/tracetool-test.py > @@ -14,7 +14,7 @@ def get_formats(backend): > "c", > "h", > ] > - if backend in {"ftrace", "log", "simple", "syslog"}: > + if backend in {"dtrace", "ftrace", "log", "simple", "syslog"}: > formats += ["rs"] > if backend == "dtrace": > formats += [ > -- > 2.51.1 > > --0000000000002992c50643f7b450 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable


Il mer 19 nov 2025, 19:18 Stefan= Hajnoczi <stefanha@redhat.com> ha scritto:
dtrace.rs to see what the new generated code looks li= ke.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
I'm not sure if Cargo.toml, Cargo.lock, and meson.build are in
sync/consistent, but it builds successfully. I find the Rust build
system integration confusing because I'm not an expert in cargo or
meson. Please review the build system changes carefully.

The only change I&#= 39;d make, is to re-export probe::probe from the trace crate, like it alrea= dy does for libc. This way you don't need the change to rust/hw/char/pl= 011/meson.build.

Otherwi= se it works great, and it's nice that we can reuse the C semaphore to a= void changes to the probe crate.

Hopefully within a few months all the subprojects will not need a= nymore the current boilerplate.

Paolo

---
=C2=A0rust/Cargo.lock=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0|=C2=A0 6 +++
=C2=A0rust/hw/char/pl011/meson.build=C2=A0 =C2=A0 =C2=A0 |=C2=A0 1 +
=C2=A0rust/hw/timer/hpet/meson.build=C2=A0 =C2=A0 =C2=A0 |=C2=A0 1 +
=C2=A0rust/trace/Cargo.toml=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0|=C2=A0 1 +
=C2=A0rust/trace/meson.build=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 |=C2=A0 2 +-
=C2=A0scripts/tracetool/__init__.py=C2=A0 =C2=A0 =C2=A0 =C2=A0|=C2=A0 1 + =C2=A0scripts/tracetool/backend/dtrace.py | 32 ++++++++++++++
=C2=A0scripts/tracetool/format/rs.py=C2=A0 =C2=A0 =C2=A0 | 27 ++++++++++--<= br> =C2=A0tests/tracetool/dtrace.rs=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0| 65 +++++++++++++++++++++++++++++
=C2=A0tests/tracetool/ftrace.rs=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0| 21 ++++++++++
=C2=A0tests/tracetool/log.rs=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 | 21 ++++++++++
=C2=A0tests/tracetool/simple.rs=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0| 21 ++++++++++
=C2=A0tests/tracetool/syslog.rs=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0| 21 ++++++++++
=C2=A0tests/tracetool/tracetool-test.py=C2=A0 =C2=A0|=C2=A0 2 +-
=C2=A014 files changed, 216 insertions(+), 6 deletions(-)
=C2=A0create mode 100644 tests/tracetool/dtrace.rs

diff --git a/rust/Cargo.lock b/rust/Cargo.lock
index 0c1df625df..5bd768cb0d 100644
--- a/rust/Cargo.lock
+++ b/rust/Cargo.lock
@@ -144,6 +144,7 @@ dependencies =3D [
=C2=A0 "migration",
=C2=A0 "qom",
=C2=A0 "system",
+ "trace",
=C2=A0 "util",
=C2=A0]

@@ -229,6 +230,10 @@ dependencies =3D [
=C2=A0 "util",
=C2=A0]

+[[package]]
+name =3D "probe"
+version =3D "0.5.2"
+
=C2=A0[[package]]
=C2=A0name =3D "proc-macro-error"
=C2=A0version =3D "1.0.4"
@@ -429,6 +434,7 @@ name =3D "trace"
=C2=A0version =3D "0.1.0"
=C2=A0dependencies =3D [
=C2=A0 "libc",
+ "probe",
=C2=A0]

=C2=A0[[package]]
diff --git a/rust/hw/char/pl011/meson.build b/rust/hw/char/pl011/meson.buil= d
index 33b91f2191..5b6ea274a2 100644
--- a/rust/hw/char/pl011/meson.build
+++ b/rust/hw/char/pl011/meson.build
@@ -37,6 +37,7 @@ _libpl011_rs =3D static_library(
=C2=A0 =C2=A0 =C2=A0util_rs,
=C2=A0 =C2=A0 =C2=A0migration_rs,
=C2=A0 =C2=A0 =C2=A0bql_rs,
+=C2=A0 =C2=A0 probe_rs,
=C2=A0 =C2=A0 =C2=A0qom_rs,
=C2=A0 =C2=A0 =C2=A0chardev_rs,
=C2=A0 =C2=A0 =C2=A0system_rs,
diff --git a/rust/hw/timer/hpet/meson.build b/rust/hw/timer/hpet/meson.buil= d
index 465995bb5a..4e95754b20 100644
--- a/rust/hw/timer/hpet/meson.build
+++ b/rust/hw/timer/hpet/meson.build
@@ -8,6 +8,7 @@ _libhpet_rs =3D static_library(
=C2=A0 =C2=A0 =C2=A0util_rs,
=C2=A0 =C2=A0 =C2=A0migration_rs,
=C2=A0 =C2=A0 =C2=A0bql_rs,
+=C2=A0 =C2=A0 probe_rs,
=C2=A0 =C2=A0 =C2=A0qom_rs,
=C2=A0 =C2=A0 =C2=A0system_rs,
=C2=A0 =C2=A0 =C2=A0hwcore_rs,
diff --git a/rust/trace/Cargo.toml b/rust/trace/Cargo.toml
index fc81bce580..11e27f8d28 100644
--- a/rust/trace/Cargo.toml
+++ b/rust/trace/Cargo.toml
@@ -14,6 +14,7 @@ rust-version.workspace =3D true

=C2=A0[dependencies]
=C2=A0libc =3D { workspace =3D true }
+probe =3D "0.5"

=C2=A0[lints]
=C2=A0workspace =3D true
diff --git a/rust/trace/meson.build b/rust/trace/meson.build
index adca57e550..cf6b0355a8 100644
--- a/rust/trace/meson.build
+++ b/rust/trace/meson.build
@@ -12,7 +12,7 @@ _trace_rs =3D static_library(
=C2=A0 =C2=A0lib_rs,
=C2=A0 =C2=A0trace_rs_targets,=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0# List of g= enerated `.rs` custom targets
=C2=A0 =C2=A0override_options: ['rust_std=3D2021', 'build.rust_= std=3D2021'],
-=C2=A0 dependencies: [libc_rs],
+=C2=A0 dependencies: [libc_rs, probe_rs],
=C2=A0 =C2=A0rust_abi: 'rust',
=C2=A0)

diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py<= br> index 74062d21a7..61ba6f1ba8 100644
--- a/scripts/tracetool/__init__.py
+++ b/scripts/tracetool/__init__.py
@@ -461,6 +461,7 @@ def formats(self):

=C2=A0 =C2=A0 =C2=A0QEMU_TRACE=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0=3D "trace_%(name)s"
=C2=A0 =C2=A0 =C2=A0QEMU_TRACE_TCG=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =3D QEMU_TRACE + "_tcg"
+=C2=A0 =C2=A0 QEMU_RUST_DSTATE=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=3D "= trace_%(name)s_enabled"
=C2=A0 =C2=A0 =C2=A0QEMU_DSTATE=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =3D "_TRACE_%(NAME)s_DSTATE"
=C2=A0 =C2=A0 =C2=A0QEMU_BACKEND_DSTATE=C2=A0 =C2=A0 =C2=A0 =3D "TRACE= _%(NAME)s_BACKEND_DSTATE"
=C2=A0 =C2=A0 =C2=A0QEMU_EVENT=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0=3D "_TRACE_%(NAME)s_EVENT"
diff --git a/scripts/tracetool/backend/dtrace.py b/scripts/tracetool/backen= d/dtrace.py
index b4af403025..548e228c81 100644
--- a/scripts/tracetool/backend/dtrace.py
+++ b/scripts/tracetool/backend/dtrace.py
@@ -70,3 +70,35 @@ def generate_h(event, group):
=C2=A0def generate_h_backend_dstate(event, group):
=C2=A0 =C2=A0 =C2=A0out('=C2=A0 =C2=A0 QEMU_%(uppername)s_ENABLED() || = \\',
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0uppername=3Devent.name.upper())
+
+
+def generate_rs_begin(events, group):
+=C2=A0 =C2=A0 out('use probe::probe;',
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 'use std::cell::UnsafeCell;',
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 '',
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 'extern "C" {')
+=C2=A0 =C2=A0 # These are the Rust declarations of the .probes section sem= aphores
+=C2=A0 =C2=A0 # generated by dtrace(1) in its .o file output.
+=C2=A0 =C2=A0 for e in events:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 if 'disable' in e.properties:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 continue
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 out('=C2=A0 =C2=A0 #[allow(dead_code)]'= ;,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f'=C2=A0 =C2=A0 static qemu_= {= e.name}_semaphore: UnsafeCell<u16>;')
+=C2=A0 =C2=A0 out('}',
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 '')
+
+
+def generate_rs(event, group):
+=C2=A0 =C2=A0 args =3D event.args.rust_call_extern()
+=C2=A0 =C2=A0 if args:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 args =3D ', ' + args
+
+=C2=A0 =C2=A0 out(f'=C2=A0 =C2=A0 probe!(qemu, {event.name}{arg= s});')
+
+
+def generate_rs_backend_dstate(event, group):
+=C2=A0 =C2=A0 # Rust does not have access to the <provider>_<name= >_ENABLED() macro from
+=C2=A0 =C2=A0 # the dtrace(1) generated .h file. Use the matching semaphor= e declarations
+=C2=A0 =C2=A0 # generated by generate_rs_begin() instead.
+=C2=A0 =C2=A0 out('=C2=A0 =C2=A0 (unsafe {qemu_%(n)s_semaphore.get().r= ead_volatile()}) !=3D 0 ||',
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 n=3Devent.name)
diff --git a/scripts/tracetool/format/rs.py b/scripts/tracetool/format/rs.p= y
index 32ac4e5977..7d9af7edfe 100644
--- a/scripts/tracetool/format/rs.py
+++ b/scripts/tracetool/format/rs.py
@@ -24,25 +24,43 @@ def generate(events, backend, group):
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0'#[allow(unused_imports)]',
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0'use util::bindings;',
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0'',
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 '#[allow(dead_code)]',
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0'#[inline(always)]',
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0'fn trace_event_state_is_enabled(dsta= te: u16) -> bool {',
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0'=C2=A0 =C2=A0 (unsafe { trace_events= _enabled_count }) !=3D 0 && dstate !=3D 0',
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0'}',
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0'',
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0'extern "C" {',
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 '=C2=A0 =C2=A0 #[allow(dead_code)]', =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0'=C2=A0 =C2=A0 static mut trace_event= s_enabled_count: u32;',
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0'}',)

=C2=A0 =C2=A0 =C2=A0out('extern "C" {')

=C2=A0 =C2=A0 =C2=A0for e in events:
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 out('=C2=A0 =C2=A0 static mut %s: u16;'= ; % e.api(e.QEMU_DSTATE))
-=C2=A0 =C2=A0 out('}')
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 out('=C2=A0 =C2=A0 #[allow(dead_code)]'= ;,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 '=C2=A0 =C2=A0 static mut %s= : u16;' % e.api(e.QEMU_DSTATE))
+=C2=A0 =C2=A0 out('}',
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 '')

=C2=A0 =C2=A0 =C2=A0backend.generate_begin(events, group)

=C2=A0 =C2=A0 =C2=A0for e in events:
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 out('',
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 out('#[inline(always)]',
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 '#[allow(dead_code)]', +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 'pub fn %(api)s() -> bool= ',
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 '{',
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 api=3De.api(e.QEMU_RUST_DSTATE))=
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 if "disable" not in e.properties: +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 backend.generate_backend_dstate(= e, group)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if backend.check_trace_event_get= _state:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 out('=C2=A0 = =C2=A0 trace_event_state_is_enabled(unsafe { _%(event_id)s_DSTATE}) ||'= ,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 even= t_id =3D 'TRACE_' + e.name.upper())
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 out('=C2=A0 =C2=A0 false',
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 '}',
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 '',
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0'#[inline(always)]'= ,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0'#[allow(dead_code)]= 9;,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0'pub fn %(api)s(%(args)= s)',
@@ -59,6 +77,7 @@ def generate(events, backend, group):
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0api=3De.api())
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0backend.gener= ate(e, group, check_trace_event_get_state=3DTrue)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0out('=C2= =A0 =C2=A0 }')
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 out('}')
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 out('}',
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 '')

=C2=A0 =C2=A0 =C2=A0backend.generate_end(events, group)
diff --git a/tests/tracetool/dtrace.rs b/tests/tracetool/dtrace.rs<= /a>
new file mode 100644
index 0000000000..233c2ef159
--- /dev/null
+++ b/tests/tracetool/
dtrace.rs
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+// This file is @generated by tracetool, do not edit.
+
+#[allow(unused_imports)]
+use std::ffi::c_char;
+#[allow(unused_imports)]
+use util::bindings;
+
+#[allow(dead_code)]
+#[inline(always)]
+fn trace_event_state_is_enabled(dstate: u16) -> bool {
+=C2=A0 =C2=A0 (unsafe { trace_events_enabled_count }) !=3D 0 && ds= tate !=3D 0
+}
+
+extern "C" {
+=C2=A0 =C2=A0 #[allow(dead_code)]
+=C2=A0 =C2=A0 static mut trace_events_enabled_count: u32;
+}
+extern "C" {
+=C2=A0 =C2=A0 #[allow(dead_code)]
+=C2=A0 =C2=A0 static mut _TRACE_TEST_BLAH_DSTATE: u16;
+=C2=A0 =C2=A0 #[allow(dead_code)]
+=C2=A0 =C2=A0 static mut _TRACE_TEST_WIBBLE_DSTATE: u16;
+}
+
+use probe::probe;
+use std::cell::UnsafeCell;
+
+extern "C" {
+=C2=A0 =C2=A0 #[allow(dead_code)]
+=C2=A0 =C2=A0 static qemu_test_blah_semaphore: UnsafeCell<u16>;
+=C2=A0 =C2=A0 #[allow(dead_code)]
+=C2=A0 =C2=A0 static qemu_test_wibble_semaphore: UnsafeCell<u16>; +}
+
+#[inline(always)]
+#[allow(dead_code)]
+pub fn trace_test_blah_enabled() -> bool
+{
+=C2=A0 =C2=A0 (unsafe {qemu_test_blah_semaphore.get().read_volatile()}) != =3D 0 ||
+=C2=A0 =C2=A0 false
+}
+
+#[inline(always)]
+#[allow(dead_code)]
+pub fn trace_test_blah(_context: *mut (), _filename: &std::ffi::CStr)<= br> +{
+=C2=A0 =C2=A0 probe!(qemu, test_blah, _context, _filename.as_ptr());
+}
+
+#[inline(always)]
+#[allow(dead_code)]
+pub fn trace_test_wibble_enabled() -> bool
+{
+=C2=A0 =C2=A0 (unsafe {qemu_test_wibble_semaphore.get().read_volatile()}) = !=3D 0 ||
+=C2=A0 =C2=A0 false
+}
+
+#[inline(always)]
+#[allow(dead_code)]
+pub fn trace_test_wibble(_context: *mut (), _value: std::ffi::c_int)
+{
+=C2=A0 =C2=A0 probe!(qemu, test_wibble, _context, _value);
+}
+
diff --git a/tests/tracetool/ftrace.rs b/tests/tracetool/ftrace.rs<= /a>
index 07b9259cf2..34f6600490 100644
--- a/tests/tracetool/
ftrace.rs
+++ b/tests/tracetool/ftrace.rs
@@ -6,19 +6,31 @@
=C2=A0#[allow(unused_imports)]
=C2=A0use util::bindings;

+#[allow(dead_code)]
=C2=A0#[inline(always)]
=C2=A0fn trace_event_state_is_enabled(dstate: u16) -> bool {
=C2=A0 =C2=A0 =C2=A0(unsafe { trace_events_enabled_count }) !=3D 0 &&am= p; dstate !=3D 0
=C2=A0}

=C2=A0extern "C" {
+=C2=A0 =C2=A0 #[allow(dead_code)]
=C2=A0 =C2=A0 =C2=A0static mut trace_events_enabled_count: u32;
=C2=A0}
=C2=A0extern "C" {
+=C2=A0 =C2=A0 #[allow(dead_code)]
=C2=A0 =C2=A0 =C2=A0static mut _TRACE_TEST_BLAH_DSTATE: u16;
+=C2=A0 =C2=A0 #[allow(dead_code)]
=C2=A0 =C2=A0 =C2=A0static mut _TRACE_TEST_WIBBLE_DSTATE: u16;
=C2=A0}

+#[inline(always)]
+#[allow(dead_code)]
+pub fn trace_test_blah_enabled() -> bool
+{
+=C2=A0 =C2=A0 trace_event_state_is_enabled(unsafe { _TRACE_TEST_BLAH_DSTAT= E}) ||
+=C2=A0 =C2=A0 false
+}
+
=C2=A0#[inline(always)]
=C2=A0#[allow(dead_code)]
=C2=A0pub fn trace_test_blah(_context: *mut (), _filename: &std::ffi::C= Str)
@@ -29,6 +41,14 @@ pub fn trace_test_blah(_context: *mut (), _filename: &am= p;std::ffi::CStr)
=C2=A0 =C2=A0 =C2=A0}
=C2=A0}

+#[inline(always)]
+#[allow(dead_code)]
+pub fn trace_test_wibble_enabled() -> bool
+{
+=C2=A0 =C2=A0 trace_event_state_is_enabled(unsafe { _TRACE_TEST_WIBBLE_DST= ATE}) ||
+=C2=A0 =C2=A0 false
+}
+
=C2=A0#[inline(always)]
=C2=A0#[allow(dead_code)]
=C2=A0pub fn trace_test_wibble(_context: *mut (), _value: std::ffi::c_int)<= br> @@ -38,3 +58,4 @@ pub fn trace_test_wibble(_context: *mut (), _value: std::= ffi::c_int)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0unsafe {bindings::ftrace_write(format_str= ing.as_ptr() as *const c_char, _context /* as *mut () */, _value /* as std:= :ffi::c_int */);}
=C2=A0 =C2=A0 =C2=A0}
=C2=A0}
+
diff --git a/tests/tracetool/log.rs b/tests/tracetool/log.rs
index c191895c8f..770758611d 100644
--- a/tests/tracetool/log.rs
+++ b/tests/tracetool/log.rs
@@ -6,19 +6,31 @@
=C2=A0#[allow(unused_imports)]
=C2=A0use util::bindings;

+#[allow(dead_code)]
=C2=A0#[inline(always)]
=C2=A0fn trace_event_state_is_enabled(dstate: u16) -> bool {
=C2=A0 =C2=A0 =C2=A0(unsafe { trace_events_enabled_count }) !=3D 0 &&am= p; dstate !=3D 0
=C2=A0}

=C2=A0extern "C" {
+=C2=A0 =C2=A0 #[allow(dead_code)]
=C2=A0 =C2=A0 =C2=A0static mut trace_events_enabled_count: u32;
=C2=A0}
=C2=A0extern "C" {
+=C2=A0 =C2=A0 #[allow(dead_code)]
=C2=A0 =C2=A0 =C2=A0static mut _TRACE_TEST_BLAH_DSTATE: u16;
+=C2=A0 =C2=A0 #[allow(dead_code)]
=C2=A0 =C2=A0 =C2=A0static mut _TRACE_TEST_WIBBLE_DSTATE: u16;
=C2=A0}

+#[inline(always)]
+#[allow(dead_code)]
+pub fn trace_test_blah_enabled() -> bool
+{
+=C2=A0 =C2=A0 trace_event_state_is_enabled(unsafe { _TRACE_TEST_BLAH_DSTAT= E}) ||
+=C2=A0 =C2=A0 false
+}
+
=C2=A0#[inline(always)]
=C2=A0#[allow(dead_code)]
=C2=A0pub fn trace_test_blah(_context: *mut (), _filename: &std::ffi::C= Str)
@@ -31,6 +43,14 @@ pub fn trace_test_blah(_context: *mut (), _filename: &am= p;std::ffi::CStr)
=C2=A0 =C2=A0 =C2=A0}
=C2=A0}

+#[inline(always)]
+#[allow(dead_code)]
+pub fn trace_test_wibble_enabled() -> bool
+{
+=C2=A0 =C2=A0 trace_event_state_is_enabled(unsafe { _TRACE_TEST_WIBBLE_DST= ATE}) ||
+=C2=A0 =C2=A0 false
+}
+
=C2=A0#[inline(always)]
=C2=A0#[allow(dead_code)]
=C2=A0pub fn trace_test_wibble(_context: *mut (), _value: std::ffi::c_int)<= br> @@ -42,3 +62,4 @@ pub fn trace_test_wibble(_context: *mut (), _value: std::= ffi::c_int)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}
=C2=A0 =C2=A0 =C2=A0}
=C2=A0}
+
diff --git a/tests/tracetool/simple.rs b/tests/tracetool/simple.rs<= /a>
index 9ee39495e3..92f896ef17 100644
--- a/tests/tracetool/
simple.rs
+++ b/tests/tracetool/simple.rs
@@ -6,19 +6,31 @@
=C2=A0#[allow(unused_imports)]
=C2=A0use util::bindings;

+#[allow(dead_code)]
=C2=A0#[inline(always)]
=C2=A0fn trace_event_state_is_enabled(dstate: u16) -> bool {
=C2=A0 =C2=A0 =C2=A0(unsafe { trace_events_enabled_count }) !=3D 0 &&am= p; dstate !=3D 0
=C2=A0}

=C2=A0extern "C" {
+=C2=A0 =C2=A0 #[allow(dead_code)]
=C2=A0 =C2=A0 =C2=A0static mut trace_events_enabled_count: u32;
=C2=A0}
=C2=A0extern "C" {
+=C2=A0 =C2=A0 #[allow(dead_code)]
=C2=A0 =C2=A0 =C2=A0static mut _TRACE_TEST_BLAH_DSTATE: u16;
+=C2=A0 =C2=A0 #[allow(dead_code)]
=C2=A0 =C2=A0 =C2=A0static mut _TRACE_TEST_WIBBLE_DSTATE: u16;
=C2=A0}

+#[inline(always)]
+#[allow(dead_code)]
+pub fn trace_test_blah_enabled() -> bool
+{
+=C2=A0 =C2=A0 trace_event_state_is_enabled(unsafe { _TRACE_TEST_BLAH_DSTAT= E}) ||
+=C2=A0 =C2=A0 false
+}
+
=C2=A0#[inline(always)]
=C2=A0#[allow(dead_code)]
=C2=A0pub fn trace_test_blah(_context: *mut (), _filename: &std::ffi::C= Str)
@@ -29,6 +41,14 @@ pub fn trace_test_blah(_context: *mut (), _filename: &am= p;std::ffi::CStr)
=C2=A0 =C2=A0 =C2=A0}
=C2=A0}

+#[inline(always)]
+#[allow(dead_code)]
+pub fn trace_test_wibble_enabled() -> bool
+{
+=C2=A0 =C2=A0 trace_event_state_is_enabled(unsafe { _TRACE_TEST_WIBBLE_DST= ATE}) ||
+=C2=A0 =C2=A0 false
+}
+
=C2=A0#[inline(always)]
=C2=A0#[allow(dead_code)]
=C2=A0pub fn trace_test_wibble(_context: *mut (), _value: std::ffi::c_int)<= br> @@ -38,3 +58,4 @@ pub fn trace_test_wibble(_context: *mut (), _value: std::= ffi::c_int)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0unsafe { _simple_trace_test_wibble(_conte= xt, _value); }
=C2=A0 =C2=A0 =C2=A0}
=C2=A0}
+
diff --git a/tests/tracetool/syslog.rs b/tests/tracetool/syslog.rs<= /a>
index 9d3675a0b5..378d03d34b 100644
--- a/tests/tracetool/
syslog.rs
+++ b/tests/tracetool/syslog.rs
@@ -6,19 +6,31 @@
=C2=A0#[allow(unused_imports)]
=C2=A0use util::bindings;

+#[allow(dead_code)]
=C2=A0#[inline(always)]
=C2=A0fn trace_event_state_is_enabled(dstate: u16) -> bool {
=C2=A0 =C2=A0 =C2=A0(unsafe { trace_events_enabled_count }) !=3D 0 &&am= p; dstate !=3D 0
=C2=A0}

=C2=A0extern "C" {
+=C2=A0 =C2=A0 #[allow(dead_code)]
=C2=A0 =C2=A0 =C2=A0static mut trace_events_enabled_count: u32;
=C2=A0}
=C2=A0extern "C" {
+=C2=A0 =C2=A0 #[allow(dead_code)]
=C2=A0 =C2=A0 =C2=A0static mut _TRACE_TEST_BLAH_DSTATE: u16;
+=C2=A0 =C2=A0 #[allow(dead_code)]
=C2=A0 =C2=A0 =C2=A0static mut _TRACE_TEST_WIBBLE_DSTATE: u16;
=C2=A0}

+#[inline(always)]
+#[allow(dead_code)]
+pub fn trace_test_blah_enabled() -> bool
+{
+=C2=A0 =C2=A0 trace_event_state_is_enabled(unsafe { _TRACE_TEST_BLAH_DSTAT= E}) ||
+=C2=A0 =C2=A0 false
+}
+
=C2=A0#[inline(always)]
=C2=A0#[allow(dead_code)]
=C2=A0pub fn trace_test_blah(_context: *mut (), _filename: &std::ffi::C= Str)
@@ -29,6 +41,14 @@ pub fn trace_test_blah(_context: *mut (), _filename: &am= p;std::ffi::CStr)
=C2=A0 =C2=A0 =C2=A0}
=C2=A0}

+#[inline(always)]
+#[allow(dead_code)]
+pub fn trace_test_wibble_enabled() -> bool
+{
+=C2=A0 =C2=A0 trace_event_state_is_enabled(unsafe { _TRACE_TEST_WIBBLE_DST= ATE}) ||
+=C2=A0 =C2=A0 false
+}
+
=C2=A0#[inline(always)]
=C2=A0#[allow(dead_code)]
=C2=A0pub fn trace_test_wibble(_context: *mut (), _value: std::ffi::c_int)<= br> @@ -38,3 +58,4 @@ pub fn trace_test_wibble(_context: *mut (), _value: std::= ffi::c_int)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0unsafe {::trace::syslog(::trace::LOG_INFO= , format_string.as_ptr() as *const c_char, _context /* as *mut () */, _valu= e /* as std::ffi::c_int */);}
=C2=A0 =C2=A0 =C2=A0}
=C2=A0}
+
diff --git a/tests/tracetool/tracetool-test.py b/tests/tracetool/tracetool-= test.py
index 786083ad7f..30006a9919 100755
--- a/tests/tracetool/tracetool-test.py
+++ b/tests/tracetool/tracetool-test.py
@@ -14,7 +14,7 @@ def get_formats(backend):
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"c",
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"h",
=C2=A0 =C2=A0 =C2=A0]
-=C2=A0 =C2=A0 if backend in {"ftrace", "log", "si= mple", "syslog"}:
+=C2=A0 =C2=A0 if backend in {"dtrace", "ftrace", "= ;log", "simple", "syslog"}:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0formats +=3D ["rs"]
=C2=A0 =C2=A0 =C2=A0if backend =3D=3D "dtrace":
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0formats +=3D [
--
2.51.1

--0000000000002992c50643f7b450--