Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

asan: no report when several threads hit bug #858

Closed
dvyukov opened this issue Sep 12, 2017 · 7 comments
Closed

asan: no report when several threads hit bug #858

dvyukov opened this issue Sep 12, 2017 · 7 comments
Assignees

Comments

@dvyukov
Copy link
Contributor

dvyukov commented Sep 12, 2017

Originally reported at https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82116

I can confirm this happens with clang version 6.0.0 (trunk 311230)
The repro prints something like this:

$ ./a.out 
AddressSanitizer: nested bug in the same thread, aborting.
AddressSanitizer: nested bug in the same thread, aborting.
AddressSanitizer: nested bug in the same thread, aborting.
=================================================================
AddressSanitizer: nested bug in the same thread, aborting.
@dvyukov
Copy link
Contributor Author

dvyukov commented Sep 12, 2017

Repro:

#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>

static void *start_routine(void *arg)
{
	volatile int *counter = arg;
	char buf[8];

	__atomic_sub_fetch(counter, 1, __ATOMIC_SEQ_CST);
	while (*counter)
		;
	buf[0] = buf[9];
}

int main(void)
{
	const int n_threads = 8;
	int i, counter = n_threads;
	pthread_t thread;

	for (i = 0; i < n_threads; ++i)
		pthread_create(&thread, NULL, &start_routine, (void *)&counter);
	sleep(5);
	return EXIT_FAILURE;
}

@yugr
Copy link

yugr commented Sep 17, 2017

@chefmax

@chefmax
Copy link

chefmax commented Sep 18, 2017

Hm, not reproducible with GCC 6 (and probably older Clang).

@chefmax
Copy link

chefmax commented Sep 18, 2017

Eh, this is a known race in ScopedInErrorReport constructor:

  class ScopedInErrorReport {
   public:
    explicit ScopedInErrorReport(bool fatal = false) {
      halt_on_error_ = fatal || flags()->halt_on_error;
  
      if (lock_.TryLock()) {
        StartReporting();
        return;
      }
  
      // ASan found two bugs in different threads simultaneously.
  
      u32 current_tid = GetCurrentTidOrInvalid();
      if (reporting_thread_tid_ == current_tid ||
          reporting_thread_tid_ == kInvalidTid) {
        // This is either asynch signal or nested error during error reporting.
        // Fail simple to avoid deadlocks in Report().
...
   private:
    void StartReporting() {
      // Make sure the registry and sanitizer report mutexes are locked while
      // we're printing an error report.
      // We can lock them only here to avoid self-deadlock in case of
      // recursive reports.
      asanThreadRegistry().Lock();
      CommonSanitizerReportMutex.Lock();
      reporting_thread_tid_ = GetCurrentTidOrInvalid();
      Printf("===================================================="
             "=============\n");
    }
  1. Thread 1 acquires lock_ and calls StartReporting.
  2. Thread 2 also tries to acquire lock_, fails and falls through to if (reporting_thread_tid_ == current_tid || reporting_thread_tid_ == kInvalidTid) condition.
  3. Now, if Thread 1 hasn't yet set reporting_thread_tid_ in StartReporting, thread 2 wrongly reports AddressSanitizer: nested bug in the same thread, aborting. due to reporting_thread_tid_ still equals to kInvalidTid.

@vitalybuka
Copy link
Contributor

Fixed

jyknight pushed a commit to jyknight/llvm-monorepo that referenced this issue Sep 28, 2017
Summary: Fixes google/sanitizers#858

Reviewers: eugenis, dvyukov

Subscribers: kubamracek, llvm-commits

Differential Revision: https://reviews.llvm.org/D38019

llvm-svn=313835
jyknight pushed a commit to jyknight/llvm-monorepo that referenced this issue Sep 28, 2017
"nested bug in the same thread" is not expected in case like this and was caused
by google/sanitizers#858

llvm-svn=313844
@rogeriosouzamoraes
Copy link

Hi everyone,

I can confirm that this issue happens in GCC v6.3.0, but is intermittent (very difficult to reproduce). Is there any patch for GCC?

Regards,

Rogerio

@yugr
Copy link

yugr commented Jun 6, 2018

@rogeriosouzamoraes Probly not, 6.3 was released long before this got fixed. Try with newer GCC.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants