Project

General

Profile

Actions

Bug #1435

open
AS

Problematic tracepoint provider header files in LTTng-UST test suite

Bug #1435: Problematic tracepoint provider header files in LTTng-UST test suite

Added by Anton Smyk 5 months ago. Updated 5 months ago.

Status:
New
Priority:
Normal
Assignee:
-
Target version:
-
Start date:
02/10/2026
Due date:
% Done:

0%

Estimated time:

Description

Dear LTTng developers,

We are long time happy users of LTTng-UST technology. Thank you for developing and maintaining it.

TLDR: We have stumbled upon build problem involving modern Clang versions and tracepoint provider header files in the LTTng-UST test suite, which I believe is coding error in those files. The fix appears to be easy: just remove some offending include directives from affected files.

Recently we have upgraded our toolchain to LLVM 20 + libstdc++ from GCC 15. We are also evaluating upgrade of our LTTng dependencies to latest versions. By default we provide -std=gnu++23 to CXXFLAGS building all components. Rebuilding LTTng-UST v2.13.9 and also from stable-2.15 branch, I've stumbled on compilation error in one of the tests. Here is a Dockerfile for convenience so you can reproduce it yourselves:

FROM quay.io/centos/centos:stream9

RUN dnf -y group install "Development Tools" && \
    dnf -y install llvm clang lld

ARG WORKDIR=/work
ARG DISTDIR=/work/dist

ARG URCU_BRANCH=stable-0.15
ARG LTTNG_UST_BRANCH=stable-2.15

RUN mkdir $WORKDIR && cd $WORKDIR && \
    git clone -b $URCU_BRANCH https://github.com/urcu/userspace-rcu.git && \
    git clone -b $LTTNG_UST_BRANCH https://github.com/lttng/lttng-ust.git

WORKDIR $WORKDIR

ARG CC=clang CXX=clang++
ARG CXX_STANDARD=20
ENV CC=$CC CXX=$CXX
ENV CXXFLAGS="-std=gnu++${CXX_STANDARD}" 

ENV PKG_CONFIG_PATH=$DISTDIR/lib/pkgconfig

RUN <<EOF
#!/bin/sh
set -e
set -x
cd $WORKDIR/userspace-rcu
autoreconf -vi
./configure --prefix=$DISTDIR --disable-static
make -j8 V=1
make check
make install
EOF

# Save script for manual invocations with different parameters
COPY --chmod=0755 <<EOF $WORKDIR/build-lttng-ust.sh
#!/bin/sh
set -e
set -x
cd $WORKDIR/lttng-ust
autoreconf -vi
./configure --prefix=$DISTDIR --disable-static \
    --disable-man-pages --without-sdt --disable-numa --disable-examples
make -j8 V=1
make check
EOF

RUN /work/build-lttng-ust.sh

When executed with Podman build command, it would fail like this:

podman build .
...
In file included from tp-cpp.cpp:8:
In file included from ./ust_tests_hello.h:62:
In file included from ../../../../include/lttng/tracepoint-event.h:67:
In file included from ../../../../include/lttng/ust-tracepoint-event.h:1189:
In file included from ./ust_tests_hello.h:14:
In file included from /usr/bin/../lib/clang/21/include/stddef.h:88:
/usr/bin/../lib/clang/21/include/__stddef_ptrdiff_t.h:18:1: error: expected expression
18 | typedef __PTRDIFF_TYPE__ ptrdiff_t;
    | ^
In file included from tp-cpp.cpp:8:
In file included from ./ust_tests_hello.h:62:
In file included from ../../../../include/lttng/tracepoint-event.h:67:
../../../../include/lttng/ust-tracepoint-event.h:1204:15: error: invalid application of 'sizeof' to an incomplete type 'const struct lttng_ust_event_desc *const[]'
1204 |         .nr_events = LTTNG_UST__TP_ARRAY_SIZE(LTTNG_UST__TP_COMBINE_TOKENS(lttng_ust__provider_event_desc___, LTTNG_UST_TRACEPOINT_PROVIDER)) - 1,
    |                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../../../include/lttng/ust-tracepoint-event.h:97:46: note: expanded from macro 'LTTNG_UST__TP_ARRAY_SIZE'
97 | #define LTTNG_UST__TP_ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
    |                                              ^~~~~

This is due to include directive inside array initializer list in https://github.com/lttng/lttng-ust/blob/v2.13.9/include/lttng/ust-tracepoint-event.h#L1181

I was able to minimize repro case to this:

$ cat minrepro.cpp
#include <stddef.h>

[[maybe_unused]] static const int arr[] = {
    #include <stddef.h>
    0,
};

[[maybe_unused]] static const int len = (sizeof(arr) / sizeof((arr)[0]));

It happens to work with GCC, and it worked with older Clang versions thanks to #pragma once or equivalent guard:

$ clang++ -std=c++17 -Wall -Wextra -pedantic -c minrepro.cpp  && echo OK
OK
$ g++ -std=c++23 -Wall -Wextra -pedantic -c minrepro.cpp  && echo OK
OK

But it fails to be compiled with modern Clang in modern C++ mode:

$ clang++ -std=c++20 -Wall -Wextra -pedantic -c minrepro.cpp  && echo OK
In file included from minrepro.cpp:4:
In file included from /usr/bin/../lib/clang/21/include/stddef.h:88:
/usr/bin/../lib/clang/21/include/__stddef_ptrdiff_t.h:18:1: error: expected expression
   18 | typedef __PTRDIFF_TYPE__ ptrdiff_t;
      | ^
minrepro.cpp:8:48: error: invalid application of 'sizeof' to an incomplete type 'const int[]'
    8 | [[maybe_unused]] static const int len = (sizeof(arr) / sizeof((arr)[0]));
      |                                                ^~~~~
2 errors generated.

This is because modern Clang implements magic of Clang Modules:

The repro can be further minimized to more clearly demonstrate that specific Clang trouble:

$ cat minrepro2.cpp
[[maybe_unused]] static const int arr[] = {
    typedef int foo;
    0,
};

Of course, for building LTTng-UST we can use older C++ standard like -std=c++17, or let LTTng configure default to c++11.

Cleaner solution would be avoid including anything in tracepoint provider header files:

$ git diff -- tests/compile/api0/hello.cxx/
diff --git a/tests/compile/api0/hello.cxx/ust_tests_hello.h b/tests/compile/api0/hello.cxx/ust_tests_hello.h
index 1963e737..a968cd8f 100644
--- a/tests/compile/api0/hello.cxx/ust_tests_hello.h
+++ b/tests/compile/api0/hello.cxx/ust_tests_hello.h
@@ -11,7 +11,6 @@
 #define _TRACEPOINT_UST_TESTS_HELLO_H

 #include <lttng/tracepoint.h>
-#include <stddef.h>

 TRACEPOINT_ENUM(ust_tests_hello, my_enum,
        TP_ENUM_VALUES(

I was able to build stable-2.15 by patching tracepoint provider header files in tests to remove all includes like stddef.h stdbool.h and the like -- basically all except strictly necessary lttng ones:

$ git status --short
 M tests/compile/api0/hello-many/ust_tests_hello_many.h
 M tests/compile/api0/hello.cxx/ust_tests_hello.h
 M tests/compile/api0/hello/ust_tests_hello.h
 M tests/compile/api1/hello-many/ust_tests_hello_many.h
 M tests/compile/api1/hello.cxx/ust_tests_hello.h
 M tests/compile/api1/hello/ust_tests_hello.h
 M tests/compile/api1/test-app-ctx/ust_tests_hello.h
 M tests/regression/abi0-conflict/ust_tests_hello.h
$

Thankfully, example in the official documentation is clean in this regard: https://lttng.org/docs/v2.15/#doc-tracing-your-own-user-application

Actions

Also available in: PDF Atom