When using GCC on x86-64 to compile an usdt prog with -O1 or higher
optimization, the compiler will generate SIB addressing mode for global
array and PC-relative addressing mode for global variable,
e.g. "1@-96(%rbp,%rax,8)" and "-1@4+t1(%rip)".
In this patch:
- add usdt_o2 test case to cover SIB addressing usdt argument spec
handling logic
Signed-off-by: Jiawei Zhao <phoenix500526@163.com>
---
tools/testing/selftests/bpf/Makefile | 8 +++
.../selftests/bpf/prog_tests/usdt_o2.c | 71 +++++++++++++++++++
.../selftests/bpf/progs/test_usdt_o2.c | 37 ++++++++++
3 files changed, 116 insertions(+)
create mode 100644 tools/testing/selftests/bpf/prog_tests/usdt_o2.c
create mode 100644 tools/testing/selftests/bpf/progs/test_usdt_o2.c
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index 910d8d6402ef..68cf6a9cf05f 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -759,6 +759,14 @@ TRUNNER_BPF_BUILD_RULE := $$(error no BPF objects should be built)
TRUNNER_BPF_CFLAGS :=
$(eval $(call DEFINE_TEST_RUNNER,test_maps))
+# Use -O2 optimization to generate SIB addressing usdt argument spec
+# Only apply on x86 architecture where SIB addressing is relevant
+ifeq ($(ARCH), x86)
+$(OUTPUT)/usdt_o2.test.o: CFLAGS:=$(subst O0,O2,$(CFLAGS))
+$(OUTPUT)/cpuv4/usdt_o2.test.o: CFLAGS:=$(subst O0,O2,$(CFLAGS))
+$(OUTPUT)/no_alu32/usdt_o2.test.o: CFLAGS:=$(subst O0,O2,$(CFLAGS))
+endif
+
# Define test_verifier test runner.
# It is much simpler than test_maps/test_progs and sufficiently different from
# them (e.g., test.h is using completely pattern), that it's worth just
diff --git a/tools/testing/selftests/bpf/prog_tests/usdt_o2.c b/tools/testing/selftests/bpf/prog_tests/usdt_o2.c
new file mode 100644
index 000000000000..f04b756b3640
--- /dev/null
+++ b/tools/testing/selftests/bpf/prog_tests/usdt_o2.c
@@ -0,0 +1,71 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2025 Jiawei Zhao <phoenix500526@163.com>. */
+#include <test_progs.h>
+
+#define _SDT_HAS_SEMAPHORES 1
+#include "../sdt.h"
+#include "test_usdt_o2.skel.h"
+
+int lets_test_this(int);
+
+#define test_value 0xFEDCBA9876543210ULL
+#define SEC(name) __attribute__((section(name), used))
+
+
+static volatile __u64 array[1] = {test_value};
+unsigned short test_usdt1_semaphore SEC(".probes");
+
+static __always_inline void trigger_func(void)
+{
+ /* Base address + offset + (index * scale) */
+ if (test_usdt1_semaphore) {
+ for (volatile int i = 0; i <= 0; i++)
+ STAP_PROBE1(test, usdt1, array[i]);
+ }
+}
+
+static void basic_sib_usdt(void)
+{
+ LIBBPF_OPTS(bpf_usdt_opts, opts);
+ struct test_usdt_o2 *skel;
+ struct test_usdt_o2__bss *bss;
+ int err;
+
+ skel = test_usdt_o2__open_and_load();
+ if (!ASSERT_OK_PTR(skel, "skel_open"))
+ return;
+
+ bss = skel->bss;
+ bss->my_pid = getpid();
+
+ err = test_usdt_o2__attach(skel);
+ if (!ASSERT_OK(err, "skel_attach"))
+ goto cleanup;
+
+ /* usdt1 won't be auto-attached */
+ opts.usdt_cookie = 0xcafedeadbeeffeed;
+ skel->links.usdt1 = bpf_program__attach_usdt(skel->progs.usdt1,
+ 0 /*self*/, "/proc/self/exe",
+ "test", "usdt1", &opts);
+ if (!ASSERT_OK_PTR(skel->links.usdt1, "usdt1_link"))
+ goto cleanup;
+
+ trigger_func();
+
+ ASSERT_EQ(bss->usdt1_called, 1, "usdt1_called");
+ ASSERT_EQ(bss->usdt1_cookie, 0xcafedeadbeeffeed, "usdt1_cookie");
+ ASSERT_EQ(bss->usdt1_arg_cnt, 1, "usdt1_arg_cnt");
+ ASSERT_EQ(bss->usdt1_arg, test_value, "usdt1_arg");
+ ASSERT_EQ(bss->usdt1_arg_ret, 0, "usdt1_arg_ret");
+ ASSERT_EQ(bss->usdt1_arg_size, sizeof(array[0]), "usdt1_arg_size");
+
+cleanup:
+ test_usdt_o2__destroy(skel);
+}
+
+
+
+void test_usdt_o2(void)
+{
+ basic_sib_usdt();
+}
diff --git a/tools/testing/selftests/bpf/progs/test_usdt_o2.c b/tools/testing/selftests/bpf/progs/test_usdt_o2.c
new file mode 100644
index 000000000000..14602aa54578
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/test_usdt_o2.c
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2022 Meta Platforms, Inc. and affiliates. */
+
+#include "vmlinux.h"
+#include <bpf/bpf_helpers.h>
+#include <bpf/usdt.bpf.h>
+
+int my_pid;
+
+int usdt1_called;
+u64 usdt1_cookie;
+int usdt1_arg_cnt;
+int usdt1_arg_ret;
+u64 usdt1_arg;
+int usdt1_arg_size;
+
+SEC("usdt")
+int usdt1(struct pt_regs *ctx)
+{
+ long tmp;
+
+ if (my_pid != (bpf_get_current_pid_tgid() >> 32))
+ return 0;
+
+ __sync_fetch_and_add(&usdt1_called, 1);
+
+ usdt1_cookie = bpf_usdt_cookie(ctx);
+ usdt1_arg_cnt = bpf_usdt_arg_cnt(ctx);
+
+ usdt1_arg_ret = bpf_usdt_arg(ctx, 0, &tmp);
+ usdt1_arg = (u64)tmp;
+ usdt1_arg_size = bpf_usdt_arg_size(ctx, 0);
+
+ return 0;
+}
+
+char _license[] SEC("license") = "GPL";
--
2.43.0
On 8/6/25 2:24 AM, Jiawei Zhao wrote:
> When using GCC on x86-64 to compile an usdt prog with -O1 or higher
> optimization, the compiler will generate SIB addressing mode for global
> array and PC-relative addressing mode for global variable,
> e.g. "1@-96(%rbp,%rax,8)" and "-1@4+t1(%rip)".
>
> In this patch:
> - add usdt_o2 test case to cover SIB addressing usdt argument spec
> handling logic
>
> Signed-off-by: Jiawei Zhao <phoenix500526@163.com>
> ---
> tools/testing/selftests/bpf/Makefile | 8 +++
> .../selftests/bpf/prog_tests/usdt_o2.c | 71 +++++++++++++++++++
> .../selftests/bpf/progs/test_usdt_o2.c | 37 ++++++++++
> 3 files changed, 116 insertions(+)
> create mode 100644 tools/testing/selftests/bpf/prog_tests/usdt_o2.c
> create mode 100644 tools/testing/selftests/bpf/progs/test_usdt_o2.c
>
> diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
> index 910d8d6402ef..68cf6a9cf05f 100644
> --- a/tools/testing/selftests/bpf/Makefile
> +++ b/tools/testing/selftests/bpf/Makefile
> @@ -759,6 +759,14 @@ TRUNNER_BPF_BUILD_RULE := $$(error no BPF objects should be built)
> TRUNNER_BPF_CFLAGS :=
> $(eval $(call DEFINE_TEST_RUNNER,test_maps))
>
> +# Use -O2 optimization to generate SIB addressing usdt argument spec
> +# Only apply on x86 architecture where SIB addressing is relevant
> +ifeq ($(ARCH), x86)
> +$(OUTPUT)/usdt_o2.test.o: CFLAGS:=$(subst O0,O2,$(CFLAGS))
> +$(OUTPUT)/cpuv4/usdt_o2.test.o: CFLAGS:=$(subst O0,O2,$(CFLAGS))
> +$(OUTPUT)/no_alu32/usdt_o2.test.o: CFLAGS:=$(subst O0,O2,$(CFLAGS))
> +endif
I tried your selftest with gcc14 and llvm20 in my environment. See below:
llvm20:
Displaying notes found in: .note.stapsdt
Owner Data size Description
stapsdt 0x0000002f NT_STAPSDT (SystemTap probe descriptors)
Provider: test
Name: usdt1
Location: 0x00000000000003ac, Base: 0x0000000000000000, Semaphore: 0x0000000000000000
Arguments: 8@-64(%rbp)
gcc14:
Displaying notes found in: .note.stapsdt
Owner Data size Description
stapsdt 0x00000034 NT_STAPSDT (SystemTap probe descriptors)
Provider: test
Name: usdt1
Location: 0x0000000000000334, Base: 0x0000000000000000, Semaphore: 0x0000000000000000
Arguments: 8@array(,%rax,8)
llvm20 and gcc14 generate different usdt patterns. '8@-64(%rbp)' already supports so
with SIB support, the test should pass CI, I think.
> +
> # Define test_verifier test runner.
> # It is much simpler than test_maps/test_progs and sufficiently different from
> # them (e.g., test.h is using completely pattern), that it's worth just
> diff --git a/tools/testing/selftests/bpf/prog_tests/usdt_o2.c b/tools/testing/selftests/bpf/prog_tests/usdt_o2.c
> new file mode 100644
> index 000000000000..f04b756b3640
> --- /dev/null
> +++ b/tools/testing/selftests/bpf/prog_tests/usdt_o2.c
> @@ -0,0 +1,71 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/* Copyright (c) 2025 Jiawei Zhao <phoenix500526@163.com>. */
> +#include <test_progs.h>
> +
> +#define _SDT_HAS_SEMAPHORES 1
> +#include "../sdt.h"
> +#include "test_usdt_o2.skel.h"
> +
> +int lets_test_this(int);
> +
> +#define test_value 0xFEDCBA9876543210ULL
> +#define SEC(name) __attribute__((section(name), used))
> +
> +
> +static volatile __u64 array[1] = {test_value};
> +unsigned short test_usdt1_semaphore SEC(".probes");
> +
> +static __always_inline void trigger_func(void)
> +{
> + /* Base address + offset + (index * scale) */
> + if (test_usdt1_semaphore) {
> + for (volatile int i = 0; i <= 0; i++)
> + STAP_PROBE1(test, usdt1, array[i]);
> + }
> +}
> +
> +static void basic_sib_usdt(void)
> +{
> + LIBBPF_OPTS(bpf_usdt_opts, opts);
> + struct test_usdt_o2 *skel;
> + struct test_usdt_o2__bss *bss;
> + int err;
> +
> + skel = test_usdt_o2__open_and_load();
> + if (!ASSERT_OK_PTR(skel, "skel_open"))
> + return;
> +
> + bss = skel->bss;
> + bss->my_pid = getpid();
> +
> + err = test_usdt_o2__attach(skel);
> + if (!ASSERT_OK(err, "skel_attach"))
> + goto cleanup;
> +
> + /* usdt1 won't be auto-attached */
> + opts.usdt_cookie = 0xcafedeadbeeffeed;
> + skel->links.usdt1 = bpf_program__attach_usdt(skel->progs.usdt1,
> + 0 /*self*/, "/proc/self/exe",
> + "test", "usdt1", &opts);
> + if (!ASSERT_OK_PTR(skel->links.usdt1, "usdt1_link"))
> + goto cleanup;
> +
> + trigger_func();
> +
> + ASSERT_EQ(bss->usdt1_called, 1, "usdt1_called");
> + ASSERT_EQ(bss->usdt1_cookie, 0xcafedeadbeeffeed, "usdt1_cookie");
> + ASSERT_EQ(bss->usdt1_arg_cnt, 1, "usdt1_arg_cnt");
> + ASSERT_EQ(bss->usdt1_arg, test_value, "usdt1_arg");
> + ASSERT_EQ(bss->usdt1_arg_ret, 0, "usdt1_arg_ret");
> + ASSERT_EQ(bss->usdt1_arg_size, sizeof(array[0]), "usdt1_arg_size");
> +
> +cleanup:
> + test_usdt_o2__destroy(skel);
> +}
> +
> +
> +
> +void test_usdt_o2(void)
> +{
> + basic_sib_usdt();
> +}
> diff --git a/tools/testing/selftests/bpf/progs/test_usdt_o2.c b/tools/testing/selftests/bpf/progs/test_usdt_o2.c
> new file mode 100644
> index 000000000000..14602aa54578
> --- /dev/null
> +++ b/tools/testing/selftests/bpf/progs/test_usdt_o2.c
> @@ -0,0 +1,37 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/* Copyright (c) 2022 Meta Platforms, Inc. and affiliates. */
> +
> +#include "vmlinux.h"
> +#include <bpf/bpf_helpers.h>
> +#include <bpf/usdt.bpf.h>
> +
> +int my_pid;
> +
> +int usdt1_called;
> +u64 usdt1_cookie;
> +int usdt1_arg_cnt;
> +int usdt1_arg_ret;
> +u64 usdt1_arg;
> +int usdt1_arg_size;
> +
> +SEC("usdt")
> +int usdt1(struct pt_regs *ctx)
> +{
> + long tmp;
> +
> + if (my_pid != (bpf_get_current_pid_tgid() >> 32))
> + return 0;
> +
> + __sync_fetch_and_add(&usdt1_called, 1);
> +
> + usdt1_cookie = bpf_usdt_cookie(ctx);
> + usdt1_arg_cnt = bpf_usdt_arg_cnt(ctx);
> +
> + usdt1_arg_ret = bpf_usdt_arg(ctx, 0, &tmp);
> + usdt1_arg = (u64)tmp;
> + usdt1_arg_size = bpf_usdt_arg_size(ctx, 0);
> +
> + return 0;
> +}
> +
> +char _license[] SEC("license") = "GPL";
On Wed, Aug 06, 2025 at 11:17:34AM -0700, Yonghong Song wrote:
SNIP
> > diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
> > index 910d8d6402ef..68cf6a9cf05f 100644
> > --- a/tools/testing/selftests/bpf/Makefile
> > +++ b/tools/testing/selftests/bpf/Makefile
> > @@ -759,6 +759,14 @@ TRUNNER_BPF_BUILD_RULE := $$(error no BPF objects should be built)
> > TRUNNER_BPF_CFLAGS :=
> > $(eval $(call DEFINE_TEST_RUNNER,test_maps))
> > +# Use -O2 optimization to generate SIB addressing usdt argument spec
> > +# Only apply on x86 architecture where SIB addressing is relevant
> > +ifeq ($(ARCH), x86)
> > +$(OUTPUT)/usdt_o2.test.o: CFLAGS:=$(subst O0,O2,$(CFLAGS))
> > +$(OUTPUT)/cpuv4/usdt_o2.test.o: CFLAGS:=$(subst O0,O2,$(CFLAGS))
> > +$(OUTPUT)/no_alu32/usdt_o2.test.o: CFLAGS:=$(subst O0,O2,$(CFLAGS))
> > +endif
>
> I tried your selftest with gcc14 and llvm20 in my environment. See below:
>
> llvm20:
> Displaying notes found in: .note.stapsdt
> Owner Data size Description
> stapsdt 0x0000002f NT_STAPSDT (SystemTap probe descriptors)
> Provider: test
> Name: usdt1
> Location: 0x00000000000003ac, Base: 0x0000000000000000, Semaphore: 0x0000000000000000
> Arguments: 8@-64(%rbp)
>
> gcc14:
> Displaying notes found in: .note.stapsdt
> Owner Data size Description
> stapsdt 0x00000034 NT_STAPSDT (SystemTap probe descriptors)
> Provider: test
> Name: usdt1
> Location: 0x0000000000000334, Base: 0x0000000000000000, Semaphore: 0x0000000000000000
> Arguments: 8@array(,%rax,8)
>
> llvm20 and gcc14 generate different usdt patterns. '8@-64(%rbp)' already supports so
> with SIB support, the test should pass CI, I think.
I see the same with gcc 15 and clang 20
Arguments: 8@array(,%rax,8)
jirka
Hi Yonghong,
I noticed that the USDT argument specification generated by GCC 14 is '8@array(,%rax,8)'.
This pattern is currently not handled correctly. I'm exploring whether I can use DWARF information
to calculate the address of this variable. This approach seems to work. However, since I can't
reproduce the same issue on my machine, I plan to implement this approach for the PC-relative
issue in a separate patch. Would that affect the merging of this patch?
At 2025-08-07 02:17:34, "Yonghong Song" <yonghong.song@linux.dev> wrote:
>
>
>On 8/6/25 2:24 AM, Jiawei Zhao wrote:
>> When using GCC on x86-64 to compile an usdt prog with -O1 or higher
>> optimization, the compiler will generate SIB addressing mode for global
>> array and PC-relative addressing mode for global variable,
>> e.g. "1@-96(%rbp,%rax,8)" and "-1@4+t1(%rip)".
>>
>> In this patch:
>> - add usdt_o2 test case to cover SIB addressing usdt argument spec
>> handling logic
>>
>> Signed-off-by: Jiawei Zhao <phoenix500526@163.com>
>> ---
>> tools/testing/selftests/bpf/Makefile | 8 +++
>> .../selftests/bpf/prog_tests/usdt_o2.c | 71 +++++++++++++++++++
>> .../selftests/bpf/progs/test_usdt_o2.c | 37 ++++++++++
>> 3 files changed, 116 insertions(+)
>> create mode 100644 tools/testing/selftests/bpf/prog_tests/usdt_o2.c
>> create mode 100644 tools/testing/selftests/bpf/progs/test_usdt_o2.c
>>
>> diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
>> index 910d8d6402ef..68cf6a9cf05f 100644
>> --- a/tools/testing/selftests/bpf/Makefile
>> +++ b/tools/testing/selftests/bpf/Makefile
>> @@ -759,6 +759,14 @@ TRUNNER_BPF_BUILD_RULE := $$(error no BPF objects should be built)
>> TRUNNER_BPF_CFLAGS :=
>> $(eval $(call DEFINE_TEST_RUNNER,test_maps))
>>
>> +# Use -O2 optimization to generate SIB addressing usdt argument spec
>> +# Only apply on x86 architecture where SIB addressing is relevant
>> +ifeq ($(ARCH), x86)
>> +$(OUTPUT)/usdt_o2.test.o: CFLAGS:=$(subst O0,O2,$(CFLAGS))
>> +$(OUTPUT)/cpuv4/usdt_o2.test.o: CFLAGS:=$(subst O0,O2,$(CFLAGS))
>> +$(OUTPUT)/no_alu32/usdt_o2.test.o: CFLAGS:=$(subst O0,O2,$(CFLAGS))
>> +endif
>
>I tried your selftest with gcc14 and llvm20 in my environment. See below:
>
>llvm20:
>Displaying notes found in: .note.stapsdt
> Owner Data size Description
> stapsdt 0x0000002f NT_STAPSDT (SystemTap probe descriptors)
> Provider: test
> Name: usdt1
> Location: 0x00000000000003ac, Base: 0x0000000000000000, Semaphore: 0x0000000000000000
> Arguments: 8@-64(%rbp)
>
>gcc14:
>Displaying notes found in: .note.stapsdt
> Owner Data size Description
> stapsdt 0x00000034 NT_STAPSDT (SystemTap probe descriptors)
> Provider: test
> Name: usdt1
> Location: 0x0000000000000334, Base: 0x0000000000000000, Semaphore: 0x0000000000000000
> Arguments: 8@array(,%rax,8)
>
>llvm20 and gcc14 generate different usdt patterns. '8@-64(%rbp)' already supports so
>with SIB support, the test should pass CI, I think.
>
>> +
>> # Define test_verifier test runner.
>> # It is much simpler than test_maps/test_progs and sufficiently different from
>> # them (e.g., test.h is using completely pattern), that it's worth just
>> diff --git a/tools/testing/selftests/bpf/prog_tests/usdt_o2.c b/tools/testing/selftests/bpf/prog_tests/usdt_o2.c
>> new file mode 100644
>> index 000000000000..f04b756b3640
>> --- /dev/null
>> +++ b/tools/testing/selftests/bpf/prog_tests/usdt_o2.c
>> @@ -0,0 +1,71 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/* Copyright (c) 2025 Jiawei Zhao <phoenix500526@163.com>. */
>> +#include <test_progs.h>
>> +
>> +#define _SDT_HAS_SEMAPHORES 1
>> +#include "../sdt.h"
>> +#include "test_usdt_o2.skel.h"
>> +
>> +int lets_test_this(int);
>> +
>> +#define test_value 0xFEDCBA9876543210ULL
>> +#define SEC(name) __attribute__((section(name), used))
>> +
>> +
>> +static volatile __u64 array[1] = {test_value};
>> +unsigned short test_usdt1_semaphore SEC(".probes");
>> +
>> +static __always_inline void trigger_func(void)
>> +{
>> + /* Base address + offset + (index * scale) */
>> + if (test_usdt1_semaphore) {
>> + for (volatile int i = 0; i <= 0; i++)
>> + STAP_PROBE1(test, usdt1, array[i]);
>> + }
>> +}
>> +
>> +static void basic_sib_usdt(void)
>> +{
>> + LIBBPF_OPTS(bpf_usdt_opts, opts);
>> + struct test_usdt_o2 *skel;
>> + struct test_usdt_o2__bss *bss;
>> + int err;
>> +
>> + skel = test_usdt_o2__open_and_load();
>> + if (!ASSERT_OK_PTR(skel, "skel_open"))
>> + return;
>> +
>> + bss = skel->bss;
>> + bss->my_pid = getpid();
>> +
>> + err = test_usdt_o2__attach(skel);
>> + if (!ASSERT_OK(err, "skel_attach"))
>> + goto cleanup;
>> +
>> + /* usdt1 won't be auto-attached */
>> + opts.usdt_cookie = 0xcafedeadbeeffeed;
>> + skel->links.usdt1 = bpf_program__attach_usdt(skel->progs.usdt1,
>> + 0 /*self*/, "/proc/self/exe",
>> + "test", "usdt1", &opts);
>> + if (!ASSERT_OK_PTR(skel->links.usdt1, "usdt1_link"))
>> + goto cleanup;
>> +
>> + trigger_func();
>> +
>> + ASSERT_EQ(bss->usdt1_called, 1, "usdt1_called");
>> + ASSERT_EQ(bss->usdt1_cookie, 0xcafedeadbeeffeed, "usdt1_cookie");
>> + ASSERT_EQ(bss->usdt1_arg_cnt, 1, "usdt1_arg_cnt");
>> + ASSERT_EQ(bss->usdt1_arg, test_value, "usdt1_arg");
>> + ASSERT_EQ(bss->usdt1_arg_ret, 0, "usdt1_arg_ret");
>> + ASSERT_EQ(bss->usdt1_arg_size, sizeof(array[0]), "usdt1_arg_size");
>> +
>> +cleanup:
>> + test_usdt_o2__destroy(skel);
>> +}
>> +
>> +
>> +
>> +void test_usdt_o2(void)
>> +{
>> + basic_sib_usdt();
>> +}
>> diff --git a/tools/testing/selftests/bpf/progs/test_usdt_o2.c b/tools/testing/selftests/bpf/progs/test_usdt_o2.c
>> new file mode 100644
>> index 000000000000..14602aa54578
>> --- /dev/null
>> +++ b/tools/testing/selftests/bpf/progs/test_usdt_o2.c
>> @@ -0,0 +1,37 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/* Copyright (c) 2022 Meta Platforms, Inc. and affiliates. */
>> +
>> +#include "vmlinux.h"
>> +#include <bpf/bpf_helpers.h>
>> +#include <bpf/usdt.bpf.h>
>> +
>> +int my_pid;
>> +
>> +int usdt1_called;
>> +u64 usdt1_cookie;
>> +int usdt1_arg_cnt;
>> +int usdt1_arg_ret;
>> +u64 usdt1_arg;
>> +int usdt1_arg_size;
>> +
>> +SEC("usdt")
>> +int usdt1(struct pt_regs *ctx)
>> +{
>> + long tmp;
>> +
>> + if (my_pid != (bpf_get_current_pid_tgid() >> 32))
>> + return 0;
>> +
>> + __sync_fetch_and_add(&usdt1_called, 1);
>> +
>> + usdt1_cookie = bpf_usdt_cookie(ctx);
>> + usdt1_arg_cnt = bpf_usdt_arg_cnt(ctx);
>> +
>> + usdt1_arg_ret = bpf_usdt_arg(ctx, 0, &tmp);
>> + usdt1_arg = (u64)tmp;
>> + usdt1_arg_size = bpf_usdt_arg_size(ctx, 0);
>> +
>> + return 0;
>> +}
>> +
>> +char _license[] SEC("license") = "GPL";
On 8/6/25 7:57 PM, 赵佳炜 wrote: > > > > Hi Yonghong, > > I noticed that the USDT argument specification generated by GCC 14 is '8@array(,%rax,8)'. > This pattern is currently not handled correctly. I'm exploring whether I can use DWARF information > to calculate the address of this variable. This approach seems to work. However, since I can't I think 'array' should be in symbol table, so there is no need to check dwarf in my opinion. > reproduce the same issue on my machine, I plan to implement this approach for the PC-relative > issue in a separate patch. Would that affect the merging of this patch? Let us handle this since '8@array(,%rax,8)' may appear in CI environment. > > > At 2025-08-07 02:17:34, "Yonghong Song" <yonghong.song@linux.dev> wrote: >> >> On 8/6/25 2:24 AM, Jiawei Zhao wrote: >>> When using GCC on x86-64 to compile an usdt prog with -O1 or higher >>> optimization, the compiler will generate SIB addressing mode for global >>> array and PC-relative addressing mode for global variable, >>> e.g. "1@-96(%rbp,%rax,8)" and "-1@4+t1(%rip)". >>> >>> In this patch: >>> - add usdt_o2 test case to cover SIB addressing usdt argument spec >>> handling logic >>> >>> Signed-off-by: Jiawei Zhao <phoenix500526@163.com> >>> --- >>> tools/testing/selftests/bpf/Makefile | 8 +++ >>> .../selftests/bpf/prog_tests/usdt_o2.c | 71 +++++++++++++++++++ >>> .../selftests/bpf/progs/test_usdt_o2.c | 37 ++++++++++ >>> 3 files changed, 116 insertions(+) >>> create mode 100644 tools/testing/selftests/bpf/prog_tests/usdt_o2.c >>> create mode 100644 tools/testing/selftests/bpf/progs/test_usdt_o2.c >>> >>> diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile >>> index 910d8d6402ef..68cf6a9cf05f 100644 >>> --- a/tools/testing/selftests/bpf/Makefile >>> +++ b/tools/testing/selftests/bpf/Makefile >>> @@ -759,6 +759,14 @@ TRUNNER_BPF_BUILD_RULE := $$(error no BPF objects should be built) >>> TRUNNER_BPF_CFLAGS := >>> $(eval $(call DEFINE_TEST_RUNNER,test_maps)) >>> >>> +# Use -O2 optimization to generate SIB addressing usdt argument spec >>> +# Only apply on x86 architecture where SIB addressing is relevant >>> +ifeq ($(ARCH), x86) >>> +$(OUTPUT)/usdt_o2.test.o: CFLAGS:=$(subst O0,O2,$(CFLAGS)) >>> +$(OUTPUT)/cpuv4/usdt_o2.test.o: CFLAGS:=$(subst O0,O2,$(CFLAGS)) >>> +$(OUTPUT)/no_alu32/usdt_o2.test.o: CFLAGS:=$(subst O0,O2,$(CFLAGS)) >>> +endif >> I tried your selftest with gcc14 and llvm20 in my environment. See below: >> >> llvm20: >> Displaying notes found in: .note.stapsdt >> Owner Data size Description >> stapsdt 0x0000002f NT_STAPSDT (SystemTap probe descriptors) >> Provider: test >> Name: usdt1 >> Location: 0x00000000000003ac, Base: 0x0000000000000000, Semaphore: 0x0000000000000000 >> Arguments: 8@-64(%rbp) >> >> gcc14: >> Displaying notes found in: .note.stapsdt >> Owner Data size Description >> stapsdt 0x00000034 NT_STAPSDT (SystemTap probe descriptors) >> Provider: test >> Name: usdt1 >> Location: 0x0000000000000334, Base: 0x0000000000000000, Semaphore: 0x0000000000000000 >> Arguments: 8@array(,%rax,8) >> >> llvm20 and gcc14 generate different usdt patterns. '8@-64(%rbp)' already supports so >> with SIB support, the test should pass CI, I think. >> [...]
Hi Yonghong,
I found another issue where symbols can be duplicated, and I’m not sure how to tell them apart.
For example, I created two C files named usdt_rip.c and hello.c. Both define their own static ti variables, like:`static volatile char ti = 0;`.
After compiling, I obtained an ELF file usdt_rip whose .symtab contains the following entries:
$ readelf -s usdt_rip
Symbol table '.symtab' contains 42 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS Scrt1.o
2: 000000000000038c 32 OBJECT LOCAL DEFAULT 4 __abi_tag
3: 0000000000000000 0 FILE LOCAL DEFAULT ABS usdt_rip.c
4: 0000000000004021 1 OBJECT LOCAL DEFAULT 25 ti
5: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
6: 00000000000010a0 0 FUNC LOCAL DEFAULT 14 deregister_tm_clones
7: 00000000000010d0 0 FUNC LOCAL DEFAULT 14 register_tm_clones
8: 0000000000001110 0 FUNC LOCAL DEFAULT 14 __do_global_dtors_aux
9: 0000000000004020 1 OBJECT LOCAL DEFAULT 25 completed.0
10: 0000000000003df8 0 OBJECT LOCAL DEFAULT 21 __do_global_dtor[...]
11: 0000000000001150 0 FUNC LOCAL DEFAULT 14 frame_dummy
12: 0000000000003df0 0 OBJECT LOCAL DEFAULT 20 __frame_dummy_in[...]
13: 0000000000000000 0 FILE LOCAL DEFAULT ABS damo.c
14: 0000000000004022 1 OBJECT LOCAL DEFAULT 25 ti
15: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
16: 00000000000020d8 0 OBJECT LOCAL DEFAULT 19 __FRAME_END__
As you can see, there are two ti variables in the .symtab section. Their values are very close, making them hard to distinguish.
I’m unsure how to handle this situation. Do you have any suggestions?
Thanks,
Jiawei Zhao
At 2025-08-08 02:01:08, "Yonghong Song" <yonghong.song@linux.dev> wrote:
>
>
>On 8/6/25 7:57 PM, 赵佳炜 wrote:
>>
>>
>>
>> Hi Yonghong,
>>
>> I noticed that the USDT argument specification generated by GCC 14 is '8@array(,%rax,8)'.
>> This pattern is currently not handled correctly. I'm exploring whether I can use DWARF information
>> to calculate the address of this variable. This approach seems to work. However, since I can't
>
>I think 'array' should be in symbol table, so there is no need to check dwarf in my opinion.
>
>> reproduce the same issue on my machine, I plan to implement this approach for the PC-relative
>> issue in a separate patch. Would that affect the merging of this patch?
>
>Let us handle this since '8@array(,%rax,8)' may appear in CI environment.
>
>>
>>
>> At 2025-08-07 02:17:34, "Yonghong Song" <yonghong.song@linux.dev> wrote:
>>>
>>> On 8/6/25 2:24 AM, Jiawei Zhao wrote:
>>>> When using GCC on x86-64 to compile an usdt prog with -O1 or higher
>>>> optimization, the compiler will generate SIB addressing mode for global
>>>> array and PC-relative addressing mode for global variable,
>>>> e.g. "1@-96(%rbp,%rax,8)" and "-1@4+t1(%rip)".
>>>>
>>>> In this patch:
>>>> - add usdt_o2 test case to cover SIB addressing usdt argument spec
>>>> handling logic
>>>>
>>>> Signed-off-by: Jiawei Zhao <phoenix500526@163.com>
>>>> ---
>>>> tools/testing/selftests/bpf/Makefile | 8 +++
>>>> .../selftests/bpf/prog_tests/usdt_o2.c | 71 +++++++++++++++++++
>>>> .../selftests/bpf/progs/test_usdt_o2.c | 37 ++++++++++
>>>> 3 files changed, 116 insertions(+)
>>>> create mode 100644 tools/testing/selftests/bpf/prog_tests/usdt_o2.c
>>>> create mode 100644 tools/testing/selftests/bpf/progs/test_usdt_o2.c
>>>>
>>>> diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
>>>> index 910d8d6402ef..68cf6a9cf05f 100644
>>>> --- a/tools/testing/selftests/bpf/Makefile
>>>> +++ b/tools/testing/selftests/bpf/Makefile
>>>> @@ -759,6 +759,14 @@ TRUNNER_BPF_BUILD_RULE := $$(error no BPF objects should be built)
>>>> TRUNNER_BPF_CFLAGS :=
>>>> $(eval $(call DEFINE_TEST_RUNNER,test_maps))
>>>>
>>>> +# Use -O2 optimization to generate SIB addressing usdt argument spec
>>>> +# Only apply on x86 architecture where SIB addressing is relevant
>>>> +ifeq ($(ARCH), x86)
>>>> +$(OUTPUT)/usdt_o2.test.o: CFLAGS:=$(subst O0,O2,$(CFLAGS))
>>>> +$(OUTPUT)/cpuv4/usdt_o2.test.o: CFLAGS:=$(subst O0,O2,$(CFLAGS))
>>>> +$(OUTPUT)/no_alu32/usdt_o2.test.o: CFLAGS:=$(subst O0,O2,$(CFLAGS))
>>>> +endif
>>> I tried your selftest with gcc14 and llvm20 in my environment. See below:
>>>
>>> llvm20:
>>> Displaying notes found in: .note.stapsdt
>>> Owner Data size Description
>>> stapsdt 0x0000002f NT_STAPSDT (SystemTap probe descriptors)
>>> Provider: test
>>> Name: usdt1
>>> Location: 0x00000000000003ac, Base: 0x0000000000000000, Semaphore: 0x0000000000000000
>>> Arguments: 8@-64(%rbp)
>>>
>>> gcc14:
>>> Displaying notes found in: .note.stapsdt
>>> Owner Data size Description
>>> stapsdt 0x00000034 NT_STAPSDT (SystemTap probe descriptors)
>>> Provider: test
>>> Name: usdt1
>>> Location: 0x0000000000000334, Base: 0x0000000000000000, Semaphore: 0x0000000000000000
>>> Arguments: 8@array(,%rax,8)
>>>
>>> llvm20 and gcc14 generate different usdt patterns. '8@-64(%rbp)' already supports so
>>> with SIB support, the test should pass CI, I think.
>>>
>[...]
On 8/10/25 1:55 AM, 赵佳炜 wrote: > > > Hi Yonghong, > > I found another issue where symbols can be duplicated, and I’m not sure how to tell them apart. > > For example, I created two C files named usdt_rip.c and hello.c. Both define their own static ti variables, like:`static volatile char ti = 0;`. > > After compiling, I obtained an ELF file usdt_rip whose .symtab contains the following entries: > > $ readelf -s usdt_rip > > Symbol table '.symtab' contains 42 entries: > Num: Value Size Type Bind Vis Ndx Name > 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND > 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS Scrt1.o > 2: 000000000000038c 32 OBJECT LOCAL DEFAULT 4 __abi_tag > 3: 0000000000000000 0 FILE LOCAL DEFAULT ABS usdt_rip.c > 4: 0000000000004021 1 OBJECT LOCAL DEFAULT 25 ti > 5: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c > 6: 00000000000010a0 0 FUNC LOCAL DEFAULT 14 deregister_tm_clones > 7: 00000000000010d0 0 FUNC LOCAL DEFAULT 14 register_tm_clones > 8: 0000000000001110 0 FUNC LOCAL DEFAULT 14 __do_global_dtors_aux > 9: 0000000000004020 1 OBJECT LOCAL DEFAULT 25 completed.0 > 10: 0000000000003df8 0 OBJECT LOCAL DEFAULT 21 __do_global_dtor[...] > 11: 0000000000001150 0 FUNC LOCAL DEFAULT 14 frame_dummy > 12: 0000000000003df0 0 OBJECT LOCAL DEFAULT 20 __frame_dummy_in[...] > 13: 0000000000000000 0 FILE LOCAL DEFAULT ABS damo.c > 14: 0000000000004022 1 OBJECT LOCAL DEFAULT 25 ti > 15: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c > 16: 00000000000020d8 0 OBJECT LOCAL DEFAULT 19 __FRAME_END__ > > > As you can see, there are two ti variables in the .symtab section. Their values are very close, making them hard to distinguish. > > I’m unsure how to handle this situation. Do you have any suggestions? Did you check relocations? Relocaitons should be able to point exact which symbol. > > Thanks, > Jiawei Zhao [...]
Yes, I've tried that but it didn't help. FYI: $ readelf -nsr usdt_rip Relocation section '.rela.dyn' at offset 0x530 contains 9 entries: Offset Info Type Sym. Value Sym. Name + Addend 000000003df0 000000000008 R_X86_64_RELATIVE 1150 000000003df8 000000000008 R_X86_64_RELATIVE 1110 000000004008 000000000008 R_X86_64_RELATIVE 4008 000000004018 000000000008 R_X86_64_RELATIVE 1160 000000003fd8 000100000006 R_X86_64_GLOB_DAT 0000000000000000 __libc_start_main@GLIBC_2.34 + 0 000000003fe0 000200000006 R_X86_64_GLOB_DAT 0000000000000000 _ITM_deregisterTM[...] + 0 000000003fe8 000300000006 R_X86_64_GLOB_DAT 0000000000000000 __gmon_start__ + 0 000000003ff0 000400000006 R_X86_64_GLOB_DAT 0000000000000000 _ITM_registerTMCl[...] + 0 000000003ff8 000500000006 R_X86_64_GLOB_DAT 0000000000000000 __cxa_finalize@GLIBC_2.2.5 + 0 Symbol table '.dynsym' contains 6 entries: Num: Value Size Type Bind Vis Ndx Name 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND 1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _[...]@GLIBC_2.34 (2) 2: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterT[...] 3: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__ 4: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMC[...] 5: 0000000000000000 0 FUNC WEAK DEFAULT UND [...]@GLIBC_2.2.5 (3) Symbol table '.symtab' contains 42 entries: Num: Value Size Type Bind Vis Ndx Name 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS Scrt1.o 2: 000000000000038c 32 OBJECT LOCAL DEFAULT 4 __abi_tag 3: 0000000000000000 0 FILE LOCAL DEFAULT ABS usdt_rip.c 4: 0000000000004021 1 OBJECT LOCAL DEFAULT 25 ti 5: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c 6: 00000000000010a0 0 FUNC LOCAL DEFAULT 14 deregister_tm_clones 7: 00000000000010d0 0 FUNC LOCAL DEFAULT 14 register_tm_clones 8: 0000000000001110 0 FUNC LOCAL DEFAULT 14 __do_global_dtors_aux 9: 0000000000004020 1 OBJECT LOCAL DEFAULT 25 completed.0 10: 0000000000003df8 0 OBJECT LOCAL DEFAULT 21 __do_global_dtor[...] 11: 0000000000001150 0 FUNC LOCAL DEFAULT 14 frame_dummy 12: 0000000000003df0 0 OBJECT LOCAL DEFAULT 20 __frame_dummy_in[...] 13: 0000000000000000 0 FILE LOCAL DEFAULT ABS damo.c 14: 0000000000004022 1 OBJECT LOCAL DEFAULT 25 ti 15: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c 16: 00000000000020d8 0 OBJECT LOCAL DEFAULT 19 __FRAME_END__ 17: 0000000000000000 0 FILE LOCAL DEFAULT ABS 18: 0000000000003e00 0 OBJECT LOCAL DEFAULT 22 _DYNAMIC 19: 0000000000002008 0 NOTYPE LOCAL DEFAULT 18 __GNU_EH_FRAME_HDR 20: 0000000000003fc0 0 OBJECT LOCAL DEFAULT 23 _GLOBAL_OFFSET_TABLE_ 21: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_mai[...] 22: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterT[...] 23: 0000000000004000 0 NOTYPE WEAK DEFAULT 24 data_start 24: 0000000000001160 8 FUNC GLOBAL DEFAULT 14 add 25: 0000000000004020 0 NOTYPE GLOBAL DEFAULT 24 _edata 26: 0000000000002004 1 NOTYPE WEAK HIDDEN 17 _.stapsdt.base 27: 0000000000004010 8 OBJECT GLOBAL DEFAULT 24 t1 28: 0000000000001168 0 FUNC GLOBAL HIDDEN 15 _fini 29: 0000000000004000 0 NOTYPE GLOBAL DEFAULT 24 __data_start 30: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__ 31: 0000000000004008 0 OBJECT GLOBAL HIDDEN 24 __dso_handle 32: 0000000000002000 4 OBJECT GLOBAL DEFAULT 16 _IO_stdin_used 33: 0000000000004028 0 NOTYPE GLOBAL DEFAULT 25 _end 34: 0000000000001070 38 FUNC GLOBAL DEFAULT 14 _start 35: 0000000000004020 0 NOTYPE GLOBAL DEFAULT 25 __bss_start 36: 0000000000001040 48 FUNC GLOBAL DEFAULT 14 main 37: 0000000000004018 8 OBJECT GLOBAL DEFAULT 24 add_ptr 38: 0000000000004020 0 OBJECT GLOBAL HIDDEN 24 __TMC_END__ 39: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMC[...] 40: 0000000000000000 0 FUNC WEAK DEFAULT UND __cxa_finalize@G[...] 41: 0000000000001000 0 FUNC GLOBAL HIDDEN 11 _init Displaying notes found in: .note.gnu.property Owner Data size Description GNU 0x00000020 NT_GNU_PROPERTY_TYPE_0 Properties: x86 feature: IBT, SHSTK x86 ISA needed: x86-64-baseline Displaying notes found in: .note.gnu.build-id Owner Data size Description GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring) Build ID: eb615daa575687cc44edc1d339b27890c12c27f1 Displaying notes found in: .note.ABI-tag Owner Data size Description GNU 0x00000010 NT_GNU_ABI_TAG (ABI version tag) OS: Linux, ABI: 3.2.0 Displaying notes found in: .note.stapsdt Owner Data size Description stapsdt 0x00000066 NT_STAPSDT (SystemTap probe descriptors) Provider: usdt_rip Name: rip_global_var Location: 0x0000000000001058, Base: 0x0000000000002004, Semaphore: 0x0000000000000000 Arguments: -1@ti(%rip) 8@add_ptr(%rip) -1@4+t1(%rip) -1@ti(%rip) At 2025-08-12 13:06:40, "Yonghong Song" <yonghong.song@linux.dev> wrote: > > >On 8/10/25 1:55 AM, 赵佳炜 wrote: >> >> >> Hi Yonghong, >> >> I found another issue where symbols can be duplicated, and I’m not sure how to tell them apart. >> >> For example, I created two C files named usdt_rip.c and hello.c. Both define their own static ti variables, like:`static volatile char ti = 0;`. >> >> After compiling, I obtained an ELF file usdt_rip whose .symtab contains the following entries: >> >> $ readelf -s usdt_rip >> >> Symbol table '.symtab' contains 42 entries: >> Num: Value Size Type Bind Vis Ndx Name >> 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND >> 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS Scrt1.o >> 2: 000000000000038c 32 OBJECT LOCAL DEFAULT 4 __abi_tag >> 3: 0000000000000000 0 FILE LOCAL DEFAULT ABS usdt_rip.c >> 4: 0000000000004021 1 OBJECT LOCAL DEFAULT 25 ti >> 5: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c >> 6: 00000000000010a0 0 FUNC LOCAL DEFAULT 14 deregister_tm_clones >> 7: 00000000000010d0 0 FUNC LOCAL DEFAULT 14 register_tm_clones >> 8: 0000000000001110 0 FUNC LOCAL DEFAULT 14 __do_global_dtors_aux >> 9: 0000000000004020 1 OBJECT LOCAL DEFAULT 25 completed.0 >> 10: 0000000000003df8 0 OBJECT LOCAL DEFAULT 21 __do_global_dtor[...] >> 11: 0000000000001150 0 FUNC LOCAL DEFAULT 14 frame_dummy >> 12: 0000000000003df0 0 OBJECT LOCAL DEFAULT 20 __frame_dummy_in[...] >> 13: 0000000000000000 0 FILE LOCAL DEFAULT ABS damo.c >> 14: 0000000000004022 1 OBJECT LOCAL DEFAULT 25 ti >> 15: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c >> 16: 00000000000020d8 0 OBJECT LOCAL DEFAULT 19 __FRAME_END__ >> >> >> As you can see, there are two ti variables in the .symtab section. Their values are very close, making them hard to distinguish. >> >> I’m unsure how to handle this situation. Do you have any suggestions? > >Did you check relocations? Relocaitons should be able to point exact which symbol. > >> >> Thanks, >> Jiawei Zhao >[...]
On 8/12/25 12:02 AM, 赵佳炜 wrote: > Yes, I've tried that but it didn't help. FYI: > > $ readelf -nsr usdt_rip > > > Relocation section '.rela.dyn' at offset 0x530 contains 9 entries: > Offset Info Type Sym. Value Sym. Name + Addend > 000000003df0 000000000008 R_X86_64_RELATIVE 1150 > 000000003df8 000000000008 R_X86_64_RELATIVE 1110 > 000000004008 000000000008 R_X86_64_RELATIVE 4008 > 000000004018 000000000008 R_X86_64_RELATIVE 1160 > 000000003fd8 000100000006 R_X86_64_GLOB_DAT 0000000000000000 __libc_start_main@GLIBC_2.34 + 0 > 000000003fe0 000200000006 R_X86_64_GLOB_DAT 0000000000000000 _ITM_deregisterTM[...] + 0 > 000000003fe8 000300000006 R_X86_64_GLOB_DAT 0000000000000000 __gmon_start__ + 0 > 000000003ff0 000400000006 R_X86_64_GLOB_DAT 0000000000000000 _ITM_registerTMCl[...] + 0 > 000000003ff8 000500000006 R_X86_64_GLOB_DAT 0000000000000000 __cxa_finalize@GLIBC_2.2.5 + 0 > > > Symbol table '.dynsym' contains 6 entries: > Num: Value Size Type Bind Vis Ndx Name > 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND > 1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _[...]@GLIBC_2.34 (2) > 2: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterT[...] > 3: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__ > 4: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMC[...] > 5: 0000000000000000 0 FUNC WEAK DEFAULT UND [...]@GLIBC_2.2.5 (3) > > > Symbol table '.symtab' contains 42 entries: > Num: Value Size Type Bind Vis Ndx Name > 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND > 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS Scrt1.o > 2: 000000000000038c 32 OBJECT LOCAL DEFAULT 4 __abi_tag > 3: 0000000000000000 0 FILE LOCAL DEFAULT ABS usdt_rip.c > 4: 0000000000004021 1 OBJECT LOCAL DEFAULT 25 ti > 5: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c > 6: 00000000000010a0 0 FUNC LOCAL DEFAULT 14 deregister_tm_clones > 7: 00000000000010d0 0 FUNC LOCAL DEFAULT 14 register_tm_clones > 8: 0000000000001110 0 FUNC LOCAL DEFAULT 14 __do_global_dtors_aux > 9: 0000000000004020 1 OBJECT LOCAL DEFAULT 25 completed.0 > 10: 0000000000003df8 0 OBJECT LOCAL DEFAULT 21 __do_global_dtor[...] > 11: 0000000000001150 0 FUNC LOCAL DEFAULT 14 frame_dummy > 12: 0000000000003df0 0 OBJECT LOCAL DEFAULT 20 __frame_dummy_in[...] > 13: 0000000000000000 0 FILE LOCAL DEFAULT ABS damo.c > 14: 0000000000004022 1 OBJECT LOCAL DEFAULT 25 ti > 15: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c > 16: 00000000000020d8 0 OBJECT LOCAL DEFAULT 19 __FRAME_END__ > 17: 0000000000000000 0 FILE LOCAL DEFAULT ABS > 18: 0000000000003e00 0 OBJECT LOCAL DEFAULT 22 _DYNAMIC > 19: 0000000000002008 0 NOTYPE LOCAL DEFAULT 18 __GNU_EH_FRAME_HDR > 20: 0000000000003fc0 0 OBJECT LOCAL DEFAULT 23 _GLOBAL_OFFSET_TABLE_ > 21: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_mai[...] > 22: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterT[...] > 23: 0000000000004000 0 NOTYPE WEAK DEFAULT 24 data_start > 24: 0000000000001160 8 FUNC GLOBAL DEFAULT 14 add > 25: 0000000000004020 0 NOTYPE GLOBAL DEFAULT 24 _edata > 26: 0000000000002004 1 NOTYPE WEAK HIDDEN 17 _.stapsdt.base > 27: 0000000000004010 8 OBJECT GLOBAL DEFAULT 24 t1 > 28: 0000000000001168 0 FUNC GLOBAL HIDDEN 15 _fini > 29: 0000000000004000 0 NOTYPE GLOBAL DEFAULT 24 __data_start > 30: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__ > 31: 0000000000004008 0 OBJECT GLOBAL HIDDEN 24 __dso_handle > 32: 0000000000002000 4 OBJECT GLOBAL DEFAULT 16 _IO_stdin_used > 33: 0000000000004028 0 NOTYPE GLOBAL DEFAULT 25 _end > 34: 0000000000001070 38 FUNC GLOBAL DEFAULT 14 _start > 35: 0000000000004020 0 NOTYPE GLOBAL DEFAULT 25 __bss_start > 36: 0000000000001040 48 FUNC GLOBAL DEFAULT 14 main > 37: 0000000000004018 8 OBJECT GLOBAL DEFAULT 24 add_ptr > 38: 0000000000004020 0 OBJECT GLOBAL HIDDEN 24 __TMC_END__ > 39: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMC[...] > 40: 0000000000000000 0 FUNC WEAK DEFAULT UND __cxa_finalize@G[...] > 41: 0000000000001000 0 FUNC GLOBAL HIDDEN 11 _init > > > Displaying notes found in: .note.gnu.property > Owner Data size Description > GNU 0x00000020 NT_GNU_PROPERTY_TYPE_0 > Properties: x86 feature: IBT, SHSTK > x86 ISA needed: x86-64-baseline > > > Displaying notes found in: .note.gnu.build-id > Owner Data size Description > GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring) > Build ID: eb615daa575687cc44edc1d339b27890c12c27f1 > > > Displaying notes found in: .note.ABI-tag > Owner Data size Description > GNU 0x00000010 NT_GNU_ABI_TAG (ABI version tag) > OS: Linux, ABI: 3.2.0 > > > Displaying notes found in: .note.stapsdt > Owner Data size Description > stapsdt 0x00000066 NT_STAPSDT (SystemTap probe descriptors) > Provider: usdt_rip > Name: rip_global_var > Location: 0x0000000000001058, Base: 0x0000000000002004, Semaphore: 0x0000000000000000 > Arguments: -1@ti(%rip) 8@add_ptr(%rip) -1@4+t1(%rip) -1@ti(%rip) Could you share the complete source codes and compiler options which reproduce the above result? > > > > At 2025-08-12 13:06:40, "Yonghong Song" <yonghong.song@linux.dev> wrote: >> >> On 8/10/25 1:55 AM, 赵佳炜 wrote: >>> >>> Hi Yonghong, >>> >>> I found another issue where symbols can be duplicated, and I’m not sure how to tell them apart. >>> >>> For example, I created two C files named usdt_rip.c and hello.c. Both define their own static ti variables, like:`static volatile char ti = 0;`. >>> >>> After compiling, I obtained an ELF file usdt_rip whose .symtab contains the following entries: >>> >>> $ readelf -s usdt_rip >>> >>> Symbol table '.symtab' contains 42 entries: >>> Num: Value Size Type Bind Vis Ndx Name >>> 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND >>> 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS Scrt1.o >>> 2: 000000000000038c 32 OBJECT LOCAL DEFAULT 4 __abi_tag >>> 3: 0000000000000000 0 FILE LOCAL DEFAULT ABS usdt_rip.c >>> 4: 0000000000004021 1 OBJECT LOCAL DEFAULT 25 ti >>> 5: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c >>> 6: 00000000000010a0 0 FUNC LOCAL DEFAULT 14 deregister_tm_clones >>> 7: 00000000000010d0 0 FUNC LOCAL DEFAULT 14 register_tm_clones >>> 8: 0000000000001110 0 FUNC LOCAL DEFAULT 14 __do_global_dtors_aux >>> 9: 0000000000004020 1 OBJECT LOCAL DEFAULT 25 completed.0 >>> 10: 0000000000003df8 0 OBJECT LOCAL DEFAULT 21 __do_global_dtor[...] >>> 11: 0000000000001150 0 FUNC LOCAL DEFAULT 14 frame_dummy >>> 12: 0000000000003df0 0 OBJECT LOCAL DEFAULT 20 __frame_dummy_in[...] >>> 13: 0000000000000000 0 FILE LOCAL DEFAULT ABS damo.c >>> 14: 0000000000004022 1 OBJECT LOCAL DEFAULT 25 ti >>> 15: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c >>> 16: 00000000000020d8 0 OBJECT LOCAL DEFAULT 19 __FRAME_END__ >>> >>> >>> As you can see, there are two ti variables in the .symtab section. Their values are very close, making them hard to distinguish. >>> >>> I’m unsure how to handle this situation. Do you have any suggestions? >> Did you check relocations? Relocaitons should be able to point exact which symbol. >> >>> Thanks, >>> Jiawei Zhao >> [...]
Sure.
The usdt_rip.c source code:
```C
// the usdt_rip.c file
#include <stddef.h>
#include <stdint.h>
#include "sdt.h"
static volatile char ti = 0;
int add(int a, int b) {
return a + b;
}
int (*add_ptr)(int, int) = add;
struct st{
int a;
char b;
};
volatile struct st t1 = {.a = 1, .b = 'a'};
static void __always_inline trigger_func() {
STAP_PROBE4(usdt_rip, rip_global_var, ti, add_ptr, t1.b, ti);
}
int main() {
trigger_func();
return 0;
}
```
The test/usdt_rip.c source code:
```C
// The test/usdt_rip.c file
static volatile char ti = 0;
```
The compiler option is `gcc -O2 -g usdt_rip.c test/usdt_rip.c -o usdt_rip`
My compiler version:
```bash
$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-linux-gnu/13/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 13.3.0-6ubuntu2~24.04' --with-bugurl=file:///usr/share/doc/gcc-13/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-13 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/libexec --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-libstdcxx-backtrace --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-13-fG75Ri/gcc-13-13.3.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-13-fG75Ri/gcc-13-13.3.0/debian/tmp-gcn/usr --enable-offload-defaulted --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=2
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 13.3.0 (Ubuntu 13.3.0-6ubuntu2~24.04)
```
At 2025-08-13 00:11:45, "Yonghong Song" <yonghong.song@linux.dev> wrote:
>
>
>On 8/12/25 12:02 AM, 赵佳炜 wrote:
>> Yes, I've tried that but it didn't help. FYI:
>>
>> $ readelf -nsr usdt_rip
>>
>>
>> Relocation section '.rela.dyn' at offset 0x530 contains 9 entries:
>> Offset Info Type Sym. Value Sym. Name + Addend
>> 000000003df0 000000000008 R_X86_64_RELATIVE 1150
>> 000000003df8 000000000008 R_X86_64_RELATIVE 1110
>> 000000004008 000000000008 R_X86_64_RELATIVE 4008
>> 000000004018 000000000008 R_X86_64_RELATIVE 1160
>> 000000003fd8 000100000006 R_X86_64_GLOB_DAT 0000000000000000 __libc_start_main@GLIBC_2.34 + 0
>> 000000003fe0 000200000006 R_X86_64_GLOB_DAT 0000000000000000 _ITM_deregisterTM[...] + 0
>> 000000003fe8 000300000006 R_X86_64_GLOB_DAT 0000000000000000 __gmon_start__ + 0
>> 000000003ff0 000400000006 R_X86_64_GLOB_DAT 0000000000000000 _ITM_registerTMCl[...] + 0
>> 000000003ff8 000500000006 R_X86_64_GLOB_DAT 0000000000000000 __cxa_finalize@GLIBC_2.2.5 + 0
>>
>>
>> Symbol table '.dynsym' contains 6 entries:
>> Num: Value Size Type Bind Vis Ndx Name
>> 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
>> 1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _[...]@GLIBC_2.34 (2)
>> 2: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterT[...]
>> 3: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
>> 4: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMC[...]
>> 5: 0000000000000000 0 FUNC WEAK DEFAULT UND [...]@GLIBC_2.2.5 (3)
>>
>>
>> Symbol table '.symtab' contains 42 entries:
>> Num: Value Size Type Bind Vis Ndx Name
>> 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
>> 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS Scrt1.o
>> 2: 000000000000038c 32 OBJECT LOCAL DEFAULT 4 __abi_tag
>> 3: 0000000000000000 0 FILE LOCAL DEFAULT ABS usdt_rip.c
>> 4: 0000000000004021 1 OBJECT LOCAL DEFAULT 25 ti
>> 5: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
>> 6: 00000000000010a0 0 FUNC LOCAL DEFAULT 14 deregister_tm_clones
>> 7: 00000000000010d0 0 FUNC LOCAL DEFAULT 14 register_tm_clones
>> 8: 0000000000001110 0 FUNC LOCAL DEFAULT 14 __do_global_dtors_aux
>> 9: 0000000000004020 1 OBJECT LOCAL DEFAULT 25 completed.0
>> 10: 0000000000003df8 0 OBJECT LOCAL DEFAULT 21 __do_global_dtor[...]
>> 11: 0000000000001150 0 FUNC LOCAL DEFAULT 14 frame_dummy
>> 12: 0000000000003df0 0 OBJECT LOCAL DEFAULT 20 __frame_dummy_in[...]
>> 13: 0000000000000000 0 FILE LOCAL DEFAULT ABS damo.c
>> 14: 0000000000004022 1 OBJECT LOCAL DEFAULT 25 ti
>> 15: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
>> 16: 00000000000020d8 0 OBJECT LOCAL DEFAULT 19 __FRAME_END__
>> 17: 0000000000000000 0 FILE LOCAL DEFAULT ABS
>> 18: 0000000000003e00 0 OBJECT LOCAL DEFAULT 22 _DYNAMIC
>> 19: 0000000000002008 0 NOTYPE LOCAL DEFAULT 18 __GNU_EH_FRAME_HDR
>> 20: 0000000000003fc0 0 OBJECT LOCAL DEFAULT 23 _GLOBAL_OFFSET_TABLE_
>> 21: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_mai[...]
>> 22: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterT[...]
>> 23: 0000000000004000 0 NOTYPE WEAK DEFAULT 24 data_start
>> 24: 0000000000001160 8 FUNC GLOBAL DEFAULT 14 add
>> 25: 0000000000004020 0 NOTYPE GLOBAL DEFAULT 24 _edata
>> 26: 0000000000002004 1 NOTYPE WEAK HIDDEN 17 _.stapsdt.base
>> 27: 0000000000004010 8 OBJECT GLOBAL DEFAULT 24 t1
>> 28: 0000000000001168 0 FUNC GLOBAL HIDDEN 15 _fini
>> 29: 0000000000004000 0 NOTYPE GLOBAL DEFAULT 24 __data_start
>> 30: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
>> 31: 0000000000004008 0 OBJECT GLOBAL HIDDEN 24 __dso_handle
>> 32: 0000000000002000 4 OBJECT GLOBAL DEFAULT 16 _IO_stdin_used
>> 33: 0000000000004028 0 NOTYPE GLOBAL DEFAULT 25 _end
>> 34: 0000000000001070 38 FUNC GLOBAL DEFAULT 14 _start
>> 35: 0000000000004020 0 NOTYPE GLOBAL DEFAULT 25 __bss_start
>> 36: 0000000000001040 48 FUNC GLOBAL DEFAULT 14 main
>> 37: 0000000000004018 8 OBJECT GLOBAL DEFAULT 24 add_ptr
>> 38: 0000000000004020 0 OBJECT GLOBAL HIDDEN 24 __TMC_END__
>> 39: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMC[...]
>> 40: 0000000000000000 0 FUNC WEAK DEFAULT UND __cxa_finalize@G[...]
>> 41: 0000000000001000 0 FUNC GLOBAL HIDDEN 11 _init
>>
>>
>> Displaying notes found in: .note.gnu.property
>> Owner Data size Description
>> GNU 0x00000020 NT_GNU_PROPERTY_TYPE_0
>> Properties: x86 feature: IBT, SHSTK
>> x86 ISA needed: x86-64-baseline
>>
>>
>> Displaying notes found in: .note.gnu.build-id
>> Owner Data size Description
>> GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring)
>> Build ID: eb615daa575687cc44edc1d339b27890c12c27f1
>>
>>
>> Displaying notes found in: .note.ABI-tag
>> Owner Data size Description
>> GNU 0x00000010 NT_GNU_ABI_TAG (ABI version tag)
>> OS: Linux, ABI: 3.2.0
>>
>>
>> Displaying notes found in: .note.stapsdt
>> Owner Data size Description
>> stapsdt 0x00000066 NT_STAPSDT (SystemTap probe descriptors)
>> Provider: usdt_rip
>> Name: rip_global_var
>> Location: 0x0000000000001058, Base: 0x0000000000002004, Semaphore: 0x0000000000000000
>> Arguments: -1@ti(%rip) 8@add_ptr(%rip) -1@4+t1(%rip) -1@ti(%rip)
>
>Could you share the complete source codes and compiler options which
>reproduce the above result?
>
>>
>>
>>
>> At 2025-08-12 13:06:40, "Yonghong Song" <yonghong.song@linux.dev> wrote:
>>>
>>> On 8/10/25 1:55 AM, 赵佳炜 wrote:
>>>>
>>>> Hi Yonghong,
>>>>
>>>> I found another issue where symbols can be duplicated, and I’m not sure how to tell them apart.
>>>>
>>>> For example, I created two C files named usdt_rip.c and hello.c. Both define their own static ti variables, like:`static volatile char ti = 0;`.
>>>>
>>>> After compiling, I obtained an ELF file usdt_rip whose .symtab contains the following entries:
>>>>
>>>> $ readelf -s usdt_rip
>>>>
>>>> Symbol table '.symtab' contains 42 entries:
>>>> Num: Value Size Type Bind Vis Ndx Name
>>>> 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
>>>> 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS Scrt1.o
>>>> 2: 000000000000038c 32 OBJECT LOCAL DEFAULT 4 __abi_tag
>>>> 3: 0000000000000000 0 FILE LOCAL DEFAULT ABS usdt_rip.c
>>>> 4: 0000000000004021 1 OBJECT LOCAL DEFAULT 25 ti
>>>> 5: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
>>>> 6: 00000000000010a0 0 FUNC LOCAL DEFAULT 14 deregister_tm_clones
>>>> 7: 00000000000010d0 0 FUNC LOCAL DEFAULT 14 register_tm_clones
>>>> 8: 0000000000001110 0 FUNC LOCAL DEFAULT 14 __do_global_dtors_aux
>>>> 9: 0000000000004020 1 OBJECT LOCAL DEFAULT 25 completed.0
>>>> 10: 0000000000003df8 0 OBJECT LOCAL DEFAULT 21 __do_global_dtor[...]
>>>> 11: 0000000000001150 0 FUNC LOCAL DEFAULT 14 frame_dummy
>>>> 12: 0000000000003df0 0 OBJECT LOCAL DEFAULT 20 __frame_dummy_in[...]
>>>> 13: 0000000000000000 0 FILE LOCAL DEFAULT ABS damo.c
>>>> 14: 0000000000004022 1 OBJECT LOCAL DEFAULT 25 ti
>>>> 15: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
>>>> 16: 00000000000020d8 0 OBJECT LOCAL DEFAULT 19 __FRAME_END__
>>>>
>>>>
>>>> As you can see, there are two ti variables in the .symtab section. Their values are very close, making them hard to distinguish.
>>>>
>>>> I’m unsure how to handle this situation. Do you have any suggestions?
>>> Did you check relocations? Relocaitons should be able to point exact which symbol.
>>>
>>>> Thanks,
>>>> Jiawei Zhao
>>> [...]
On 8/12/25 7:27 PM, 赵佳炜 wrote:
>
>
>
>
>
> Sure.
>
> The usdt_rip.c source code:
>
> ```C
> // the usdt_rip.c file
> #include <stddef.h>
> #include <stdint.h>
> #include "sdt.h"
>
> static volatile char ti = 0;
>
> int add(int a, int b) {
> return a + b;
> }
> int (*add_ptr)(int, int) = add;
>
> struct st{
> int a;
> char b;
> };
>
> volatile struct st t1 = {.a = 1, .b = 'a'};
>
> static void __always_inline trigger_func() {
> STAP_PROBE4(usdt_rip, rip_global_var, ti, add_ptr, t1.b, ti);
> }
>
> int main() {
> trigger_func();
> return 0;
> }
> ```
>
> The test/usdt_rip.c source code:
>
> ```C
> // The test/usdt_rip.c file
> static volatile char ti = 0;
> ```
>
> The compiler option is `gcc -O2 -g usdt_rip.c test/usdt_rip.c -o usdt_rip`
>
> My compiler version:
> ```bash
> $ gcc -v
> Using built-in specs.
> COLLECT_GCC=gcc
> COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-linux-gnu/13/lto-wrapper
> OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa
> OFFLOAD_TARGET_DEFAULT=1
> Target: x86_64-linux-gnu
> Configured with: ../src/configure -v --with-pkgversion='Ubuntu 13.3.0-6ubuntu2~24.04' --with-bugurl=file:///usr/share/doc/gcc-13/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-13 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/libexec --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-libstdcxx-backtrace --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-13-fG75Ri/gcc-13-13.3.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-13-fG75Ri/gcc-13-13.3.0/debian/tmp-gcn/usr --enable-offload-defaulted --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=2
> Thread model: posix
> Supported LTO compression algorithms: zlib zstd
> gcc version 13.3.0 (Ubuntu 13.3.0-6ubuntu2~24.04)
> ```
Thanks for the code. I compiled with gcc14 compiler and the below is the asm code for 'main' function:
0000000000401020 <main>:
401020: 90 nop
401021: 31 c0 xor %eax,%eax
401023: c3 ret
401024: 66 2e 0f 1f 84 00 00 cs nopw 0x0(%rax,%rax,1)
40102b: 00 00 00
40102e: 66 90 xchg %ax,%ax
stapsdt note:
Displaying notes found in: .note.stapsdt
Owner Data size Description
stapsdt 0x00000066 NT_STAPSDT (SystemTap probe descriptors)
Provider: usdt_rip
Name: rip_global_var
Location: 0x0000000000401020, Base: 0x0000000000402010, Semaphore: 0x0000000000000000
Arguments: -1@ti(%rip) 8@add_ptr(%rip) -1@t1+4(%rip) -1@ti(%rip)
$ readelf -s usdt_rip | grep ti
4: 0000000000404019 1 OBJECT LOCAL DEFAULT 24 ti
14: 000000000040401a 1 OBJECT LOCAL DEFAULT 24 ti
So yet, it would be hard to find which 'ti' should be used to resolve usdt arguments.
I then tried with clang21. The 'main' function:
0000000000001140 <main>:
1140: 0f b6 05 f2 2e 00 00 movzbl 0x2ef2(%rip),%eax # 4039 <ti>
1147: 48 8b 0d da 2e 00 00 mov 0x2eda(%rip),%rcx # 4028 <add_ptr>
114e: 0f b6 15 df 2e 00 00 movzbl 0x2edf(%rip),%edx # 4034 <t1+0x4>
1155: 0f b6 35 dd 2e 00 00 movzbl 0x2edd(%rip),%esi # 4039 <ti>
115c: 88 44 24 f7 mov %al,-0x9(%rsp)
1160: 48 89 4c 24 f8 mov %rcx,-0x8(%rsp)
1165: 88 54 24 f6 mov %dl,-0xa(%rsp)
1169: 40 88 74 24 f5 mov %sil,-0xb(%rsp)
116e: 90 nop
116f: 31 c0 xor %eax,%eax
1171: c3 ret
1172: 66 90 xchg %ax,%ax
For this case, usdt should work properly. The following is related symbol table:
74: 0000000000004028 8 OBJECT GLOBAL DEFAULT 26 add_ptr
64: 0000000000004030 8 OBJECT GLOBAL DEFAULT 26 t1
50: 0000000000004039 1 OBJECT LOCAL DEFAULT 27 ti <=== for '# 4039 <ti>'.
And for llvm21, only one 'ti' in the symbol table.
$ readelf -s usdt_rip | grep ti
50: 0000000000004039 1 OBJECT LOCAL DEFAULT 27 ti
The stapsdt note:
Displaying notes found in: .note.stapsdt
Owner Data size Description
stapsdt 0x00000061 NT_STAPSDT (SystemTap probe descriptors)
Provider: usdt_rip
Name: rip_global_var
Location: 0x000000000000116e, Base: 0x0000000000002004, Semaphore: 0x0000000000000000
Arguments: -1@-9(%rsp) 8@-8(%rsp) -1@-10(%rsp) -1@-11(%rsp)
It looks like clang optimized away the following:
// The test/usdt_rip.c file
static volatile char ti = 0;
but gcc does not. But even if the above 'ti' is preserved for clang,
clang generated code should still be fine since the argument
is -1@-9(%rsp) 8@-8(%rsp) -1@-10(%rsp) -1@-11(%rsp).
I think you can file a bug for gcc community.
>
>
> At 2025-08-13 00:11:45, "Yonghong Song" <yonghong.song@linux.dev> wrote:
>>
>> On 8/12/25 12:02 AM, 赵佳炜 wrote:
>>> Yes, I've tried that but it didn't help. FYI:
>>>
>>> $ readelf -nsr usdt_rip
>>>
>>>
>>> Relocation section '.rela.dyn' at offset 0x530 contains 9 entries:
>>> Offset Info Type Sym. Value Sym. Name + Addend
>>> 000000003df0 000000000008 R_X86_64_RELATIVE 1150
>>> 000000003df8 000000000008 R_X86_64_RELATIVE 1110
>>> 000000004008 000000000008 R_X86_64_RELATIVE 4008
>>> 000000004018 000000000008 R_X86_64_RELATIVE 1160
>>> 000000003fd8 000100000006 R_X86_64_GLOB_DAT 0000000000000000 __libc_start_main@GLIBC_2.34 + 0
>>> 000000003fe0 000200000006 R_X86_64_GLOB_DAT 0000000000000000 _ITM_deregisterTM[...] + 0
>>> 000000003fe8 000300000006 R_X86_64_GLOB_DAT 0000000000000000 __gmon_start__ + 0
>>> 000000003ff0 000400000006 R_X86_64_GLOB_DAT 0000000000000000 _ITM_registerTMCl[...] + 0
>>> 000000003ff8 000500000006 R_X86_64_GLOB_DAT 0000000000000000 __cxa_finalize@GLIBC_2.2.5 + 0
>>>
>>>
>>> Symbol table '.dynsym' contains 6 entries:
>>> Num: Value Size Type Bind Vis Ndx Name
>>> 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
>>> 1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _[...]@GLIBC_2.34 (2)
>>> 2: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterT[...]
>>> 3: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
>>> 4: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMC[...]
>>> 5: 0000000000000000 0 FUNC WEAK DEFAULT UND [...]@GLIBC_2.2.5 (3)
>>>
>>>
>>> Symbol table '.symtab' contains 42 entries:
>>> Num: Value Size Type Bind Vis Ndx Name
>>> 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
>>> 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS Scrt1.o
>>> 2: 000000000000038c 32 OBJECT LOCAL DEFAULT 4 __abi_tag
>>> 3: 0000000000000000 0 FILE LOCAL DEFAULT ABS usdt_rip.c
>>> 4: 0000000000004021 1 OBJECT LOCAL DEFAULT 25 ti
>>> 5: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
>>> 6: 00000000000010a0 0 FUNC LOCAL DEFAULT 14 deregister_tm_clones
>>> 7: 00000000000010d0 0 FUNC LOCAL DEFAULT 14 register_tm_clones
>>> 8: 0000000000001110 0 FUNC LOCAL DEFAULT 14 __do_global_dtors_aux
>>> 9: 0000000000004020 1 OBJECT LOCAL DEFAULT 25 completed.0
>>> 10: 0000000000003df8 0 OBJECT LOCAL DEFAULT 21 __do_global_dtor[...]
>>> 11: 0000000000001150 0 FUNC LOCAL DEFAULT 14 frame_dummy
>>> 12: 0000000000003df0 0 OBJECT LOCAL DEFAULT 20 __frame_dummy_in[...]
>>> 13: 0000000000000000 0 FILE LOCAL DEFAULT ABS damo.c
>>> 14: 0000000000004022 1 OBJECT LOCAL DEFAULT 25 ti
>>> 15: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
>>> 16: 00000000000020d8 0 OBJECT LOCAL DEFAULT 19 __FRAME_END__
>>> 17: 0000000000000000 0 FILE LOCAL DEFAULT ABS
>>> 18: 0000000000003e00 0 OBJECT LOCAL DEFAULT 22 _DYNAMIC
>>> 19: 0000000000002008 0 NOTYPE LOCAL DEFAULT 18 __GNU_EH_FRAME_HDR
>>> 20: 0000000000003fc0 0 OBJECT LOCAL DEFAULT 23 _GLOBAL_OFFSET_TABLE_
>>> 21: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_mai[...]
>>> 22: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterT[...]
>>> 23: 0000000000004000 0 NOTYPE WEAK DEFAULT 24 data_start
>>> 24: 0000000000001160 8 FUNC GLOBAL DEFAULT 14 add
>>> 25: 0000000000004020 0 NOTYPE GLOBAL DEFAULT 24 _edata
>>> 26: 0000000000002004 1 NOTYPE WEAK HIDDEN 17 _.stapsdt.base
>>> 27: 0000000000004010 8 OBJECT GLOBAL DEFAULT 24 t1
>>> 28: 0000000000001168 0 FUNC GLOBAL HIDDEN 15 _fini
>>> 29: 0000000000004000 0 NOTYPE GLOBAL DEFAULT 24 __data_start
>>> 30: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
>>> 31: 0000000000004008 0 OBJECT GLOBAL HIDDEN 24 __dso_handle
>>> 32: 0000000000002000 4 OBJECT GLOBAL DEFAULT 16 _IO_stdin_used
>>> 33: 0000000000004028 0 NOTYPE GLOBAL DEFAULT 25 _end
>>> 34: 0000000000001070 38 FUNC GLOBAL DEFAULT 14 _start
>>> 35: 0000000000004020 0 NOTYPE GLOBAL DEFAULT 25 __bss_start
>>> 36: 0000000000001040 48 FUNC GLOBAL DEFAULT 14 main
>>> 37: 0000000000004018 8 OBJECT GLOBAL DEFAULT 24 add_ptr
>>> 38: 0000000000004020 0 OBJECT GLOBAL HIDDEN 24 __TMC_END__
>>> 39: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMC[...]
>>> 40: 0000000000000000 0 FUNC WEAK DEFAULT UND __cxa_finalize@G[...]
>>> 41: 0000000000001000 0 FUNC GLOBAL HIDDEN 11 _init
>>>
>>>
>>> Displaying notes found in: .note.gnu.property
>>> Owner Data size Description
>>> GNU 0x00000020 NT_GNU_PROPERTY_TYPE_0
>>> Properties: x86 feature: IBT, SHSTK
>>> x86 ISA needed: x86-64-baseline
>>>
>>>
>>> Displaying notes found in: .note.gnu.build-id
>>> Owner Data size Description
>>> GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring)
>>> Build ID: eb615daa575687cc44edc1d339b27890c12c27f1
>>>
>>>
>>> Displaying notes found in: .note.ABI-tag
>>> Owner Data size Description
>>> GNU 0x00000010 NT_GNU_ABI_TAG (ABI version tag)
>>> OS: Linux, ABI: 3.2.0
>>>
>>>
>>> Displaying notes found in: .note.stapsdt
>>> Owner Data size Description
>>> stapsdt 0x00000066 NT_STAPSDT (SystemTap probe descriptors)
>>> Provider: usdt_rip
>>> Name: rip_global_var
>>> Location: 0x0000000000001058, Base: 0x0000000000002004, Semaphore: 0x0000000000000000
>>> Arguments: -1@ti(%rip) 8@add_ptr(%rip) -1@4+t1(%rip) -1@ti(%rip)
>> Could you share the complete source codes and compiler options which
>> reproduce the above result?
>>
>>>
>>>
>>> At 2025-08-12 13:06:40, "Yonghong Song" <yonghong.song@linux.dev> wrote:
>>>> On 8/10/25 1:55 AM, 赵佳炜 wrote:
>>>>> Hi Yonghong,
>>>>>
>>>>> I found another issue where symbols can be duplicated, and I’m not sure how to tell them apart.
>>>>>
>>>>> For example, I created two C files named usdt_rip.c and hello.c. Both define their own static ti variables, like:`static volatile char ti = 0;`.
>>>>>
>>>>> After compiling, I obtained an ELF file usdt_rip whose .symtab contains the following entries:
>>>>>
>>>>> $ readelf -s usdt_rip
>>>>>
>>>>> Symbol table '.symtab' contains 42 entries:
>>>>> Num: Value Size Type Bind Vis Ndx Name
>>>>> 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
>>>>> 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS Scrt1.o
>>>>> 2: 000000000000038c 32 OBJECT LOCAL DEFAULT 4 __abi_tag
>>>>> 3: 0000000000000000 0 FILE LOCAL DEFAULT ABS usdt_rip.c
>>>>> 4: 0000000000004021 1 OBJECT LOCAL DEFAULT 25 ti
>>>>> 5: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
>>>>> 6: 00000000000010a0 0 FUNC LOCAL DEFAULT 14 deregister_tm_clones
>>>>> 7: 00000000000010d0 0 FUNC LOCAL DEFAULT 14 register_tm_clones
>>>>> 8: 0000000000001110 0 FUNC LOCAL DEFAULT 14 __do_global_dtors_aux
>>>>> 9: 0000000000004020 1 OBJECT LOCAL DEFAULT 25 completed.0
>>>>> 10: 0000000000003df8 0 OBJECT LOCAL DEFAULT 21 __do_global_dtor[...]
>>>>> 11: 0000000000001150 0 FUNC LOCAL DEFAULT 14 frame_dummy
>>>>> 12: 0000000000003df0 0 OBJECT LOCAL DEFAULT 20 __frame_dummy_in[...]
>>>>> 13: 0000000000000000 0 FILE LOCAL DEFAULT ABS damo.c
>>>>> 14: 0000000000004022 1 OBJECT LOCAL DEFAULT 25 ti
>>>>> 15: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
>>>>> 16: 00000000000020d8 0 OBJECT LOCAL DEFAULT 19 __FRAME_END__
>>>>>
>>>>>
>>>>> As you can see, there are two ti variables in the .symtab section. Their values are very close, making them hard to distinguish.
>>>>>
>>>>> I’m unsure how to handle this situation. Do you have any suggestions?
>>>> Did you check relocations? Relocaitons should be able to point exact which symbol.
>>>>
>>>>> Thanks,
>>>>> Jiawei Zhao
>>>> [...]
Hi, Yonghong. I've already filed an issue[1] in GCC community.
Accroding to the discussion, it's not a gcc bug but may be a systemtap bug.
I don't know how to report this bug to systemtap, but I found that the
libbpf/usdt have the same problem. I've filed an issue in libbpf/usdt repo[2].
I also have some ideas about it. I wrote it down in the issue[2] comment.
May be we can discuss there.
[1]. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121569
[2]. https://github.com/libbpf/usdt/issues/13
At 2025-08-13 13:24:39, "Yonghong Song" <yonghong.song@linux.dev> wrote:
>
>
>On 8/12/25 7:27 PM, 赵佳炜 wrote:
>>
>>
>>
>>
>>
>> Sure.
>>
>> The usdt_rip.c source code:
>>
>> ```C
>> // the usdt_rip.c file
>> #include <stddef.h>
>> #include <stdint.h>
>> #include "sdt.h"
>>
>> static volatile char ti = 0;
>>
>> int add(int a, int b) {
>> return a + b;
>> }
>> int (*add_ptr)(int, int) = add;
>>
>> struct st{
>> int a;
>> char b;
>> };
>>
>> volatile struct st t1 = {.a = 1, .b = 'a'};
>>
>> static void __always_inline trigger_func() {
>> STAP_PROBE4(usdt_rip, rip_global_var, ti, add_ptr, t1.b, ti);
>> }
>>
>> int main() {
>> trigger_func();
>> return 0;
>> }
>> ```
>>
>> The test/usdt_rip.c source code:
>>
>> ```C
>> // The test/usdt_rip.c file
>> static volatile char ti = 0;
>> ```
>>
>> The compiler option is `gcc -O2 -g usdt_rip.c test/usdt_rip.c -o usdt_rip`
>>
>> My compiler version:
>> ```bash
>> $ gcc -v
>> Using built-in specs.
>> COLLECT_GCC=gcc
>> COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-linux-gnu/13/lto-wrapper
>> OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa
>> OFFLOAD_TARGET_DEFAULT=1
>> Target: x86_64-linux-gnu
>> Configured with: ../src/configure -v --with-pkgversion='Ubuntu 13.3.0-6ubuntu2~24.04' --with-bugurl=file:///usr/share/doc/gcc-13/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-13 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/libexec --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-libstdcxx-backtrace --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-13-fG75Ri/gcc-13-13.3.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-13-fG75Ri/gcc-13-13.3.0/debian/tmp-gcn/usr --enable-offload-defaulted --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=2
>> Thread model: posix
>> Supported LTO compression algorithms: zlib zstd
>> gcc version 13.3.0 (Ubuntu 13.3.0-6ubuntu2~24.04)
>> ```
>
>Thanks for the code. I compiled with gcc14 compiler and the below is the asm code for 'main' function:
>
>0000000000401020 <main>:
> 401020: 90 nop
> 401021: 31 c0 xor %eax,%eax
> 401023: c3 ret
> 401024: 66 2e 0f 1f 84 00 00 cs nopw 0x0(%rax,%rax,1)
> 40102b: 00 00 00
> 40102e: 66 90 xchg %ax,%ax
>
>stapsdt note:
> Displaying notes found in: .note.stapsdt
> Owner Data size Description
> stapsdt 0x00000066 NT_STAPSDT (SystemTap probe descriptors)
> Provider: usdt_rip
> Name: rip_global_var
> Location: 0x0000000000401020, Base: 0x0000000000402010, Semaphore: 0x0000000000000000
> Arguments: -1@ti(%rip) 8@add_ptr(%rip) -1@t1+4(%rip) -1@ti(%rip)
>
>$ readelf -s usdt_rip | grep ti
> 4: 0000000000404019 1 OBJECT LOCAL DEFAULT 24 ti
> 14: 000000000040401a 1 OBJECT LOCAL DEFAULT 24 ti
>
>So yet, it would be hard to find which 'ti' should be used to resolve usdt arguments.
>
>
>I then tried with clang21. The 'main' function:
>
>0000000000001140 <main>:
> 1140: 0f b6 05 f2 2e 00 00 movzbl 0x2ef2(%rip),%eax # 4039 <ti>
> 1147: 48 8b 0d da 2e 00 00 mov 0x2eda(%rip),%rcx # 4028 <add_ptr>
> 114e: 0f b6 15 df 2e 00 00 movzbl 0x2edf(%rip),%edx # 4034 <t1+0x4>
> 1155: 0f b6 35 dd 2e 00 00 movzbl 0x2edd(%rip),%esi # 4039 <ti>
> 115c: 88 44 24 f7 mov %al,-0x9(%rsp)
> 1160: 48 89 4c 24 f8 mov %rcx,-0x8(%rsp)
> 1165: 88 54 24 f6 mov %dl,-0xa(%rsp)
> 1169: 40 88 74 24 f5 mov %sil,-0xb(%rsp)
> 116e: 90 nop
> 116f: 31 c0 xor %eax,%eax
> 1171: c3 ret
> 1172: 66 90 xchg %ax,%ax
>
>For this case, usdt should work properly. The following is related symbol table:
>
> 74: 0000000000004028 8 OBJECT GLOBAL DEFAULT 26 add_ptr
> 64: 0000000000004030 8 OBJECT GLOBAL DEFAULT 26 t1
> 50: 0000000000004039 1 OBJECT LOCAL DEFAULT 27 ti <=== for '# 4039 <ti>'.
>
>And for llvm21, only one 'ti' in the symbol table.
>
>$ readelf -s usdt_rip | grep ti
> 50: 0000000000004039 1 OBJECT LOCAL DEFAULT 27 ti
>
>The stapsdt note:
> Displaying notes found in: .note.stapsdt
> Owner Data size Description
> stapsdt 0x00000061 NT_STAPSDT (SystemTap probe descriptors)
> Provider: usdt_rip
> Name: rip_global_var
> Location: 0x000000000000116e, Base: 0x0000000000002004, Semaphore: 0x0000000000000000
> Arguments: -1@-9(%rsp) 8@-8(%rsp) -1@-10(%rsp) -1@-11(%rsp)
>
>It looks like clang optimized away the following:
> // The test/usdt_rip.c file
> static volatile char ti = 0;
>but gcc does not. But even if the above 'ti' is preserved for clang,
>clang generated code should still be fine since the argument
>is -1@-9(%rsp) 8@-8(%rsp) -1@-10(%rsp) -1@-11(%rsp).
>
>I think you can file a bug for gcc community.
>
>>
>>
>> At 2025-08-13 00:11:45, "Yonghong Song" <yonghong.song@linux.dev> wrote:
>>>
>>> On 8/12/25 12:02 AM, 赵佳炜 wrote:
>>>> Yes, I've tried that but it didn't help. FYI:
>>>>
>>>> $ readelf -nsr usdt_rip
>>>>
>>>>
>>>> Relocation section '.rela.dyn' at offset 0x530 contains 9 entries:
>>>> Offset Info Type Sym. Value Sym. Name + Addend
>>>> 000000003df0 000000000008 R_X86_64_RELATIVE 1150
>>>> 000000003df8 000000000008 R_X86_64_RELATIVE 1110
>>>> 000000004008 000000000008 R_X86_64_RELATIVE 4008
>>>> 000000004018 000000000008 R_X86_64_RELATIVE 1160
>>>> 000000003fd8 000100000006 R_X86_64_GLOB_DAT 0000000000000000 __libc_start_main@GLIBC_2.34 + 0
>>>> 000000003fe0 000200000006 R_X86_64_GLOB_DAT 0000000000000000 _ITM_deregisterTM[...] + 0
>>>> 000000003fe8 000300000006 R_X86_64_GLOB_DAT 0000000000000000 __gmon_start__ + 0
>>>> 000000003ff0 000400000006 R_X86_64_GLOB_DAT 0000000000000000 _ITM_registerTMCl[...] + 0
>>>> 000000003ff8 000500000006 R_X86_64_GLOB_DAT 0000000000000000 __cxa_finalize@GLIBC_2.2.5 + 0
>>>>
>>>>
>>>> Symbol table '.dynsym' contains 6 entries:
>>>> Num: Value Size Type Bind Vis Ndx Name
>>>> 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
>>>> 1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _[...]@GLIBC_2.34 (2)
>>>> 2: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterT[...]
>>>> 3: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
>>>> 4: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMC[...]
>>>> 5: 0000000000000000 0 FUNC WEAK DEFAULT UND [...]@GLIBC_2.2.5 (3)
>>>>
>>>>
>>>> Symbol table '.symtab' contains 42 entries:
>>>> Num: Value Size Type Bind Vis Ndx Name
>>>> 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
>>>> 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS Scrt1.o
>>>> 2: 000000000000038c 32 OBJECT LOCAL DEFAULT 4 __abi_tag
>>>> 3: 0000000000000000 0 FILE LOCAL DEFAULT ABS usdt_rip.c
>>>> 4: 0000000000004021 1 OBJECT LOCAL DEFAULT 25 ti
>>>> 5: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
>>>> 6: 00000000000010a0 0 FUNC LOCAL DEFAULT 14 deregister_tm_clones
>>>> 7: 00000000000010d0 0 FUNC LOCAL DEFAULT 14 register_tm_clones
>>>> 8: 0000000000001110 0 FUNC LOCAL DEFAULT 14 __do_global_dtors_aux
>>>> 9: 0000000000004020 1 OBJECT LOCAL DEFAULT 25 completed.0
>>>> 10: 0000000000003df8 0 OBJECT LOCAL DEFAULT 21 __do_global_dtor[...]
>>>> 11: 0000000000001150 0 FUNC LOCAL DEFAULT 14 frame_dummy
>>>> 12: 0000000000003df0 0 OBJECT LOCAL DEFAULT 20 __frame_dummy_in[...]
>>>> 13: 0000000000000000 0 FILE LOCAL DEFAULT ABS damo.c
>>>> 14: 0000000000004022 1 OBJECT LOCAL DEFAULT 25 ti
>>>> 15: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
>>>> 16: 00000000000020d8 0 OBJECT LOCAL DEFAULT 19 __FRAME_END__
>>>> 17: 0000000000000000 0 FILE LOCAL DEFAULT ABS
>>>> 18: 0000000000003e00 0 OBJECT LOCAL DEFAULT 22 _DYNAMIC
>>>> 19: 0000000000002008 0 NOTYPE LOCAL DEFAULT 18 __GNU_EH_FRAME_HDR
>>>> 20: 0000000000003fc0 0 OBJECT LOCAL DEFAULT 23 _GLOBAL_OFFSET_TABLE_
>>>> 21: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_mai[...]
>>>> 22: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterT[...]
>>>> 23: 0000000000004000 0 NOTYPE WEAK DEFAULT 24 data_start
>>>> 24: 0000000000001160 8 FUNC GLOBAL DEFAULT 14 add
>>>> 25: 0000000000004020 0 NOTYPE GLOBAL DEFAULT 24 _edata
>>>> 26: 0000000000002004 1 NOTYPE WEAK HIDDEN 17 _.stapsdt.base
>>>> 27: 0000000000004010 8 OBJECT GLOBAL DEFAULT 24 t1
>>>> 28: 0000000000001168 0 FUNC GLOBAL HIDDEN 15 _fini
>>>> 29: 0000000000004000 0 NOTYPE GLOBAL DEFAULT 24 __data_start
>>>> 30: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
>>>> 31: 0000000000004008 0 OBJECT GLOBAL HIDDEN 24 __dso_handle
>>>> 32: 0000000000002000 4 OBJECT GLOBAL DEFAULT 16 _IO_stdin_used
>>>> 33: 0000000000004028 0 NOTYPE GLOBAL DEFAULT 25 _end
>>>> 34: 0000000000001070 38 FUNC GLOBAL DEFAULT 14 _start
>>>> 35: 0000000000004020 0 NOTYPE GLOBAL DEFAULT 25 __bss_start
>>>> 36: 0000000000001040 48 FUNC GLOBAL DEFAULT 14 main
>>>> 37: 0000000000004018 8 OBJECT GLOBAL DEFAULT 24 add_ptr
>>>> 38: 0000000000004020 0 OBJECT GLOBAL HIDDEN 24 __TMC_END__
>>>> 39: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMC[...]
>>>> 40: 0000000000000000 0 FUNC WEAK DEFAULT UND __cxa_finalize@G[...]
>>>> 41: 0000000000001000 0 FUNC GLOBAL HIDDEN 11 _init
>>>>
>>>>
>>>> Displaying notes found in: .note.gnu.property
>>>> Owner Data size Description
>>>> GNU 0x00000020 NT_GNU_PROPERTY_TYPE_0
>>>> Properties: x86 feature: IBT, SHSTK
>>>> x86 ISA needed: x86-64-baseline
>>>>
>>>>
>>>> Displaying notes found in: .note.gnu.build-id
>>>> Owner Data size Description
>>>> GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring)
>>>> Build ID: eb615daa575687cc44edc1d339b27890c12c27f1
>>>>
>>>>
>>>> Displaying notes found in: .note.ABI-tag
>>>> Owner Data size Description
>>>> GNU 0x00000010 NT_GNU_ABI_TAG (ABI version tag)
>>>> OS: Linux, ABI: 3.2.0
>>>>
>>>>
>>>> Displaying notes found in: .note.stapsdt
>>>> Owner Data size Description
>>>> stapsdt 0x00000066 NT_STAPSDT (SystemTap probe descriptors)
>>>> Provider: usdt_rip
>>>> Name: rip_global_var
>>>> Location: 0x0000000000001058, Base: 0x0000000000002004, Semaphore: 0x0000000000000000
>>>> Arguments: -1@ti(%rip) 8@add_ptr(%rip) -1@4+t1(%rip) -1@ti(%rip)
>>> Could you share the complete source codes and compiler options which
>>> reproduce the above result?
>>>
>>>>
>>>>
>>>> At 2025-08-12 13:06:40, "Yonghong Song" <yonghong.song@linux.dev> wrote:
>>>>> On 8/10/25 1:55 AM, 赵佳炜 wrote:
>>>>>> Hi Yonghong,
>>>>>>
>>>>>> I found another issue where symbols can be duplicated, and I’m not sure how to tell them apart.
>>>>>>
>>>>>> For example, I created two C files named usdt_rip.c and hello.c. Both define their own static ti variables, like:`static volatile char ti = 0;`.
>>>>>>
>>>>>> After compiling, I obtained an ELF file usdt_rip whose .symtab contains the following entries:
>>>>>>
>>>>>> $ readelf -s usdt_rip
>>>>>>
>>>>>> Symbol table '.symtab' contains 42 entries:
>>>>>> Num: Value Size Type Bind Vis Ndx Name
>>>>>> 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
>>>>>> 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS Scrt1.o
>>>>>> 2: 000000000000038c 32 OBJECT LOCAL DEFAULT 4 __abi_tag
>>>>>> 3: 0000000000000000 0 FILE LOCAL DEFAULT ABS usdt_rip.c
>>>>>> 4: 0000000000004021 1 OBJECT LOCAL DEFAULT 25 ti
>>>>>> 5: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
>>>>>> 6: 00000000000010a0 0 FUNC LOCAL DEFAULT 14 deregister_tm_clones
>>>>>> 7: 00000000000010d0 0 FUNC LOCAL DEFAULT 14 register_tm_clones
>>>>>> 8: 0000000000001110 0 FUNC LOCAL DEFAULT 14 __do_global_dtors_aux
>>>>>> 9: 0000000000004020 1 OBJECT LOCAL DEFAULT 25 completed.0
>>>>>> 10: 0000000000003df8 0 OBJECT LOCAL DEFAULT 21 __do_global_dtor[...]
>>>>>> 11: 0000000000001150 0 FUNC LOCAL DEFAULT 14 frame_dummy
>>>>>> 12: 0000000000003df0 0 OBJECT LOCAL DEFAULT 20 __frame_dummy_in[...]
>>>>>> 13: 0000000000000000 0 FILE LOCAL DEFAULT ABS damo.c
>>>>>> 14: 0000000000004022 1 OBJECT LOCAL DEFAULT 25 ti
>>>>>> 15: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
>>>>>> 16: 00000000000020d8 0 OBJECT LOCAL DEFAULT 19 __FRAME_END__
>>>>>>
>>>>>>
>>>>>> As you can see, there are two ti variables in the .symtab section. Their values are very close, making them hard to distinguish.
>>>>>>
>>>>>> I’m unsure how to handle this situation. Do you have any suggestions?
>>>>> Did you check relocations? Relocaitons should be able to point exact which symbol.
>>>>>
>>>>>> Thanks,
>>>>>> Jiawei Zhao
>>>>> [...]
>
On 8/17/25 6:43 AM, 赵佳炜 wrote:
>
>
>
>
>
>
> Hi, Yonghong. I've already filed an issue[1] in GCC community.
>
>
> Accroding to the discussion, it's not a gcc bug but may be a systemtap bug.
> I don't know how to report this bug to systemtap, but I found that the
> libbpf/usdt have the same problem. I've filed an issue in libbpf/usdt repo[2].
>
> I also have some ideas about it. I wrote it down in the issue[2] comment.
> May be we can discuss there.
>
> [1]. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121569
> [2]. https://github.com/libbpf/usdt/issues/13
Thanks for filing an issue on gcc and getting some feedback/suggestions
from gcc community.
Currently, libbpf/usdt does not suport format like '-1@ti(%rip)'. If we do
intend to implement this. libbpf/usdt can reject that if 'ti' is a
static variable. libbpf can provide some hints about how to make it
work (see above [1] and [2]). Then, it would be user's reponsibility to
change code so libbpf can support it.
>
>
>
> At 2025-08-13 13:24:39, "Yonghong Song" <yonghong.song@linux.dev> wrote:
>>
>> On 8/12/25 7:27 PM, 赵佳炜 wrote:
>>>
>>>
>>>
>>>
>>> Sure.
>>>
>>> The usdt_rip.c source code:
>>>
>>> ```C
>>> // the usdt_rip.c file
>>> #include <stddef.h>
>>> #include <stdint.h>
>>> #include "sdt.h"
>>>
>>> static volatile char ti = 0;
>>>
>>> int add(int a, int b) {
>>> return a + b;
>>> }
>>> int (*add_ptr)(int, int) = add;
>>>
>>> struct st{
>>> int a;
>>> char b;
>>> };
>>>
>>> volatile struct st t1 = {.a = 1, .b = 'a'};
>>>
>>> static void __always_inline trigger_func() {
>>> STAP_PROBE4(usdt_rip, rip_global_var, ti, add_ptr, t1.b, ti);
>>> }
>>>
>>> int main() {
>>> trigger_func();
>>> return 0;
>>> }
>>> ```
>>>
>>> The test/usdt_rip.c source code:
>>>
>>> ```C
>>> // The test/usdt_rip.c file
>>> static volatile char ti = 0;
>>> ```
>>>
>>> The compiler option is `gcc -O2 -g usdt_rip.c test/usdt_rip.c -o usdt_rip`
>>>
>>> My compiler version:
>>> ```bash
>>> $ gcc -v
>>> Using built-in specs.
>>> COLLECT_GCC=gcc
>>> COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-linux-gnu/13/lto-wrapper
>>> OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa
>>> OFFLOAD_TARGET_DEFAULT=1
>>> Target: x86_64-linux-gnu
>>> Configured with: ../src/configure -v --with-pkgversion='Ubuntu 13.3.0-6ubuntu2~24.04' --with-bugurl=file:///usr/share/doc/gcc-13/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-13 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/libexec --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-libstdcxx-backtrace --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-13-fG75Ri/gcc-13-13.3.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-13-fG75Ri/gcc-13-13.3.0/debian/tmp-gcn/usr --enable-offload-defaulted --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=2
>>> Thread model: posix
>>> Supported LTO compression algorithms: zlib zstd
>>> gcc version 13.3.0 (Ubuntu 13.3.0-6ubuntu2~24.04)
>>> ```
>> Thanks for the code. I compiled with gcc14 compiler and the below is the asm code for 'main' function:
>>
>> 0000000000401020 <main>:
>> 401020: 90 nop
>> 401021: 31 c0 xor %eax,%eax
>> 401023: c3 ret
>> 401024: 66 2e 0f 1f 84 00 00 cs nopw 0x0(%rax,%rax,1)
>> 40102b: 00 00 00
>> 40102e: 66 90 xchg %ax,%ax
>>
>> stapsdt note:
>> Displaying notes found in: .note.stapsdt
>> Owner Data size Description
>> stapsdt 0x00000066 NT_STAPSDT (SystemTap probe descriptors)
>> Provider: usdt_rip
>> Name: rip_global_var
>> Location: 0x0000000000401020, Base: 0x0000000000402010, Semaphore: 0x0000000000000000
>> Arguments: -1@ti(%rip) 8@add_ptr(%rip) -1@t1+4(%rip) -1@ti(%rip)
>>
>> $ readelf -s usdt_rip | grep ti
>> 4: 0000000000404019 1 OBJECT LOCAL DEFAULT 24 ti
>> 14: 000000000040401a 1 OBJECT LOCAL DEFAULT 24 ti
>>
>> So yet, it would be hard to find which 'ti' should be used to resolve usdt arguments.
>>
>>
>> I then tried with clang21. The 'main' function:
>>
>> 0000000000001140 <main>:
>> 1140: 0f b6 05 f2 2e 00 00 movzbl 0x2ef2(%rip),%eax # 4039 <ti>
>> 1147: 48 8b 0d da 2e 00 00 mov 0x2eda(%rip),%rcx # 4028 <add_ptr>
>> 114e: 0f b6 15 df 2e 00 00 movzbl 0x2edf(%rip),%edx # 4034 <t1+0x4>
>> 1155: 0f b6 35 dd 2e 00 00 movzbl 0x2edd(%rip),%esi # 4039 <ti>
>> 115c: 88 44 24 f7 mov %al,-0x9(%rsp)
>> 1160: 48 89 4c 24 f8 mov %rcx,-0x8(%rsp)
>> 1165: 88 54 24 f6 mov %dl,-0xa(%rsp)
>> 1169: 40 88 74 24 f5 mov %sil,-0xb(%rsp)
>> 116e: 90 nop
>> 116f: 31 c0 xor %eax,%eax
>> 1171: c3 ret
>> 1172: 66 90 xchg %ax,%ax
>>
>> For this case, usdt should work properly. The following is related symbol table:
>>
>> 74: 0000000000004028 8 OBJECT GLOBAL DEFAULT 26 add_ptr
>> 64: 0000000000004030 8 OBJECT GLOBAL DEFAULT 26 t1
>> 50: 0000000000004039 1 OBJECT LOCAL DEFAULT 27 ti <=== for '# 4039 <ti>'.
>>
>> And for llvm21, only one 'ti' in the symbol table.
>>
>> $ readelf -s usdt_rip | grep ti
>> 50: 0000000000004039 1 OBJECT LOCAL DEFAULT 27 ti
>>
>> The stapsdt note:
>> Displaying notes found in: .note.stapsdt
>> Owner Data size Description
>> stapsdt 0x00000061 NT_STAPSDT (SystemTap probe descriptors)
>> Provider: usdt_rip
>> Name: rip_global_var
>> Location: 0x000000000000116e, Base: 0x0000000000002004, Semaphore: 0x0000000000000000
>> Arguments: -1@-9(%rsp) 8@-8(%rsp) -1@-10(%rsp) -1@-11(%rsp)
>>
>> It looks like clang optimized away the following:
>> // The test/usdt_rip.c file
>> static volatile char ti = 0;
>> but gcc does not. But even if the above 'ti' is preserved for clang,
>> clang generated code should still be fine since the argument
>> is -1@-9(%rsp) 8@-8(%rsp) -1@-10(%rsp) -1@-11(%rsp).
>>
>> I think you can file a bug for gcc community.
>>
>>>
>>> At 2025-08-13 00:11:45, "Yonghong Song" <yonghong.song@linux.dev> wrote:
>>>> On 8/12/25 12:02 AM, 赵佳炜 wrote:
>>>>> Yes, I've tried that but it didn't help. FYI:
>>>>>
>>>>> $ readelf -nsr usdt_rip
>>>>>
>>>>>
>>>>> Relocation section '.rela.dyn' at offset 0x530 contains 9 entries:
>>>>> Offset Info Type Sym. Value Sym. Name + Addend
>>>>> 000000003df0 000000000008 R_X86_64_RELATIVE 1150
>>>>> 000000003df8 000000000008 R_X86_64_RELATIVE 1110
>>>>> 000000004008 000000000008 R_X86_64_RELATIVE 4008
>>>>> 000000004018 000000000008 R_X86_64_RELATIVE 1160
>>>>> 000000003fd8 000100000006 R_X86_64_GLOB_DAT 0000000000000000 __libc_start_main@GLIBC_2.34 + 0
>>>>> 000000003fe0 000200000006 R_X86_64_GLOB_DAT 0000000000000000 _ITM_deregisterTM[...] + 0
>>>>> 000000003fe8 000300000006 R_X86_64_GLOB_DAT 0000000000000000 __gmon_start__ + 0
>>>>> 000000003ff0 000400000006 R_X86_64_GLOB_DAT 0000000000000000 _ITM_registerTMCl[...] + 0
>>>>> 000000003ff8 000500000006 R_X86_64_GLOB_DAT 0000000000000000 __cxa_finalize@GLIBC_2.2.5 + 0
>>>>>
>>>>>
>>>>> Symbol table '.dynsym' contains 6 entries:
>>>>> Num: Value Size Type Bind Vis Ndx Name
>>>>> 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
>>>>> 1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _[...]@GLIBC_2.34 (2)
>>>>> 2: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterT[...]
>>>>> 3: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
>>>>> 4: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMC[...]
>>>>> 5: 0000000000000000 0 FUNC WEAK DEFAULT UND [...]@GLIBC_2.2.5 (3)
>>>>>
>>>>>
>>>>> Symbol table '.symtab' contains 42 entries:
>>>>> Num: Value Size Type Bind Vis Ndx Name
>>>>> 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
>>>>> 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS Scrt1.o
>>>>> 2: 000000000000038c 32 OBJECT LOCAL DEFAULT 4 __abi_tag
>>>>> 3: 0000000000000000 0 FILE LOCAL DEFAULT ABS usdt_rip.c
>>>>> 4: 0000000000004021 1 OBJECT LOCAL DEFAULT 25 ti
>>>>> 5: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
>>>>> 6: 00000000000010a0 0 FUNC LOCAL DEFAULT 14 deregister_tm_clones
>>>>> 7: 00000000000010d0 0 FUNC LOCAL DEFAULT 14 register_tm_clones
>>>>> 8: 0000000000001110 0 FUNC LOCAL DEFAULT 14 __do_global_dtors_aux
>>>>> 9: 0000000000004020 1 OBJECT LOCAL DEFAULT 25 completed.0
>>>>> 10: 0000000000003df8 0 OBJECT LOCAL DEFAULT 21 __do_global_dtor[...]
>>>>> 11: 0000000000001150 0 FUNC LOCAL DEFAULT 14 frame_dummy
>>>>> 12: 0000000000003df0 0 OBJECT LOCAL DEFAULT 20 __frame_dummy_in[...]
>>>>> 13: 0000000000000000 0 FILE LOCAL DEFAULT ABS damo.c
>>>>> 14: 0000000000004022 1 OBJECT LOCAL DEFAULT 25 ti
>>>>> 15: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
>>>>> 16: 00000000000020d8 0 OBJECT LOCAL DEFAULT 19 __FRAME_END__
>>>>> 17: 0000000000000000 0 FILE LOCAL DEFAULT ABS
>>>>> 18: 0000000000003e00 0 OBJECT LOCAL DEFAULT 22 _DYNAMIC
>>>>> 19: 0000000000002008 0 NOTYPE LOCAL DEFAULT 18 __GNU_EH_FRAME_HDR
>>>>> 20: 0000000000003fc0 0 OBJECT LOCAL DEFAULT 23 _GLOBAL_OFFSET_TABLE_
>>>>> 21: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_mai[...]
>>>>> 22: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterT[...]
>>>>> 23: 0000000000004000 0 NOTYPE WEAK DEFAULT 24 data_start
>>>>> 24: 0000000000001160 8 FUNC GLOBAL DEFAULT 14 add
>>>>> 25: 0000000000004020 0 NOTYPE GLOBAL DEFAULT 24 _edata
>>>>> 26: 0000000000002004 1 NOTYPE WEAK HIDDEN 17 _.stapsdt.base
>>>>> 27: 0000000000004010 8 OBJECT GLOBAL DEFAULT 24 t1
>>>>> 28: 0000000000001168 0 FUNC GLOBAL HIDDEN 15 _fini
>>>>> 29: 0000000000004000 0 NOTYPE GLOBAL DEFAULT 24 __data_start
>>>>> 30: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
>>>>> 31: 0000000000004008 0 OBJECT GLOBAL HIDDEN 24 __dso_handle
>>>>> 32: 0000000000002000 4 OBJECT GLOBAL DEFAULT 16 _IO_stdin_used
>>>>> 33: 0000000000004028 0 NOTYPE GLOBAL DEFAULT 25 _end
>>>>> 34: 0000000000001070 38 FUNC GLOBAL DEFAULT 14 _start
>>>>> 35: 0000000000004020 0 NOTYPE GLOBAL DEFAULT 25 __bss_start
>>>>> 36: 0000000000001040 48 FUNC GLOBAL DEFAULT 14 main
>>>>> 37: 0000000000004018 8 OBJECT GLOBAL DEFAULT 24 add_ptr
>>>>> 38: 0000000000004020 0 OBJECT GLOBAL HIDDEN 24 __TMC_END__
>>>>> 39: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMC[...]
>>>>> 40: 0000000000000000 0 FUNC WEAK DEFAULT UND __cxa_finalize@G[...]
>>>>> 41: 0000000000001000 0 FUNC GLOBAL HIDDEN 11 _init
>>>>>
>>>>>
>>>>> Displaying notes found in: .note.gnu.property
>>>>> Owner Data size Description
>>>>> GNU 0x00000020 NT_GNU_PROPERTY_TYPE_0
>>>>> Properties: x86 feature: IBT, SHSTK
>>>>> x86 ISA needed: x86-64-baseline
>>>>>
>>>>>
>>>>> Displaying notes found in: .note.gnu.build-id
>>>>> Owner Data size Description
>>>>> GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring)
>>>>> Build ID: eb615daa575687cc44edc1d339b27890c12c27f1
>>>>>
>>>>>
>>>>> Displaying notes found in: .note.ABI-tag
>>>>> Owner Data size Description
>>>>> GNU 0x00000010 NT_GNU_ABI_TAG (ABI version tag)
>>>>> OS: Linux, ABI: 3.2.0
>>>>>
>>>>>
>>>>> Displaying notes found in: .note.stapsdt
>>>>> Owner Data size Description
>>>>> stapsdt 0x00000066 NT_STAPSDT (SystemTap probe descriptors)
>>>>> Provider: usdt_rip
>>>>> Name: rip_global_var
>>>>> Location: 0x0000000000001058, Base: 0x0000000000002004, Semaphore: 0x0000000000000000
>>>>> Arguments: -1@ti(%rip) 8@add_ptr(%rip) -1@4+t1(%rip) -1@ti(%rip)
>>>> Could you share the complete source codes and compiler options which
>>>> reproduce the above result?
>>>>
>>>>>
>>>>> At 2025-08-12 13:06:40, "Yonghong Song" <yonghong.song@linux.dev> wrote:
>>>>>> On 8/10/25 1:55 AM, 赵佳炜 wrote:
>>>>>>> Hi Yonghong,
>>>>>>>
>>>>>>> I found another issue where symbols can be duplicated, and I’m not sure how to tell them apart.
>>>>>>>
>>>>>>> For example, I created two C files named usdt_rip.c and hello.c. Both define their own static ti variables, like:`static volatile char ti = 0;`.
>>>>>>>
>>>>>>> After compiling, I obtained an ELF file usdt_rip whose .symtab contains the following entries:
>>>>>>>
>>>>>>> $ readelf -s usdt_rip
>>>>>>>
>>>>>>> Symbol table '.symtab' contains 42 entries:
>>>>>>> Num: Value Size Type Bind Vis Ndx Name
>>>>>>> 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
>>>>>>> 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS Scrt1.o
>>>>>>> 2: 000000000000038c 32 OBJECT LOCAL DEFAULT 4 __abi_tag
>>>>>>> 3: 0000000000000000 0 FILE LOCAL DEFAULT ABS usdt_rip.c
>>>>>>> 4: 0000000000004021 1 OBJECT LOCAL DEFAULT 25 ti
>>>>>>> 5: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
>>>>>>> 6: 00000000000010a0 0 FUNC LOCAL DEFAULT 14 deregister_tm_clones
>>>>>>> 7: 00000000000010d0 0 FUNC LOCAL DEFAULT 14 register_tm_clones
>>>>>>> 8: 0000000000001110 0 FUNC LOCAL DEFAULT 14 __do_global_dtors_aux
>>>>>>> 9: 0000000000004020 1 OBJECT LOCAL DEFAULT 25 completed.0
>>>>>>> 10: 0000000000003df8 0 OBJECT LOCAL DEFAULT 21 __do_global_dtor[...]
>>>>>>> 11: 0000000000001150 0 FUNC LOCAL DEFAULT 14 frame_dummy
>>>>>>> 12: 0000000000003df0 0 OBJECT LOCAL DEFAULT 20 __frame_dummy_in[...]
>>>>>>> 13: 0000000000000000 0 FILE LOCAL DEFAULT ABS damo.c
>>>>>>> 14: 0000000000004022 1 OBJECT LOCAL DEFAULT 25 ti
>>>>>>> 15: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
>>>>>>> 16: 00000000000020d8 0 OBJECT LOCAL DEFAULT 19 __FRAME_END__
>>>>>>>
>>>>>>>
>>>>>>> As you can see, there are two ti variables in the .symtab section. Their values are very close, making them hard to distinguish.
>>>>>>>
>>>>>>> I’m unsure how to handle this situation. Do you have any suggestions?
>>>>>> Did you check relocations? Relocaitons should be able to point exact which symbol.
>>>>>>
>>>>>>> Thanks,
>>>>>>> Jiawei Zhao
>>>>>> [...]
On Mon, Aug 18, 2025 at 10:35 AM Yonghong Song <yonghong.song@linux.dev> wrote: > > > > On 8/17/25 6:43 AM, 赵佳炜 wrote: > > > > > > > > > > > > > > Hi, Yonghong. I've already filed an issue[1] in GCC community. > > > > > > Accroding to the discussion, it's not a gcc bug but may be a systemtap bug. > > I don't know how to report this bug to systemtap, but I found that the > > libbpf/usdt have the same problem. I've filed an issue in libbpf/usdt repo[2]. > > > > I also have some ideas about it. I wrote it down in the issue[2] comment. > > May be we can discuss there. > > > > [1]. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121569 > > [2]. https://github.com/libbpf/usdt/issues/13 > > Thanks for filing an issue on gcc and getting some feedback/suggestions > from gcc community. > > Currently, libbpf/usdt does not suport format like '-1@ti(%rip)'. If we do Exactly, it doesn't. I haven't yet ran into a case where real-world applications would use such an argument format, so there was no incentive in trying to support it. Was this issue discovered as part of testing on some real world application, or it's mostly through testing on synthetic cases? > intend to implement this. libbpf/usdt can reject that if 'ti' is a > static variable. libbpf can provide some hints about how to make it > work (see above [1] and [2]). Then, it would be user's reponsibility to > change code so libbpf can support it. > > > > > > > [...]
In the previous discussion with Yonghong Song, we found that some compiler would generate such an arguement format. Although I have never encounter such an issue, I found that the global volatile variable could trigger the compiler to generate this argument spec. So I tried to solve this problem. I guess this would not be a problem since we have already used STAP_PROBE_ASM to reliably generate SIB argument spec. BTW, I have another issue to discuss. Now, bcc framework is not a recommendation for writing bpf program, so bpftrace is now migrating from bcc framework to libbpf. Bcc framework provides some relevant APIs for get usdt probe info[1]. And I found that there is not similar APIs in libbpf, therefore I have to parse elf file manually. Could we add some relevant APIs, maybe like `bpf_program__usdt_probe_list`, in libbpf? I can make a patch to implement it. WDYT? [1]. https://github.com/bpftrace/bpftrace/blob/1cd4bbdd4a13dd55880f2cc638dde641fb5f8474/src/usdt.cpp#L131C1-L152C2 At 2025-08-21 07:00:35, "Andrii Nakryiko" <andrii.nakryiko@gmail.com> wrote: >On Mon, Aug 18, 2025 at 10:35 AM Yonghong Song <yonghong.song@linux.dev> wrote: >> >> >> >> On 8/17/25 6:43 AM, 赵佳炜 wrote: >> > >> > >> > >> > >> > >> > >> > Hi, Yonghong. I've already filed an issue[1] in GCC community. >> > >> > >> > Accroding to the discussion, it's not a gcc bug but may be a systemtap bug. >> > I don't know how to report this bug to systemtap, but I found that the >> > libbpf/usdt have the same problem. I've filed an issue in libbpf/usdt repo[2]. >> > >> > I also have some ideas about it. I wrote it down in the issue[2] comment. >> > May be we can discuss there. >> > >> > [1]. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121569 >> > [2]. https://github.com/libbpf/usdt/issues/13 >> >> Thanks for filing an issue on gcc and getting some feedback/suggestions >> from gcc community. >> >> Currently, libbpf/usdt does not suport format like '-1@ti(%rip)'. If we do > >Exactly, it doesn't. I haven't yet ran into a case where real-world >applications would use such an argument format, so there was no >incentive in trying to support it. > >Was this issue discovered as part of testing on some real world >application, or it's mostly through testing on synthetic cases? > >> intend to implement this. libbpf/usdt can reject that if 'ti' is a >> static variable. libbpf can provide some hints about how to make it >> work (see above [1] and [2]). Then, it would be user's reponsibility to >> change code so libbpf can support it. >> >> > >> > >> > > >[...]
On Thu, Aug 21, 2025 at 8:38 AM 赵佳炜 <phoenix500526@163.com> wrote: > > > > > > > > > > > In the previous discussion with Yonghong Song, we found that some compiler would generate > such an arguement format. Although I have never encounter such an issue, I found that the > global volatile variable could trigger the compiler to generate this argument spec. So I tried to > solve this problem. I guess this would not be a problem since we have already used STAP_PROBE_ASM > to reliably generate SIB argument spec. Yep, let's hold off on implementing this, as it doesn't seem to be really necessary in practice. > > BTW, I have another issue to discuss. > > Now, bcc framework is not a recommendation for writing bpf program, so bpftrace is now migrating > from bcc framework to libbpf. Bcc framework provides some relevant APIs for get usdt probe info[1]. > And I found that there is not similar APIs in libbpf, therefore I have to parse elf file manually. > > Could we add some relevant APIs, maybe like `bpf_program__usdt_probe_list`, in libbpf? I can make > a patch to implement it. WDYT? > I'm not yet convinced this belongs in libbpf, tbh. The process of discovering USDTs actually involved two separate tasks: discovering binaries (executable and shared libs) that constitute a process, and then for each binary discovering which USDTs belong to it. The first part is pretty clearly out of scope for libbpf. Second one in principle can be added, but as I said I'm a bit hesitant at this point, as we don't even have "USDT manager" exposed through public API. So not yet. > > [1]. https://github.com/bpftrace/bpftrace/blob/1cd4bbdd4a13dd55880f2cc638dde641fb5f8474/src/usdt.cpp#L131C1-L152C2 > > > > > > > > At 2025-08-21 07:00:35, "Andrii Nakryiko" <andrii.nakryiko@gmail.com> wrote: > >On Mon, Aug 18, 2025 at 10:35 AM Yonghong Song <yonghong.song@linux.dev> wrote: > >> > >> > >> > >> On 8/17/25 6:43 AM, 赵佳炜 wrote: > >> > > >> > > >> > > >> > > >> > > >> > > >> > Hi, Yonghong. I've already filed an issue[1] in GCC community. > >> > > >> > > >> > Accroding to the discussion, it's not a gcc bug but may be a systemtap bug. > >> > I don't know how to report this bug to systemtap, but I found that the > >> > libbpf/usdt have the same problem. I've filed an issue in libbpf/usdt repo[2]. > >> > > >> > I also have some ideas about it. I wrote it down in the issue[2] comment. > >> > May be we can discuss there. > >> > > >> > [1]. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121569 > >> > [2]. https://github.com/libbpf/usdt/issues/13 > >> > >> Thanks for filing an issue on gcc and getting some feedback/suggestions > >> from gcc community. > >> > >> Currently, libbpf/usdt does not suport format like '-1@ti(%rip)'. If we do > > > >Exactly, it doesn't. I haven't yet ran into a case where real-world > >applications would use such an argument format, so there was no > >incentive in trying to support it. > > > >Was this issue discovered as part of testing on some real world > >application, or it's mostly through testing on synthetic cases? > > > >> intend to implement this. libbpf/usdt can reject that if 'ti' is a > >> static variable. libbpf can provide some hints about how to make it > >> work (see above [1] and [2]). Then, it would be user's reponsibility to > >> change code so libbpf can support it. > >> > >> > > >> > > >> > > > > >[...]
Ok, I see. I file an issue in libbpf repo to track this discussion. FYI: https://github.com/libbpf/libbpf/issues/918 At 2025-08-22 02:28:31, "Andrii Nakryiko" <andrii.nakryiko@gmail.com> wrote: >On Thu, Aug 21, 2025 at 8:38 AM 赵佳炜 <phoenix500526@163.com> wrote: >> >> >> >> >> >> >> >> >> >> >> In the previous discussion with Yonghong Song, we found that some compiler would generate >> such an arguement format. Although I have never encounter such an issue, I found that the >> global volatile variable could trigger the compiler to generate this argument spec. So I tried to >> solve this problem. I guess this would not be a problem since we have already used STAP_PROBE_ASM >> to reliably generate SIB argument spec. > >Yep, let's hold off on implementing this, as it doesn't seem to be >really necessary in practice. > >> >> BTW, I have another issue to discuss. >> >> Now, bcc framework is not a recommendation for writing bpf program, so bpftrace is now migrating >> from bcc framework to libbpf. Bcc framework provides some relevant APIs for get usdt probe info[1]. >> And I found that there is not similar APIs in libbpf, therefore I have to parse elf file manually. >> >> Could we add some relevant APIs, maybe like `bpf_program__usdt_probe_list`, in libbpf? I can make >> a patch to implement it. WDYT? >> > >I'm not yet convinced this belongs in libbpf, tbh. The process of >discovering USDTs actually involved two separate tasks: discovering >binaries (executable and shared libs) that constitute a process, and >then for each binary discovering which USDTs belong to it. The first >part is pretty clearly out of scope for libbpf. Second one in >principle can be added, but as I said I'm a bit hesitant at this >point, as we don't even have "USDT manager" exposed through public >API. > >So not yet. > >> >> [1]. https://github.com/bpftrace/bpftrace/blob/1cd4bbdd4a13dd55880f2cc638dde641fb5f8474/src/usdt.cpp#L131C1-L152C2 >> >> >> >> >> >> >> >> At 2025-08-21 07:00:35, "Andrii Nakryiko" <andrii.nakryiko@gmail.com> wrote: >> >On Mon, Aug 18, 2025 at 10:35 AM Yonghong Song <yonghong.song@linux.dev> wrote: >> >> >> >> >> >> >> >> On 8/17/25 6:43 AM, 赵佳炜 wrote: >> >> > >> >> > >> >> > >> >> > >> >> > >> >> > >> >> > Hi, Yonghong. I've already filed an issue[1] in GCC community. >> >> > >> >> > >> >> > Accroding to the discussion, it's not a gcc bug but may be a systemtap bug. >> >> > I don't know how to report this bug to systemtap, but I found that the >> >> > libbpf/usdt have the same problem. I've filed an issue in libbpf/usdt repo[2]. >> >> > >> >> > I also have some ideas about it. I wrote it down in the issue[2] comment. >> >> > May be we can discuss there. >> >> > >> >> > [1]. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121569 >> >> > [2]. https://github.com/libbpf/usdt/issues/13 >> >> >> >> Thanks for filing an issue on gcc and getting some feedback/suggestions >> >> from gcc community. >> >> >> >> Currently, libbpf/usdt does not suport format like '-1@ti(%rip)'. If we do >> > >> >Exactly, it doesn't. I haven't yet ran into a case where real-world >> >applications would use such an argument format, so there was no >> >incentive in trying to support it. >> > >> >Was this issue discovered as part of testing on some real world >> >application, or it's mostly through testing on synthetic cases? >> > >> >> intend to implement this. libbpf/usdt can reject that if 'ti' is a >> >> static variable. libbpf can provide some hints about how to make it >> >> work (see above [1] and [2]). Then, it would be user's reponsibility to >> >> change code so libbpf can support it. >> >> >> >> > >> >> > >> >> > >> > >> >[...]
> libbpf/usdt can reject that if 'ti' is a static variable.
But how can we do that? It seems we cannot determine whether a variable is static
during the preprocessing phase.
At 2025-08-19 01:35:04, "Yonghong Song" <yonghong.song@linux.dev> wrote:
>
>
>On 8/17/25 6:43 AM, 赵佳炜 wrote:
>>
>>
>>
>>
>>
>>
>> Hi, Yonghong. I've already filed an issue[1] in GCC community.
>>
>>
>> Accroding to the discussion, it's not a gcc bug but may be a systemtap bug.
>> I don't know how to report this bug to systemtap, but I found that the
>> libbpf/usdt have the same problem. I've filed an issue in libbpf/usdt repo[2].
>>
>> I also have some ideas about it. I wrote it down in the issue[2] comment.
>> May be we can discuss there.
>>
>> [1]. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121569
>> [2]. https://github.com/libbpf/usdt/issues/13
>
>Thanks for filing an issue on gcc and getting some feedback/suggestions
>from gcc community.
>
>Currently, libbpf/usdt does not suport format like '-1@ti(%rip)'. If we do
>intend to implement this. libbpf/usdt can reject that if 'ti' is a
>static variable. libbpf can provide some hints about how to make it
>work (see above [1] and [2]). Then, it would be user's reponsibility to
>change code so libbpf can support it.
>
>>
>>
>>
>> At 2025-08-13 13:24:39, "Yonghong Song" <yonghong.song@linux.dev> wrote:
>>>
>>> On 8/12/25 7:27 PM, 赵佳炜 wrote:
>>>>
>>>>
>>>>
>>>>
>>>> Sure.
>>>>
>>>> The usdt_rip.c source code:
>>>>
>>>> ```C
>>>> // the usdt_rip.c file
>>>> #include <stddef.h>
>>>> #include <stdint.h>
>>>> #include "sdt.h"
>>>>
>>>> static volatile char ti = 0;
>>>>
>>>> int add(int a, int b) {
>>>> return a + b;
>>>> }
>>>> int (*add_ptr)(int, int) = add;
>>>>
>>>> struct st{
>>>> int a;
>>>> char b;
>>>> };
>>>>
>>>> volatile struct st t1 = {.a = 1, .b = 'a'};
>>>>
>>>> static void __always_inline trigger_func() {
>>>> STAP_PROBE4(usdt_rip, rip_global_var, ti, add_ptr, t1.b, ti);
>>>> }
>>>>
>>>> int main() {
>>>> trigger_func();
>>>> return 0;
>>>> }
>>>> ```
>>>>
>>>> The test/usdt_rip.c source code:
>>>>
>>>> ```C
>>>> // The test/usdt_rip.c file
>>>> static volatile char ti = 0;
>>>> ```
>>>>
>>>> The compiler option is `gcc -O2 -g usdt_rip.c test/usdt_rip.c -o usdt_rip`
>>>>
>>>> My compiler version:
>>>> ```bash
>>>> $ gcc -v
>>>> Using built-in specs.
>>>> COLLECT_GCC=gcc
>>>> COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-linux-gnu/13/lto-wrapper
>>>> OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa
>>>> OFFLOAD_TARGET_DEFAULT=1
>>>> Target: x86_64-linux-gnu
>>>> Configured with: ../src/configure -v --with-pkgversion='Ubuntu 13.3.0-6ubuntu2~24.04' --with-bugurl=file:///usr/share/doc/gcc-13/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-13 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/libexec --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-libstdcxx-backtrace --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-13-fG75Ri/gcc-13-13.3.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-13-fG75Ri/gcc-13-13.3.0/debian/tmp-gcn/usr --enable-offload-defaulted --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=2
>>>> Thread model: posix
>>>> Supported LTO compression algorithms: zlib zstd
>>>> gcc version 13.3.0 (Ubuntu 13.3.0-6ubuntu2~24.04)
>>>> ```
>>> Thanks for the code. I compiled with gcc14 compiler and the below is the asm code for 'main' function:
>>>
>>> 0000000000401020 <main>:
>>> 401020: 90 nop
>>> 401021: 31 c0 xor %eax,%eax
>>> 401023: c3 ret
>>> 401024: 66 2e 0f 1f 84 00 00 cs nopw 0x0(%rax,%rax,1)
>>> 40102b: 00 00 00
>>> 40102e: 66 90 xchg %ax,%ax
>>>
>>> stapsdt note:
>>> Displaying notes found in: .note.stapsdt
>>> Owner Data size Description
>>> stapsdt 0x00000066 NT_STAPSDT (SystemTap probe descriptors)
>>> Provider: usdt_rip
>>> Name: rip_global_var
>>> Location: 0x0000000000401020, Base: 0x0000000000402010, Semaphore: 0x0000000000000000
>>> Arguments: -1@ti(%rip) 8@add_ptr(%rip) -1@t1+4(%rip) -1@ti(%rip)
>>>
>>> $ readelf -s usdt_rip | grep ti
>>> 4: 0000000000404019 1 OBJECT LOCAL DEFAULT 24 ti
>>> 14: 000000000040401a 1 OBJECT LOCAL DEFAULT 24 ti
>>>
>>> So yet, it would be hard to find which 'ti' should be used to resolve usdt arguments.
>>>
>>>
>>> I then tried with clang21. The 'main' function:
>>>
>>> 0000000000001140 <main>:
>>> 1140: 0f b6 05 f2 2e 00 00 movzbl 0x2ef2(%rip),%eax # 4039 <ti>
>>> 1147: 48 8b 0d da 2e 00 00 mov 0x2eda(%rip),%rcx # 4028 <add_ptr>
>>> 114e: 0f b6 15 df 2e 00 00 movzbl 0x2edf(%rip),%edx # 4034 <t1+0x4>
>>> 1155: 0f b6 35 dd 2e 00 00 movzbl 0x2edd(%rip),%esi # 4039 <ti>
>>> 115c: 88 44 24 f7 mov %al,-0x9(%rsp)
>>> 1160: 48 89 4c 24 f8 mov %rcx,-0x8(%rsp)
>>> 1165: 88 54 24 f6 mov %dl,-0xa(%rsp)
>>> 1169: 40 88 74 24 f5 mov %sil,-0xb(%rsp)
>>> 116e: 90 nop
>>> 116f: 31 c0 xor %eax,%eax
>>> 1171: c3 ret
>>> 1172: 66 90 xchg %ax,%ax
>>>
>>> For this case, usdt should work properly. The following is related symbol table:
>>>
>>> 74: 0000000000004028 8 OBJECT GLOBAL DEFAULT 26 add_ptr
>>> 64: 0000000000004030 8 OBJECT GLOBAL DEFAULT 26 t1
>>> 50: 0000000000004039 1 OBJECT LOCAL DEFAULT 27 ti <=== for '# 4039 <ti>'.
>>>
>>> And for llvm21, only one 'ti' in the symbol table.
>>>
>>> $ readelf -s usdt_rip | grep ti
>>> 50: 0000000000004039 1 OBJECT LOCAL DEFAULT 27 ti
>>>
>>> The stapsdt note:
>>> Displaying notes found in: .note.stapsdt
>>> Owner Data size Description
>>> stapsdt 0x00000061 NT_STAPSDT (SystemTap probe descriptors)
>>> Provider: usdt_rip
>>> Name: rip_global_var
>>> Location: 0x000000000000116e, Base: 0x0000000000002004, Semaphore: 0x0000000000000000
>>> Arguments: -1@-9(%rsp) 8@-8(%rsp) -1@-10(%rsp) -1@-11(%rsp)
>>>
>>> It looks like clang optimized away the following:
>>> // The test/usdt_rip.c file
>>> static volatile char ti = 0;
>>> but gcc does not. But even if the above 'ti' is preserved for clang,
>>> clang generated code should still be fine since the argument
>>> is -1@-9(%rsp) 8@-8(%rsp) -1@-10(%rsp) -1@-11(%rsp).
>>>
>>> I think you can file a bug for gcc community.
>>>
>>>>
>>>> At 2025-08-13 00:11:45, "Yonghong Song" <yonghong.song@linux.dev> wrote:
>>>>> On 8/12/25 12:02 AM, 赵佳炜 wrote:
>>>>>> Yes, I've tried that but it didn't help. FYI:
>>>>>>
>>>>>> $ readelf -nsr usdt_rip
>>>>>>
>>>>>>
>>>>>> Relocation section '.rela.dyn' at offset 0x530 contains 9 entries:
>>>>>> Offset Info Type Sym. Value Sym. Name + Addend
>>>>>> 000000003df0 000000000008 R_X86_64_RELATIVE 1150
>>>>>> 000000003df8 000000000008 R_X86_64_RELATIVE 1110
>>>>>> 000000004008 000000000008 R_X86_64_RELATIVE 4008
>>>>>> 000000004018 000000000008 R_X86_64_RELATIVE 1160
>>>>>> 000000003fd8 000100000006 R_X86_64_GLOB_DAT 0000000000000000 __libc_start_main@GLIBC_2.34 + 0
>>>>>> 000000003fe0 000200000006 R_X86_64_GLOB_DAT 0000000000000000 _ITM_deregisterTM[...] + 0
>>>>>> 000000003fe8 000300000006 R_X86_64_GLOB_DAT 0000000000000000 __gmon_start__ + 0
>>>>>> 000000003ff0 000400000006 R_X86_64_GLOB_DAT 0000000000000000 _ITM_registerTMCl[...] + 0
>>>>>> 000000003ff8 000500000006 R_X86_64_GLOB_DAT 0000000000000000 __cxa_finalize@GLIBC_2.2.5 + 0
>>>>>>
>>>>>>
>>>>>> Symbol table '.dynsym' contains 6 entries:
>>>>>> Num: Value Size Type Bind Vis Ndx Name
>>>>>> 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
>>>>>> 1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _[...]@GLIBC_2.34 (2)
>>>>>> 2: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterT[...]
>>>>>> 3: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
>>>>>> 4: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMC[...]
>>>>>> 5: 0000000000000000 0 FUNC WEAK DEFAULT UND [...]@GLIBC_2.2.5 (3)
>>>>>>
>>>>>>
>>>>>> Symbol table '.symtab' contains 42 entries:
>>>>>> Num: Value Size Type Bind Vis Ndx Name
>>>>>> 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
>>>>>> 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS Scrt1.o
>>>>>> 2: 000000000000038c 32 OBJECT LOCAL DEFAULT 4 __abi_tag
>>>>>> 3: 0000000000000000 0 FILE LOCAL DEFAULT ABS usdt_rip.c
>>>>>> 4: 0000000000004021 1 OBJECT LOCAL DEFAULT 25 ti
>>>>>> 5: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
>>>>>> 6: 00000000000010a0 0 FUNC LOCAL DEFAULT 14 deregister_tm_clones
>>>>>> 7: 00000000000010d0 0 FUNC LOCAL DEFAULT 14 register_tm_clones
>>>>>> 8: 0000000000001110 0 FUNC LOCAL DEFAULT 14 __do_global_dtors_aux
>>>>>> 9: 0000000000004020 1 OBJECT LOCAL DEFAULT 25 completed.0
>>>>>> 10: 0000000000003df8 0 OBJECT LOCAL DEFAULT 21 __do_global_dtor[...]
>>>>>> 11: 0000000000001150 0 FUNC LOCAL DEFAULT 14 frame_dummy
>>>>>> 12: 0000000000003df0 0 OBJECT LOCAL DEFAULT 20 __frame_dummy_in[...]
>>>>>> 13: 0000000000000000 0 FILE LOCAL DEFAULT ABS damo.c
>>>>>> 14: 0000000000004022 1 OBJECT LOCAL DEFAULT 25 ti
>>>>>> 15: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
>>>>>> 16: 00000000000020d8 0 OBJECT LOCAL DEFAULT 19 __FRAME_END__
>>>>>> 17: 0000000000000000 0 FILE LOCAL DEFAULT ABS
>>>>>> 18: 0000000000003e00 0 OBJECT LOCAL DEFAULT 22 _DYNAMIC
>>>>>> 19: 0000000000002008 0 NOTYPE LOCAL DEFAULT 18 __GNU_EH_FRAME_HDR
>>>>>> 20: 0000000000003fc0 0 OBJECT LOCAL DEFAULT 23 _GLOBAL_OFFSET_TABLE_
>>>>>> 21: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_mai[...]
>>>>>> 22: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterT[...]
>>>>>> 23: 0000000000004000 0 NOTYPE WEAK DEFAULT 24 data_start
>>>>>> 24: 0000000000001160 8 FUNC GLOBAL DEFAULT 14 add
>>>>>> 25: 0000000000004020 0 NOTYPE GLOBAL DEFAULT 24 _edata
>>>>>> 26: 0000000000002004 1 NOTYPE WEAK HIDDEN 17 _.stapsdt.base
>>>>>> 27: 0000000000004010 8 OBJECT GLOBAL DEFAULT 24 t1
>>>>>> 28: 0000000000001168 0 FUNC GLOBAL HIDDEN 15 _fini
>>>>>> 29: 0000000000004000 0 NOTYPE GLOBAL DEFAULT 24 __data_start
>>>>>> 30: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
>>>>>> 31: 0000000000004008 0 OBJECT GLOBAL HIDDEN 24 __dso_handle
>>>>>> 32: 0000000000002000 4 OBJECT GLOBAL DEFAULT 16 _IO_stdin_used
>>>>>> 33: 0000000000004028 0 NOTYPE GLOBAL DEFAULT 25 _end
>>>>>> 34: 0000000000001070 38 FUNC GLOBAL DEFAULT 14 _start
>>>>>> 35: 0000000000004020 0 NOTYPE GLOBAL DEFAULT 25 __bss_start
>>>>>> 36: 0000000000001040 48 FUNC GLOBAL DEFAULT 14 main
>>>>>> 37: 0000000000004018 8 OBJECT GLOBAL DEFAULT 24 add_ptr
>>>>>> 38: 0000000000004020 0 OBJECT GLOBAL HIDDEN 24 __TMC_END__
>>>>>> 39: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMC[...]
>>>>>> 40: 0000000000000000 0 FUNC WEAK DEFAULT UND __cxa_finalize@G[...]
>>>>>> 41: 0000000000001000 0 FUNC GLOBAL HIDDEN 11 _init
>>>>>>
>>>>>>
>>>>>> Displaying notes found in: .note.gnu.property
>>>>>> Owner Data size Description
>>>>>> GNU 0x00000020 NT_GNU_PROPERTY_TYPE_0
>>>>>> Properties: x86 feature: IBT, SHSTK
>>>>>> x86 ISA needed: x86-64-baseline
>>>>>>
>>>>>>
>>>>>> Displaying notes found in: .note.gnu.build-id
>>>>>> Owner Data size Description
>>>>>> GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring)
>>>>>> Build ID: eb615daa575687cc44edc1d339b27890c12c27f1
>>>>>>
>>>>>>
>>>>>> Displaying notes found in: .note.ABI-tag
>>>>>> Owner Data size Description
>>>>>> GNU 0x00000010 NT_GNU_ABI_TAG (ABI version tag)
>>>>>> OS: Linux, ABI: 3.2.0
>>>>>>
>>>>>>
>>>>>> Displaying notes found in: .note.stapsdt
>>>>>> Owner Data size Description
>>>>>> stapsdt 0x00000066 NT_STAPSDT (SystemTap probe descriptors)
>>>>>> Provider: usdt_rip
>>>>>> Name: rip_global_var
>>>>>> Location: 0x0000000000001058, Base: 0x0000000000002004, Semaphore: 0x0000000000000000
>>>>>> Arguments: -1@ti(%rip) 8@add_ptr(%rip) -1@4+t1(%rip) -1@ti(%rip)
>>>>> Could you share the complete source codes and compiler options which
>>>>> reproduce the above result?
>>>>>
>>>>>>
>>>>>> At 2025-08-12 13:06:40, "Yonghong Song" <yonghong.song@linux.dev> wrote:
>>>>>>> On 8/10/25 1:55 AM, 赵佳炜 wrote:
>>>>>>>> Hi Yonghong,
>>>>>>>>
>>>>>>>> I found another issue where symbols can be duplicated, and I’m not sure how to tell them apart.
>>>>>>>>
>>>>>>>> For example, I created two C files named usdt_rip.c and hello.c. Both define their own static ti variables, like:`static volatile char ti = 0;`.
>>>>>>>>
>>>>>>>> After compiling, I obtained an ELF file usdt_rip whose .symtab contains the following entries:
>>>>>>>>
>>>>>>>> $ readelf -s usdt_rip
>>>>>>>>
>>>>>>>> Symbol table '.symtab' contains 42 entries:
>>>>>>>> Num: Value Size Type Bind Vis Ndx Name
>>>>>>>> 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
>>>>>>>> 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS Scrt1.o
>>>>>>>> 2: 000000000000038c 32 OBJECT LOCAL DEFAULT 4 __abi_tag
>>>>>>>> 3: 0000000000000000 0 FILE LOCAL DEFAULT ABS usdt_rip.c
>>>>>>>> 4: 0000000000004021 1 OBJECT LOCAL DEFAULT 25 ti
>>>>>>>> 5: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
>>>>>>>> 6: 00000000000010a0 0 FUNC LOCAL DEFAULT 14 deregister_tm_clones
>>>>>>>> 7: 00000000000010d0 0 FUNC LOCAL DEFAULT 14 register_tm_clones
>>>>>>>> 8: 0000000000001110 0 FUNC LOCAL DEFAULT 14 __do_global_dtors_aux
>>>>>>>> 9: 0000000000004020 1 OBJECT LOCAL DEFAULT 25 completed.0
>>>>>>>> 10: 0000000000003df8 0 OBJECT LOCAL DEFAULT 21 __do_global_dtor[...]
>>>>>>>> 11: 0000000000001150 0 FUNC LOCAL DEFAULT 14 frame_dummy
>>>>>>>> 12: 0000000000003df0 0 OBJECT LOCAL DEFAULT 20 __frame_dummy_in[...]
>>>>>>>> 13: 0000000000000000 0 FILE LOCAL DEFAULT ABS damo.c
>>>>>>>> 14: 0000000000004022 1 OBJECT LOCAL DEFAULT 25 ti
>>>>>>>> 15: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
>>>>>>>> 16: 00000000000020d8 0 OBJECT LOCAL DEFAULT 19 __FRAME_END__
>>>>>>>>
>>>>>>>>
>>>>>>>> As you can see, there are two ti variables in the .symtab section. Their values are very close, making them hard to distinguish.
>>>>>>>>
>>>>>>>> I’m unsure how to handle this situation. Do you have any suggestions?
>>>>>>> Did you check relocations? Relocaitons should be able to point exact which symbol.
>>>>>>>
>>>>>>>> Thanks,
>>>>>>>> Jiawei Zhao
>>>>>>> [...]
>
On 8/19/25 2:50 AM, 赵佳炜 wrote:
>
>
>
>
>> libbpf/usdt can reject that if 'ti' is a static variable.
> But how can we do that? It seems we cannot determine whether a variable is static
> during the preprocessing phase.
What I mean is after compilation and during libbpf processing usdt requests.
At that time, libbpf can inspect the application binary and all usdt's.
My above statement
libbpf/usdt can reject that if 'ti' is a static variable.
is not not precise, it should be
libbpf/usdt can reject if there are ambiguity and provides some hints.
If the preprocessing phase means compilation, yes, we cannot do anything.
>
>
>
>
>
> At 2025-08-19 01:35:04, "Yonghong Song" <yonghong.song@linux.dev> wrote:
>>
>> On 8/17/25 6:43 AM, 赵佳炜 wrote:
>>>
>>>
>>>
>>>
>>>
>>> Hi, Yonghong. I've already filed an issue[1] in GCC community.
>>>
>>>
>>> Accroding to the discussion, it's not a gcc bug but may be a systemtap bug.
>>> I don't know how to report this bug to systemtap, but I found that the
>>> libbpf/usdt have the same problem. I've filed an issue in libbpf/usdt repo[2].
>>>
>>> I also have some ideas about it. I wrote it down in the issue[2] comment.
>>> May be we can discuss there.
>>>
>>> [1]. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121569
>>> [2]. https://github.com/libbpf/usdt/issues/13
>> Thanks for filing an issue on gcc and getting some feedback/suggestions
> >from gcc community.
>> Currently, libbpf/usdt does not suport format like '-1@ti(%rip)'. If we do
>> intend to implement this. libbpf/usdt can reject that if 'ti' is a
>> static variable. libbpf can provide some hints about how to make it
>> work (see above [1] and [2]). Then, it would be user's reponsibility to
>> change code so libbpf can support it.
>>
>>>
>>>
>>> At 2025-08-13 13:24:39, "Yonghong Song" <yonghong.song@linux.dev> wrote:
>>>> On 8/12/25 7:27 PM, 赵佳炜 wrote:
>>>>>
>>>>>
>>>>>
>>>>> Sure.
>>>>>
>>>>> The usdt_rip.c source code:
>>>>>
>>>>> ```C
>>>>> // the usdt_rip.c file
>>>>> #include <stddef.h>
>>>>> #include <stdint.h>
>>>>> #include "sdt.h"
>>>>>
>>>>> static volatile char ti = 0;
>>>>>
>>>>> int add(int a, int b) {
>>>>> return a + b;
>>>>> }
>>>>> int (*add_ptr)(int, int) = add;
>>>>>
>>>>> struct st{
>>>>> int a;
>>>>> char b;
>>>>> };
>>>>>
>>>>> volatile struct st t1 = {.a = 1, .b = 'a'};
>>>>>
>>>>> static void __always_inline trigger_func() {
>>>>> STAP_PROBE4(usdt_rip, rip_global_var, ti, add_ptr, t1.b, ti);
>>>>> }
>>>>>
>>>>> int main() {
>>>>> trigger_func();
>>>>> return 0;
>>>>> }
>>>>> ```
>>>>>
>>>>> The test/usdt_rip.c source code:
>>>>>
>>>>> ```C
>>>>> // The test/usdt_rip.c file
>>>>> static volatile char ti = 0;
>>>>> ```
>>>>>
>>>>> The compiler option is `gcc -O2 -g usdt_rip.c test/usdt_rip.c -o usdt_rip`
>>>>>
>>>>> My compiler version:
>>>>> ```bash
>>>>> $ gcc -v
>>>>> Using built-in specs.
>>>>> COLLECT_GCC=gcc
>>>>> COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-linux-gnu/13/lto-wrapper
>>>>> OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa
>>>>> OFFLOAD_TARGET_DEFAULT=1
>>>>> Target: x86_64-linux-gnu
>>>>> Configured with: ../src/configure -v --with-pkgversion='Ubuntu 13.3.0-6ubuntu2~24.04' --with-bugurl=file:///usr/share/doc/gcc-13/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-13 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/libexec --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-libstdcxx-backtrace --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-13-fG75Ri/gcc-13-13.3.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-13-fG75Ri/gcc-13-13.3.0/debian/tmp-gcn/usr --enable-offload-defaulted --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=2
>>>>> Thread model: posix
>>>>> Supported LTO compression algorithms: zlib zstd
>>>>> gcc version 13.3.0 (Ubuntu 13.3.0-6ubuntu2~24.04)
>>>>> ```
>>>> Thanks for the code. I compiled with gcc14 compiler and the below is the asm code for 'main' function:
>>>>
>>>> 0000000000401020 <main>:
>>>> 401020: 90 nop
>>>> 401021: 31 c0 xor %eax,%eax
>>>> 401023: c3 ret
>>>> 401024: 66 2e 0f 1f 84 00 00 cs nopw 0x0(%rax,%rax,1)
>>>> 40102b: 00 00 00
>>>> 40102e: 66 90 xchg %ax,%ax
>>>>
>>>> stapsdt note:
>>>> Displaying notes found in: .note.stapsdt
>>>> Owner Data size Description
>>>> stapsdt 0x00000066 NT_STAPSDT (SystemTap probe descriptors)
>>>> Provider: usdt_rip
>>>> Name: rip_global_var
>>>> Location: 0x0000000000401020, Base: 0x0000000000402010, Semaphore: 0x0000000000000000
>>>> Arguments: -1@ti(%rip) 8@add_ptr(%rip) -1@t1+4(%rip) -1@ti(%rip)
>>>>
>>>> $ readelf -s usdt_rip | grep ti
>>>> 4: 0000000000404019 1 OBJECT LOCAL DEFAULT 24 ti
>>>> 14: 000000000040401a 1 OBJECT LOCAL DEFAULT 24 ti
>>>>
>>>> So yet, it would be hard to find which 'ti' should be used to resolve usdt arguments.
>>>>
>>>>
>>>> I then tried with clang21. The 'main' function:
>>>>
>>>> 0000000000001140 <main>:
>>>> 1140: 0f b6 05 f2 2e 00 00 movzbl 0x2ef2(%rip),%eax # 4039 <ti>
>>>> 1147: 48 8b 0d da 2e 00 00 mov 0x2eda(%rip),%rcx # 4028 <add_ptr>
>>>> 114e: 0f b6 15 df 2e 00 00 movzbl 0x2edf(%rip),%edx # 4034 <t1+0x4>
>>>> 1155: 0f b6 35 dd 2e 00 00 movzbl 0x2edd(%rip),%esi # 4039 <ti>
>>>> 115c: 88 44 24 f7 mov %al,-0x9(%rsp)
>>>> 1160: 48 89 4c 24 f8 mov %rcx,-0x8(%rsp)
>>>> 1165: 88 54 24 f6 mov %dl,-0xa(%rsp)
>>>> 1169: 40 88 74 24 f5 mov %sil,-0xb(%rsp)
>>>> 116e: 90 nop
>>>> 116f: 31 c0 xor %eax,%eax
>>>> 1171: c3 ret
>>>> 1172: 66 90 xchg %ax,%ax
>>>>
>>>> For this case, usdt should work properly. The following is related symbol table:
>>>>
>>>> 74: 0000000000004028 8 OBJECT GLOBAL DEFAULT 26 add_ptr
>>>> 64: 0000000000004030 8 OBJECT GLOBAL DEFAULT 26 t1
>>>> 50: 0000000000004039 1 OBJECT LOCAL DEFAULT 27 ti <=== for '# 4039 <ti>'.
>>>>
>>>> And for llvm21, only one 'ti' in the symbol table.
>>>>
>>>> $ readelf -s usdt_rip | grep ti
>>>> 50: 0000000000004039 1 OBJECT LOCAL DEFAULT 27 ti
>>>>
>>>> The stapsdt note:
>>>> Displaying notes found in: .note.stapsdt
>>>> Owner Data size Description
>>>> stapsdt 0x00000061 NT_STAPSDT (SystemTap probe descriptors)
>>>> Provider: usdt_rip
>>>> Name: rip_global_var
>>>> Location: 0x000000000000116e, Base: 0x0000000000002004, Semaphore: 0x0000000000000000
>>>> Arguments: -1@-9(%rsp) 8@-8(%rsp) -1@-10(%rsp) -1@-11(%rsp)
>>>>
>>>> It looks like clang optimized away the following:
>>>> // The test/usdt_rip.c file
>>>> static volatile char ti = 0;
>>>> but gcc does not. But even if the above 'ti' is preserved for clang,
>>>> clang generated code should still be fine since the argument
>>>> is -1@-9(%rsp) 8@-8(%rsp) -1@-10(%rsp) -1@-11(%rsp).
>>>>
>>>> I think you can file a bug for gcc community.
>>>>
>>>>> At 2025-08-13 00:11:45, "Yonghong Song" <yonghong.song@linux.dev> wrote:
>>>>>> On 8/12/25 12:02 AM, 赵佳炜 wrote:
>>>>>>> Yes, I've tried that but it didn't help. FYI:
>>>>>>>
>>>>>>> $ readelf -nsr usdt_rip
>>>>>>>
>>>>>>>
>>>>>>> Relocation section '.rela.dyn' at offset 0x530 contains 9 entries:
>>>>>>> Offset Info Type Sym. Value Sym. Name + Addend
>>>>>>> 000000003df0 000000000008 R_X86_64_RELATIVE 1150
>>>>>>> 000000003df8 000000000008 R_X86_64_RELATIVE 1110
>>>>>>> 000000004008 000000000008 R_X86_64_RELATIVE 4008
>>>>>>> 000000004018 000000000008 R_X86_64_RELATIVE 1160
>>>>>>> 000000003fd8 000100000006 R_X86_64_GLOB_DAT 0000000000000000 __libc_start_main@GLIBC_2.34 + 0
>>>>>>> 000000003fe0 000200000006 R_X86_64_GLOB_DAT 0000000000000000 _ITM_deregisterTM[...] + 0
>>>>>>> 000000003fe8 000300000006 R_X86_64_GLOB_DAT 0000000000000000 __gmon_start__ + 0
>>>>>>> 000000003ff0 000400000006 R_X86_64_GLOB_DAT 0000000000000000 _ITM_registerTMCl[...] + 0
>>>>>>> 000000003ff8 000500000006 R_X86_64_GLOB_DAT 0000000000000000 __cxa_finalize@GLIBC_2.2.5 + 0
>>>>>>>
>>>>>>>
>>>>>>> Symbol table '.dynsym' contains 6 entries:
>>>>>>> Num: Value Size Type Bind Vis Ndx Name
>>>>>>> 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
>>>>>>> 1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _[...]@GLIBC_2.34 (2)
>>>>>>> 2: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterT[...]
>>>>>>> 3: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
>>>>>>> 4: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMC[...]
>>>>>>> 5: 0000000000000000 0 FUNC WEAK DEFAULT UND [...]@GLIBC_2.2.5 (3)
>>>>>>>
>>>>>>>
>>>>>>> Symbol table '.symtab' contains 42 entries:
>>>>>>> Num: Value Size Type Bind Vis Ndx Name
>>>>>>> 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
>>>>>>> 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS Scrt1.o
>>>>>>> 2: 000000000000038c 32 OBJECT LOCAL DEFAULT 4 __abi_tag
>>>>>>> 3: 0000000000000000 0 FILE LOCAL DEFAULT ABS usdt_rip.c
>>>>>>> 4: 0000000000004021 1 OBJECT LOCAL DEFAULT 25 ti
>>>>>>> 5: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
>>>>>>> 6: 00000000000010a0 0 FUNC LOCAL DEFAULT 14 deregister_tm_clones
>>>>>>> 7: 00000000000010d0 0 FUNC LOCAL DEFAULT 14 register_tm_clones
>>>>>>> 8: 0000000000001110 0 FUNC LOCAL DEFAULT 14 __do_global_dtors_aux
>>>>>>> 9: 0000000000004020 1 OBJECT LOCAL DEFAULT 25 completed.0
>>>>>>> 10: 0000000000003df8 0 OBJECT LOCAL DEFAULT 21 __do_global_dtor[...]
>>>>>>> 11: 0000000000001150 0 FUNC LOCAL DEFAULT 14 frame_dummy
>>>>>>> 12: 0000000000003df0 0 OBJECT LOCAL DEFAULT 20 __frame_dummy_in[...]
>>>>>>> 13: 0000000000000000 0 FILE LOCAL DEFAULT ABS damo.c
>>>>>>> 14: 0000000000004022 1 OBJECT LOCAL DEFAULT 25 ti
>>>>>>> 15: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
>>>>>>> 16: 00000000000020d8 0 OBJECT LOCAL DEFAULT 19 __FRAME_END__
>>>>>>> 17: 0000000000000000 0 FILE LOCAL DEFAULT ABS
>>>>>>> 18: 0000000000003e00 0 OBJECT LOCAL DEFAULT 22 _DYNAMIC
>>>>>>> 19: 0000000000002008 0 NOTYPE LOCAL DEFAULT 18 __GNU_EH_FRAME_HDR
>>>>>>> 20: 0000000000003fc0 0 OBJECT LOCAL DEFAULT 23 _GLOBAL_OFFSET_TABLE_
>>>>>>> 21: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_mai[...]
>>>>>>> 22: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterT[...]
>>>>>>> 23: 0000000000004000 0 NOTYPE WEAK DEFAULT 24 data_start
>>>>>>> 24: 0000000000001160 8 FUNC GLOBAL DEFAULT 14 add
>>>>>>> 25: 0000000000004020 0 NOTYPE GLOBAL DEFAULT 24 _edata
>>>>>>> 26: 0000000000002004 1 NOTYPE WEAK HIDDEN 17 _.stapsdt.base
>>>>>>> 27: 0000000000004010 8 OBJECT GLOBAL DEFAULT 24 t1
>>>>>>> 28: 0000000000001168 0 FUNC GLOBAL HIDDEN 15 _fini
>>>>>>> 29: 0000000000004000 0 NOTYPE GLOBAL DEFAULT 24 __data_start
>>>>>>> 30: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
>>>>>>> 31: 0000000000004008 0 OBJECT GLOBAL HIDDEN 24 __dso_handle
>>>>>>> 32: 0000000000002000 4 OBJECT GLOBAL DEFAULT 16 _IO_stdin_used
>>>>>>> 33: 0000000000004028 0 NOTYPE GLOBAL DEFAULT 25 _end
>>>>>>> 34: 0000000000001070 38 FUNC GLOBAL DEFAULT 14 _start
>>>>>>> 35: 0000000000004020 0 NOTYPE GLOBAL DEFAULT 25 __bss_start
>>>>>>> 36: 0000000000001040 48 FUNC GLOBAL DEFAULT 14 main
>>>>>>> 37: 0000000000004018 8 OBJECT GLOBAL DEFAULT 24 add_ptr
>>>>>>> 38: 0000000000004020 0 OBJECT GLOBAL HIDDEN 24 __TMC_END__
>>>>>>> 39: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMC[...]
>>>>>>> 40: 0000000000000000 0 FUNC WEAK DEFAULT UND __cxa_finalize@G[...]
>>>>>>> 41: 0000000000001000 0 FUNC GLOBAL HIDDEN 11 _init
>>>>>>>
>>>>>>>
>>>>>>> Displaying notes found in: .note.gnu.property
>>>>>>> Owner Data size Description
>>>>>>> GNU 0x00000020 NT_GNU_PROPERTY_TYPE_0
>>>>>>> Properties: x86 feature: IBT, SHSTK
>>>>>>> x86 ISA needed: x86-64-baseline
>>>>>>>
>>>>>>>
>>>>>>> Displaying notes found in: .note.gnu.build-id
>>>>>>> Owner Data size Description
>>>>>>> GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring)
>>>>>>> Build ID: eb615daa575687cc44edc1d339b27890c12c27f1
>>>>>>>
>>>>>>>
>>>>>>> Displaying notes found in: .note.ABI-tag
>>>>>>> Owner Data size Description
>>>>>>> GNU 0x00000010 NT_GNU_ABI_TAG (ABI version tag)
>>>>>>> OS: Linux, ABI: 3.2.0
>>>>>>>
>>>>>>>
>>>>>>> Displaying notes found in: .note.stapsdt
>>>>>>> Owner Data size Description
>>>>>>> stapsdt 0x00000066 NT_STAPSDT (SystemTap probe descriptors)
>>>>>>> Provider: usdt_rip
>>>>>>> Name: rip_global_var
>>>>>>> Location: 0x0000000000001058, Base: 0x0000000000002004, Semaphore: 0x0000000000000000
>>>>>>> Arguments: -1@ti(%rip) 8@add_ptr(%rip) -1@4+t1(%rip) -1@ti(%rip)
>>>>>> Could you share the complete source codes and compiler options which
>>>>>> reproduce the above result?
>>>>>>
>>>>>>> At 2025-08-12 13:06:40, "Yonghong Song" <yonghong.song@linux.dev> wrote:
>>>>>>>> On 8/10/25 1:55 AM, 赵佳炜 wrote:
>>>>>>>>> Hi Yonghong,
>>>>>>>>>
>>>>>>>>> I found another issue where symbols can be duplicated, and I’m not sure how to tell them apart.
>>>>>>>>>
>>>>>>>>> For example, I created two C files named usdt_rip.c and hello.c. Both define their own static ti variables, like:`static volatile char ti = 0;`.
>>>>>>>>>
>>>>>>>>> After compiling, I obtained an ELF file usdt_rip whose .symtab contains the following entries:
>>>>>>>>>
>>>>>>>>> $ readelf -s usdt_rip
>>>>>>>>>
>>>>>>>>> Symbol table '.symtab' contains 42 entries:
>>>>>>>>> Num: Value Size Type Bind Vis Ndx Name
>>>>>>>>> 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
>>>>>>>>> 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS Scrt1.o
>>>>>>>>> 2: 000000000000038c 32 OBJECT LOCAL DEFAULT 4 __abi_tag
>>>>>>>>> 3: 0000000000000000 0 FILE LOCAL DEFAULT ABS usdt_rip.c
>>>>>>>>> 4: 0000000000004021 1 OBJECT LOCAL DEFAULT 25 ti
>>>>>>>>> 5: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
>>>>>>>>> 6: 00000000000010a0 0 FUNC LOCAL DEFAULT 14 deregister_tm_clones
>>>>>>>>> 7: 00000000000010d0 0 FUNC LOCAL DEFAULT 14 register_tm_clones
>>>>>>>>> 8: 0000000000001110 0 FUNC LOCAL DEFAULT 14 __do_global_dtors_aux
>>>>>>>>> 9: 0000000000004020 1 OBJECT LOCAL DEFAULT 25 completed.0
>>>>>>>>> 10: 0000000000003df8 0 OBJECT LOCAL DEFAULT 21 __do_global_dtor[...]
>>>>>>>>> 11: 0000000000001150 0 FUNC LOCAL DEFAULT 14 frame_dummy
>>>>>>>>> 12: 0000000000003df0 0 OBJECT LOCAL DEFAULT 20 __frame_dummy_in[...]
>>>>>>>>> 13: 0000000000000000 0 FILE LOCAL DEFAULT ABS damo.c
>>>>>>>>> 14: 0000000000004022 1 OBJECT LOCAL DEFAULT 25 ti
>>>>>>>>> 15: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
>>>>>>>>> 16: 00000000000020d8 0 OBJECT LOCAL DEFAULT 19 __FRAME_END__
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> As you can see, there are two ti variables in the .symtab section. Their values are very close, making them hard to distinguish.
>>>>>>>>>
>>>>>>>>> I’m unsure how to handle this situation. Do you have any suggestions?
>>>>>>>> Did you check relocations? Relocaitons should be able to point exact which symbol.
>>>>>>>>
>>>>>>>>> Thanks,
>>>>>>>>> Jiawei Zhao
>>>>>>>> [...]
Thanks a lot! I'll file a bug for gcc community.
At 2025-08-13 13:24:39, "Yonghong Song" <yonghong.song@linux.dev> wrote:
>
>
>On 8/12/25 7:27 PM, 赵佳炜 wrote:
>>
>>
>>
>>
>>
>> Sure.
>>
>> The usdt_rip.c source code:
>>
>> ```C
>> // the usdt_rip.c file
>> #include <stddef.h>
>> #include <stdint.h>
>> #include "sdt.h"
>>
>> static volatile char ti = 0;
>>
>> int add(int a, int b) {
>> return a + b;
>> }
>> int (*add_ptr)(int, int) = add;
>>
>> struct st{
>> int a;
>> char b;
>> };
>>
>> volatile struct st t1 = {.a = 1, .b = 'a'};
>>
>> static void __always_inline trigger_func() {
>> STAP_PROBE4(usdt_rip, rip_global_var, ti, add_ptr, t1.b, ti);
>> }
>>
>> int main() {
>> trigger_func();
>> return 0;
>> }
>> ```
>>
>> The test/usdt_rip.c source code:
>>
>> ```C
>> // The test/usdt_rip.c file
>> static volatile char ti = 0;
>> ```
>>
>> The compiler option is `gcc -O2 -g usdt_rip.c test/usdt_rip.c -o usdt_rip`
>>
>> My compiler version:
>> ```bash
>> $ gcc -v
>> Using built-in specs.
>> COLLECT_GCC=gcc
>> COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-linux-gnu/13/lto-wrapper
>> OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa
>> OFFLOAD_TARGET_DEFAULT=1
>> Target: x86_64-linux-gnu
>> Configured with: ../src/configure -v --with-pkgversion='Ubuntu 13.3.0-6ubuntu2~24.04' --with-bugurl=file:///usr/share/doc/gcc-13/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-13 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/libexec --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-libstdcxx-backtrace --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-13-fG75Ri/gcc-13-13.3.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-13-fG75Ri/gcc-13-13.3.0/debian/tmp-gcn/usr --enable-offload-defaulted --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=2
>> Thread model: posix
>> Supported LTO compression algorithms: zlib zstd
>> gcc version 13.3.0 (Ubuntu 13.3.0-6ubuntu2~24.04)
>> ```
>
>Thanks for the code. I compiled with gcc14 compiler and the below is the asm code for 'main' function:
>
>0000000000401020 <main>:
> 401020: 90 nop
> 401021: 31 c0 xor %eax,%eax
> 401023: c3 ret
> 401024: 66 2e 0f 1f 84 00 00 cs nopw 0x0(%rax,%rax,1)
> 40102b: 00 00 00
> 40102e: 66 90 xchg %ax,%ax
>
>stapsdt note:
> Displaying notes found in: .note.stapsdt
> Owner Data size Description
> stapsdt 0x00000066 NT_STAPSDT (SystemTap probe descriptors)
> Provider: usdt_rip
> Name: rip_global_var
> Location: 0x0000000000401020, Base: 0x0000000000402010, Semaphore: 0x0000000000000000
> Arguments: -1@ti(%rip) 8@add_ptr(%rip) -1@t1+4(%rip) -1@ti(%rip)
>
>$ readelf -s usdt_rip | grep ti
> 4: 0000000000404019 1 OBJECT LOCAL DEFAULT 24 ti
> 14: 000000000040401a 1 OBJECT LOCAL DEFAULT 24 ti
>
>So yet, it would be hard to find which 'ti' should be used to resolve usdt arguments.
>
>
>I then tried with clang21. The 'main' function:
>
>0000000000001140 <main>:
> 1140: 0f b6 05 f2 2e 00 00 movzbl 0x2ef2(%rip),%eax # 4039 <ti>
> 1147: 48 8b 0d da 2e 00 00 mov 0x2eda(%rip),%rcx # 4028 <add_ptr>
> 114e: 0f b6 15 df 2e 00 00 movzbl 0x2edf(%rip),%edx # 4034 <t1+0x4>
> 1155: 0f b6 35 dd 2e 00 00 movzbl 0x2edd(%rip),%esi # 4039 <ti>
> 115c: 88 44 24 f7 mov %al,-0x9(%rsp)
> 1160: 48 89 4c 24 f8 mov %rcx,-0x8(%rsp)
> 1165: 88 54 24 f6 mov %dl,-0xa(%rsp)
> 1169: 40 88 74 24 f5 mov %sil,-0xb(%rsp)
> 116e: 90 nop
> 116f: 31 c0 xor %eax,%eax
> 1171: c3 ret
> 1172: 66 90 xchg %ax,%ax
>
>For this case, usdt should work properly. The following is related symbol table:
>
> 74: 0000000000004028 8 OBJECT GLOBAL DEFAULT 26 add_ptr
> 64: 0000000000004030 8 OBJECT GLOBAL DEFAULT 26 t1
> 50: 0000000000004039 1 OBJECT LOCAL DEFAULT 27 ti <=== for '# 4039 <ti>'.
>
>And for llvm21, only one 'ti' in the symbol table.
>
>$ readelf -s usdt_rip | grep ti
> 50: 0000000000004039 1 OBJECT LOCAL DEFAULT 27 ti
>
>The stapsdt note:
> Displaying notes found in: .note.stapsdt
> Owner Data size Description
> stapsdt 0x00000061 NT_STAPSDT (SystemTap probe descriptors)
> Provider: usdt_rip
> Name: rip_global_var
> Location: 0x000000000000116e, Base: 0x0000000000002004, Semaphore: 0x0000000000000000
> Arguments: -1@-9(%rsp) 8@-8(%rsp) -1@-10(%rsp) -1@-11(%rsp)
>
>It looks like clang optimized away the following:
> // The test/usdt_rip.c file
> static volatile char ti = 0;
>but gcc does not. But even if the above 'ti' is preserved for clang,
>clang generated code should still be fine since the argument
>is -1@-9(%rsp) 8@-8(%rsp) -1@-10(%rsp) -1@-11(%rsp).
>
>I think you can file a bug for gcc community.
>
>>
>>
>> At 2025-08-13 00:11:45, "Yonghong Song" <yonghong.song@linux.dev> wrote:
>>>
>>> On 8/12/25 12:02 AM, 赵佳炜 wrote:
>>>> Yes, I've tried that but it didn't help. FYI:
>>>>
>>>> $ readelf -nsr usdt_rip
>>>>
>>>>
>>>> Relocation section '.rela.dyn' at offset 0x530 contains 9 entries:
>>>> Offset Info Type Sym. Value Sym. Name + Addend
>>>> 000000003df0 000000000008 R_X86_64_RELATIVE 1150
>>>> 000000003df8 000000000008 R_X86_64_RELATIVE 1110
>>>> 000000004008 000000000008 R_X86_64_RELATIVE 4008
>>>> 000000004018 000000000008 R_X86_64_RELATIVE 1160
>>>> 000000003fd8 000100000006 R_X86_64_GLOB_DAT 0000000000000000 __libc_start_main@GLIBC_2.34 + 0
>>>> 000000003fe0 000200000006 R_X86_64_GLOB_DAT 0000000000000000 _ITM_deregisterTM[...] + 0
>>>> 000000003fe8 000300000006 R_X86_64_GLOB_DAT 0000000000000000 __gmon_start__ + 0
>>>> 000000003ff0 000400000006 R_X86_64_GLOB_DAT 0000000000000000 _ITM_registerTMCl[...] + 0
>>>> 000000003ff8 000500000006 R_X86_64_GLOB_DAT 0000000000000000 __cxa_finalize@GLIBC_2.2.5 + 0
>>>>
>>>>
>>>> Symbol table '.dynsym' contains 6 entries:
>>>> Num: Value Size Type Bind Vis Ndx Name
>>>> 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
>>>> 1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _[...]@GLIBC_2.34 (2)
>>>> 2: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterT[...]
>>>> 3: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
>>>> 4: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMC[...]
>>>> 5: 0000000000000000 0 FUNC WEAK DEFAULT UND [...]@GLIBC_2.2.5 (3)
>>>>
>>>>
>>>> Symbol table '.symtab' contains 42 entries:
>>>> Num: Value Size Type Bind Vis Ndx Name
>>>> 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
>>>> 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS Scrt1.o
>>>> 2: 000000000000038c 32 OBJECT LOCAL DEFAULT 4 __abi_tag
>>>> 3: 0000000000000000 0 FILE LOCAL DEFAULT ABS usdt_rip.c
>>>> 4: 0000000000004021 1 OBJECT LOCAL DEFAULT 25 ti
>>>> 5: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
>>>> 6: 00000000000010a0 0 FUNC LOCAL DEFAULT 14 deregister_tm_clones
>>>> 7: 00000000000010d0 0 FUNC LOCAL DEFAULT 14 register_tm_clones
>>>> 8: 0000000000001110 0 FUNC LOCAL DEFAULT 14 __do_global_dtors_aux
>>>> 9: 0000000000004020 1 OBJECT LOCAL DEFAULT 25 completed.0
>>>> 10: 0000000000003df8 0 OBJECT LOCAL DEFAULT 21 __do_global_dtor[...]
>>>> 11: 0000000000001150 0 FUNC LOCAL DEFAULT 14 frame_dummy
>>>> 12: 0000000000003df0 0 OBJECT LOCAL DEFAULT 20 __frame_dummy_in[...]
>>>> 13: 0000000000000000 0 FILE LOCAL DEFAULT ABS damo.c
>>>> 14: 0000000000004022 1 OBJECT LOCAL DEFAULT 25 ti
>>>> 15: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
>>>> 16: 00000000000020d8 0 OBJECT LOCAL DEFAULT 19 __FRAME_END__
>>>> 17: 0000000000000000 0 FILE LOCAL DEFAULT ABS
>>>> 18: 0000000000003e00 0 OBJECT LOCAL DEFAULT 22 _DYNAMIC
>>>> 19: 0000000000002008 0 NOTYPE LOCAL DEFAULT 18 __GNU_EH_FRAME_HDR
>>>> 20: 0000000000003fc0 0 OBJECT LOCAL DEFAULT 23 _GLOBAL_OFFSET_TABLE_
>>>> 21: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_mai[...]
>>>> 22: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterT[...]
>>>> 23: 0000000000004000 0 NOTYPE WEAK DEFAULT 24 data_start
>>>> 24: 0000000000001160 8 FUNC GLOBAL DEFAULT 14 add
>>>> 25: 0000000000004020 0 NOTYPE GLOBAL DEFAULT 24 _edata
>>>> 26: 0000000000002004 1 NOTYPE WEAK HIDDEN 17 _.stapsdt.base
>>>> 27: 0000000000004010 8 OBJECT GLOBAL DEFAULT 24 t1
>>>> 28: 0000000000001168 0 FUNC GLOBAL HIDDEN 15 _fini
>>>> 29: 0000000000004000 0 NOTYPE GLOBAL DEFAULT 24 __data_start
>>>> 30: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
>>>> 31: 0000000000004008 0 OBJECT GLOBAL HIDDEN 24 __dso_handle
>>>> 32: 0000000000002000 4 OBJECT GLOBAL DEFAULT 16 _IO_stdin_used
>>>> 33: 0000000000004028 0 NOTYPE GLOBAL DEFAULT 25 _end
>>>> 34: 0000000000001070 38 FUNC GLOBAL DEFAULT 14 _start
>>>> 35: 0000000000004020 0 NOTYPE GLOBAL DEFAULT 25 __bss_start
>>>> 36: 0000000000001040 48 FUNC GLOBAL DEFAULT 14 main
>>>> 37: 0000000000004018 8 OBJECT GLOBAL DEFAULT 24 add_ptr
>>>> 38: 0000000000004020 0 OBJECT GLOBAL HIDDEN 24 __TMC_END__
>>>> 39: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMC[...]
>>>> 40: 0000000000000000 0 FUNC WEAK DEFAULT UND __cxa_finalize@G[...]
>>>> 41: 0000000000001000 0 FUNC GLOBAL HIDDEN 11 _init
>>>>
>>>>
>>>> Displaying notes found in: .note.gnu.property
>>>> Owner Data size Description
>>>> GNU 0x00000020 NT_GNU_PROPERTY_TYPE_0
>>>> Properties: x86 feature: IBT, SHSTK
>>>> x86 ISA needed: x86-64-baseline
>>>>
>>>>
>>>> Displaying notes found in: .note.gnu.build-id
>>>> Owner Data size Description
>>>> GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring)
>>>> Build ID: eb615daa575687cc44edc1d339b27890c12c27f1
>>>>
>>>>
>>>> Displaying notes found in: .note.ABI-tag
>>>> Owner Data size Description
>>>> GNU 0x00000010 NT_GNU_ABI_TAG (ABI version tag)
>>>> OS: Linux, ABI: 3.2.0
>>>>
>>>>
>>>> Displaying notes found in: .note.stapsdt
>>>> Owner Data size Description
>>>> stapsdt 0x00000066 NT_STAPSDT (SystemTap probe descriptors)
>>>> Provider: usdt_rip
>>>> Name: rip_global_var
>>>> Location: 0x0000000000001058, Base: 0x0000000000002004, Semaphore: 0x0000000000000000
>>>> Arguments: -1@ti(%rip) 8@add_ptr(%rip) -1@4+t1(%rip) -1@ti(%rip)
>>> Could you share the complete source codes and compiler options which
>>> reproduce the above result?
>>>
>>>>
>>>>
>>>> At 2025-08-12 13:06:40, "Yonghong Song" <yonghong.song@linux.dev> wrote:
>>>>> On 8/10/25 1:55 AM, 赵佳炜 wrote:
>>>>>> Hi Yonghong,
>>>>>>
>>>>>> I found another issue where symbols can be duplicated, and I’m not sure how to tell them apart.
>>>>>>
>>>>>> For example, I created two C files named usdt_rip.c and hello.c. Both define their own static ti variables, like:`static volatile char ti = 0;`.
>>>>>>
>>>>>> After compiling, I obtained an ELF file usdt_rip whose .symtab contains the following entries:
>>>>>>
>>>>>> $ readelf -s usdt_rip
>>>>>>
>>>>>> Symbol table '.symtab' contains 42 entries:
>>>>>> Num: Value Size Type Bind Vis Ndx Name
>>>>>> 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
>>>>>> 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS Scrt1.o
>>>>>> 2: 000000000000038c 32 OBJECT LOCAL DEFAULT 4 __abi_tag
>>>>>> 3: 0000000000000000 0 FILE LOCAL DEFAULT ABS usdt_rip.c
>>>>>> 4: 0000000000004021 1 OBJECT LOCAL DEFAULT 25 ti
>>>>>> 5: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
>>>>>> 6: 00000000000010a0 0 FUNC LOCAL DEFAULT 14 deregister_tm_clones
>>>>>> 7: 00000000000010d0 0 FUNC LOCAL DEFAULT 14 register_tm_clones
>>>>>> 8: 0000000000001110 0 FUNC LOCAL DEFAULT 14 __do_global_dtors_aux
>>>>>> 9: 0000000000004020 1 OBJECT LOCAL DEFAULT 25 completed.0
>>>>>> 10: 0000000000003df8 0 OBJECT LOCAL DEFAULT 21 __do_global_dtor[...]
>>>>>> 11: 0000000000001150 0 FUNC LOCAL DEFAULT 14 frame_dummy
>>>>>> 12: 0000000000003df0 0 OBJECT LOCAL DEFAULT 20 __frame_dummy_in[...]
>>>>>> 13: 0000000000000000 0 FILE LOCAL DEFAULT ABS damo.c
>>>>>> 14: 0000000000004022 1 OBJECT LOCAL DEFAULT 25 ti
>>>>>> 15: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
>>>>>> 16: 00000000000020d8 0 OBJECT LOCAL DEFAULT 19 __FRAME_END__
>>>>>>
>>>>>>
>>>>>> As you can see, there are two ti variables in the .symtab section. Their values are very close, making them hard to distinguish.
>>>>>>
>>>>>> I’m unsure how to handle this situation. Do you have any suggestions?
>>>>> Did you check relocations? Relocaitons should be able to point exact which symbol.
>>>>>
>>>>>> Thanks,
>>>>>> Jiawei Zhao
>>>>> [...]
>
Or maybe we can just throw an error when LOCAL symbols are duplicated. WDYT? At 2025-08-10 16:55:38, "赵佳炜" <phoenix500526@163.com> wrote: > > > >Hi Yonghong, > >I found another issue where symbols can be duplicated, and I’m not sure how to tell them apart. > >For example, I created two C files named usdt_rip.c and hello.c. Both define their own static ti variables, like:`static volatile char ti = 0;`. > >After compiling, I obtained an ELF file usdt_rip whose .symtab contains the following entries: > >$ readelf -s usdt_rip > >Symbol table '.symtab' contains 42 entries: > Num: Value Size Type Bind Vis Ndx Name > 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND > 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS Scrt1.o > 2: 000000000000038c 32 OBJECT LOCAL DEFAULT 4 __abi_tag > 3: 0000000000000000 0 FILE LOCAL DEFAULT ABS usdt_rip.c > 4: 0000000000004021 1 OBJECT LOCAL DEFAULT 25 ti > 5: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c > 6: 00000000000010a0 0 FUNC LOCAL DEFAULT 14 deregister_tm_clones > 7: 00000000000010d0 0 FUNC LOCAL DEFAULT 14 register_tm_clones > 8: 0000000000001110 0 FUNC LOCAL DEFAULT 14 __do_global_dtors_aux > 9: 0000000000004020 1 OBJECT LOCAL DEFAULT 25 completed.0 > 10: 0000000000003df8 0 OBJECT LOCAL DEFAULT 21 __do_global_dtor[...] > 11: 0000000000001150 0 FUNC LOCAL DEFAULT 14 frame_dummy > 12: 0000000000003df0 0 OBJECT LOCAL DEFAULT 20 __frame_dummy_in[...] > 13: 0000000000000000 0 FILE LOCAL DEFAULT ABS damo.c > 14: 0000000000004022 1 OBJECT LOCAL DEFAULT 25 ti > 15: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c > 16: 00000000000020d8 0 OBJECT LOCAL DEFAULT 19 __FRAME_END__ > > >As you can see, there are two ti variables in the .symtab section. Their values are very close, making them hard to distinguish. > >I’m unsure how to handle this situation. Do you have any suggestions? > >Thanks, >Jiawei Zhao > > > > > > > > > >At 2025-08-08 02:01:08, "Yonghong Song" <yonghong.song@linux.dev> wrote: >> >> >>On 8/6/25 7:57 PM, 赵佳炜 wrote: >>> >>> >>> >>> Hi Yonghong, >>> >>> I noticed that the USDT argument specification generated by GCC 14 is '8@array(,%rax,8)'. >>> This pattern is currently not handled correctly. I'm exploring whether I can use DWARF information >>> to calculate the address of this variable. This approach seems to work. However, since I can't >> >>I think 'array' should be in symbol table, so there is no need to check dwarf in my opinion. >> >>> reproduce the same issue on my machine, I plan to implement this approach for the PC-relative >>> issue in a separate patch. Would that affect the merging of this patch? >> >>Let us handle this since '8@array(,%rax,8)' may appear in CI environment. >> >>> >>> >>> At 2025-08-07 02:17:34, "Yonghong Song" <yonghong.song@linux.dev> wrote: >>>> >>>> On 8/6/25 2:24 AM, Jiawei Zhao wrote: >>>>> When using GCC on x86-64 to compile an usdt prog with -O1 or higher >>>>> optimization, the compiler will generate SIB addressing mode for global >>>>> array and PC-relative addressing mode for global variable, >>>>> e.g. "1@-96(%rbp,%rax,8)" and "-1@4+t1(%rip)". >>>>> >>>>> In this patch: >>>>> - add usdt_o2 test case to cover SIB addressing usdt argument spec >>>>> handling logic >>>>> >>>>> Signed-off-by: Jiawei Zhao <phoenix500526@163.com> >>>>> --- >>>>> tools/testing/selftests/bpf/Makefile | 8 +++ >>>>> .../selftests/bpf/prog_tests/usdt_o2.c | 71 +++++++++++++++++++ >>>>> .../selftests/bpf/progs/test_usdt_o2.c | 37 ++++++++++ >>>>> 3 files changed, 116 insertions(+) >>>>> create mode 100644 tools/testing/selftests/bpf/prog_tests/usdt_o2.c >>>>> create mode 100644 tools/testing/selftests/bpf/progs/test_usdt_o2.c >>>>> >>>>> diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile >>>>> index 910d8d6402ef..68cf6a9cf05f 100644 >>>>> --- a/tools/testing/selftests/bpf/Makefile >>>>> +++ b/tools/testing/selftests/bpf/Makefile >>>>> @@ -759,6 +759,14 @@ TRUNNER_BPF_BUILD_RULE := $$(error no BPF objects should be built) >>>>> TRUNNER_BPF_CFLAGS := >>>>> $(eval $(call DEFINE_TEST_RUNNER,test_maps)) >>>>> >>>>> +# Use -O2 optimization to generate SIB addressing usdt argument spec >>>>> +# Only apply on x86 architecture where SIB addressing is relevant >>>>> +ifeq ($(ARCH), x86) >>>>> +$(OUTPUT)/usdt_o2.test.o: CFLAGS:=$(subst O0,O2,$(CFLAGS)) >>>>> +$(OUTPUT)/cpuv4/usdt_o2.test.o: CFLAGS:=$(subst O0,O2,$(CFLAGS)) >>>>> +$(OUTPUT)/no_alu32/usdt_o2.test.o: CFLAGS:=$(subst O0,O2,$(CFLAGS)) >>>>> +endif >>>> I tried your selftest with gcc14 and llvm20 in my environment. See below: >>>> >>>> llvm20: >>>> Displaying notes found in: .note.stapsdt >>>> Owner Data size Description >>>> stapsdt 0x0000002f NT_STAPSDT (SystemTap probe descriptors) >>>> Provider: test >>>> Name: usdt1 >>>> Location: 0x00000000000003ac, Base: 0x0000000000000000, Semaphore: 0x0000000000000000 >>>> Arguments: 8@-64(%rbp) >>>> >>>> gcc14: >>>> Displaying notes found in: .note.stapsdt >>>> Owner Data size Description >>>> stapsdt 0x00000034 NT_STAPSDT (SystemTap probe descriptors) >>>> Provider: test >>>> Name: usdt1 >>>> Location: 0x0000000000000334, Base: 0x0000000000000000, Semaphore: 0x0000000000000000 >>>> Arguments: 8@array(,%rax,8) >>>> >>>> llvm20 and gcc14 generate different usdt patterns. '8@-64(%rbp)' already supports so >>>> with SIB support, the test should pass CI, I think. >>>> >>[...]
© 2016 - 2026 Red Hat, Inc.