Change in function signature of `__tsan_func_exit` in gcc15
HHN
harihara.sn@gmail.com
Fri Jun 13 10:42:37 GMT 2025
>
> You shouldn't call __tsan_func_exit in user code, whether as () or as
> (NULL), without including appropriate header (tsan_interface.h).
Despite `__tsan_func_exit` being in `tsan_interface.h` in the gcc source,
in GCC distributions I am unable to find it in the
`sanitizer/tsan_interface.h` header
Godbolt link <https://godbolt.org/z/PEzzMsn8z> showcasing this
I am not very familiar with the gcc build and distribution process so
forgive me if this is a naive misunderstanding
In fact, I wonder why does the codebase actually call it at all.
I am referring to the ocaml codebase which has a C runtime, we wanted to
integrate tsan into OCaml and at times need to explicitly call
`__tsan_func_exit()` from `.S` and `.c` code
Currently, we have a declaration of `extern void __tsan_func_exit(void *)`
which we use to tell the compiler that the symbol will be found later
during link time
Also, I feel there'd be many codebases out there which use `extern
<internal tsan function which gcc does not expose>`
For example, consider the AnnotateHappens{After, Before} functions used to
silence tsan false positives
These functions have been documented in the "ThreadSanitizer – data race
detection in practice" paper Section 5 - Dynamic Annotations
<https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/35604.pdf>
but
are not exposed to the user through any headers
`extern <internal tsan function>` was the only way I could use such
functions to silence false positives
On Fri, Jun 13, 2025 at 3:06 PM Jakub Jelinek <jakub@redhat.com> wrote:
> On Fri, Jun 13, 2025 at 01:52:19PM +0530, HHN wrote:
> > GCC15 changes the signature of the `__tsan_func_exit` builtin function
> from
> > `void(void *)` to `void(void)` in the following commit
> > <
> https://github.com/gcc-mirror/gcc/commit/07565115371e#diff-1e5bf766c4c8924f68cb79315944f820eabd44bf881f2db7e746af4df86cd0a8R250
> >
>
> The gcc builtin had incorrect prototype by mistake. The function is a
> builtin solely because the compiler needs to call it with -fsanitize=thread
> on its own, and the calls added by the compiler actually were using
> just __tsan_func_exit(), which is also what libtsan expects and implements.
>
> > Attaching the godbolt <https://godbolt.org/z/x3fda57r5> link showcasing
> the
> > warning generated
> >
> > Currently I am working with a codebase which explicitly calls
> > `__tsan_func_exit(NULL)` in certain places and am curious as to whether
> > backwards compatibility of the builtin function signatures is a goal?
>
> You shouldn't call __tsan_func_exit in user code, whether as () or as
> (NULL), without including appropriate header (tsan_interface.h).
> In fact, I wonder why does the codebase actually call it at all.
> The function is meant to be called from compiled code at the end of
> functions, if a function is -fsanitize=thread instrumented, it should
> be called there already, if it is not instrumented, I don't see why
> you should be calling it.
>
> Jakub
>
>
--
Hari Hara Naveen
More information about the Gcc-help
mailing list