admin管理员组

文章数量:1122832

I'm compiling code on an Ubuntu system with GCC 11.4.0 with -fsanitize=thread.

I am getting some sanitizer errors from external libraries called from my functions. I have read that I should be able to add __attribute__((no_sanitize_thread)) to functions to disable sanitizers for the function. However it is unclear to me whether this should be added to the declaration, definition or both.

No matter where I place it, the sanitizer still reports violations originating in the function. e.g.

class Foo : public Bar {
public:
void __attribute__((no_sanitize_thread)) func() override;
};

void __attribute__((no_sanitize_thread)) Foo::func() {
   call::external::lib(); 
}

still I get a report such as

==================
WARNING: ThreadSanitizer: double lock of a mutex (pid=1432431)
    #0 pthread_mutex_lock ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:4240 (libtsan.so.0+0x53908)
    #1 __gthread_mutex_lock /usr/include/x86_64-linux-gnu/c++/11/bits/gthr-default.h:749 (cranelink-encoder+0x18ac00)
    #2 std::mutex::lock() /usr/include/c++/11/bits/std_mutex.h:100 (cranelink-encoder+0x18b788)
    #3 std::unique_lock<std::mutex>::lock() /usr/include/c++/11/bits/unique_lock.h:139 (libdatachannel.so.0.22+0x5bc4b0)
    #4 __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58 (libc.so.6+0x29d8f)

  Location is heap block of size 296 at 0x7b4400001400 allocated by main thread:
    #0 operator new(unsigned long) ../../../../src/libsanitizer/tsan/tsan_new_delete.cpp:64 (libtsan.so.0+0x8f162)
    #1 fun() …

So clearly I'm doing something wrong. How can this be done?

I'm compiling code on an Ubuntu system with GCC 11.4.0 with -fsanitize=thread.

I am getting some sanitizer errors from external libraries called from my functions. I have read that I should be able to add __attribute__((no_sanitize_thread)) to functions to disable sanitizers for the function. However it is unclear to me whether this should be added to the declaration, definition or both.

No matter where I place it, the sanitizer still reports violations originating in the function. e.g.

class Foo : public Bar {
public:
void __attribute__((no_sanitize_thread)) func() override;
};

void __attribute__((no_sanitize_thread)) Foo::func() {
   call::external::lib(); 
}

still I get a report such as

==================
WARNING: ThreadSanitizer: double lock of a mutex (pid=1432431)
    #0 pthread_mutex_lock ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:4240 (libtsan.so.0+0x53908)
    #1 __gthread_mutex_lock /usr/include/x86_64-linux-gnu/c++/11/bits/gthr-default.h:749 (cranelink-encoder+0x18ac00)
    #2 std::mutex::lock() /usr/include/c++/11/bits/std_mutex.h:100 (cranelink-encoder+0x18b788)
    #3 std::unique_lock<std::mutex>::lock() /usr/include/c++/11/bits/unique_lock.h:139 (libdatachannel.so.0.22+0x5bc4b0)
    #4 __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58 (libc.so.6+0x29d8f)

  Location is heap block of size 296 at 0x7b4400001400 allocated by main thread:
    #0 operator new(unsigned long) ../../../../src/libsanitizer/tsan/tsan_new_delete.cpp:64 (libtsan.so.0+0x8f162)
    #1 fun() …

So clearly I'm doing something wrong. How can this be done?

Share Improve this question asked Nov 22, 2024 at 12:21 oarfishoarfish 4,6225 gold badges42 silver badges75 bronze badges 8
  • Could it be the external library not having that flag? Also, I think you should place it in both – Mippy Commented Nov 22, 2024 at 12:38
  • Unrelated: "double lock of a mutex" sounds like something I wouldn't suppress. :) – Ted Lyngmo Commented Nov 22, 2024 at 12:41
  • The problem in the report is not a problem in the code that has the __attribute__((no_sanitize_thread)). It's a problem in a different function. – Eljay Commented Nov 22, 2024 at 12:52
  • callstack starts from __libc_start_call_main! Doesn't this mean you have some complex global variable/constant which is initialized before main? Also this callstack doesn't point to anything what looks like your code or code of library you are using. – Marek R Commented Nov 22, 2024 at 13:16
  • The call stack is an example, and I'm not sure why its so short. there is more info in the Location is heap block of size 296 at 0x7b4400000f00 allocated by main thread: part that points to my code, but its just using some library call. So I thought i could just disable the sanitizer for the function that seems to trigger it. – oarfish Commented Nov 22, 2024 at 14:44
 |  Show 3 more comments

1 Answer 1

Reset to default 0

Sanitizers have suppression file functionality. I never used this for thread sanitizer, but I've found following chain of documentation:

Instrumentation Options (Using the GNU Compiler Collection (GCC))

-fsanitize=thread

Enable ThreadSanitizer, a fast data race detector. Memory access instructions are instrumented to detect data race bugs. See https://github.com/google/sanitizers/wiki#threadsanitizer for more details. The run-time behavior can be influenced using the TSAN_OPTIONS environment variable; see https://github.com/google/sanitizers/wiki/ThreadSanitizerFlags for a list of supported options. The option cannot be combined with -fsanitize=address, -fsanitize=leak.

Note that sanitized atomic builtins cannot throw exceptions when operating on invalid memory addresses with non-call exceptions (-fnon-call-exceptions).

And following second link: ThreadSanitizerFlags · google/sanitizers Wiki · GitHub

Flag name Default value Description
suppressions Suppressions filename. See ThreadSanitizerSuppressions page for details.

Then there is more detailed information in link froma table, but I do not see there explicit option to suppress "double lock of a mutex", most probably deadlock is the proper type.

But most promessing option is called_from_lib:

ThreadSanitizerSuppressions · google/sanitizers Wiki

ThreadSanitizerSuppressions

type description
called_from_lib suppresses all interceptors in a particular library

Looks like this is best thing you can use.

Disclaimer:

  • I've started search from documentation of you version of compiler, but wiki on github could have been updated and current version may apply only to newer version of gcc.
  • your example of report do not point to any code which looks like your code or code of some library. I see only standard library or sanitizer. This is a bit fishy.

本文标签: cHow can I suppress sanitizer errors from member functions in GCCStack Overflow