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 deadlock in ScopedInErrorReport destructor when print_stats=1 #306

Closed
ramosian-glider opened this issue Aug 31, 2015 · 4 comments
Closed

Comments

@ramosian-glider
Copy link
Member

Originally reported on Google Code with ID 306

What steps will reproduce the problem?
1. export ASAN_OPTIONS=print_stats=1
2. Run programs under Linux. When generating error reports, asan stucks.

What is the expected output? What do you see instead?
Generates error reports and exit the program.

What version of the product are you using? On what operating system?
I run under GCC 4.9.
I check http://llvm.org/svn/llvm-project/compiler-rt/trunk/lib/sanitizer_common and
find it not fixed.

Please provide any additional information below.
In asan_report.cc
class ScopedInErrorReport {
 public:
  ScopedInErrorReport() {
    ...

    ASAN_ON_ERROR();
    // 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(); //@@@@@lock once
    CommonSanitizerReportMutex.Lock();
    reporting_thread_tid = GetCurrentTidOrInvalid();
    Printf("===================================================="
           "=============\n");
  }
  // Destructor is NORETURN, as functions that report errors are.
  NORETURN ~ScopedInErrorReport() {
    // Make sure the current thread is announced.
    DescribeThread(GetCurrentThread());
    // Print memory stats.
    if (flags()->print_stats)
      __asan_print_accumulated_stats(); //@@@@@lock twice
    if (error_report_callback) {
      error_report_callback(error_message_buffer);
    }
    Report("ABORTING\n");
    Die();
  }
};

Since __asan_print_accumulated_stats() indirectly calls GetAccumulatedStats(&stats),
and
static void GetAccumulatedStats(AsanStats *stats) {
  stats->Clear();
  {
    ThreadRegistryLock l(&asanThreadRegistry()); //the twice lock
    asanThreadRegistry()
        .RunCallbackForEachThreadLocked(MergeThreadStats, stats);
  }
  ...
}

Reported by xiaoyur347 on 2014-05-06 01:19:38

@ramosian-glider
Copy link
Member Author

This is the original patch for this issue.

Reported by xiaoyur347 on 2014-05-06 01:21:11


- _Attachment: [asan_report.cc.patch](https://storage.googleapis.com/google-code-attachments/address-sanitizer/issue-306/comment-1/asan_report.cc.patch)_

@ramosian-glider
Copy link
Member Author

Confirmed, thanks for the report. 
The fix will need to be different (introduce GetAccumulatedStatsUnlocked or some such)
and it will need tests. 
Feel free to send such patch to llvm-commits (not here, see https://code.google.com/p/address-sanitizer/wiki/HowToContribute)
or let us handle 
it some time later.

Reported by konstantin.s.serebryany on 2014-05-06 13:51:28

  • Status changed: Accepted

@ramosian-glider
Copy link
Member Author

http://llvm.org/viewvc/llvm-project?view=revision&revision=208525 should fix this, 
thanks again for reporting. 

Reported by konstantin.s.serebryany on 2014-05-12 08:09:49

  • Status changed: Fixed

@ramosian-glider
Copy link
Member Author

Adding Project:AddressSanitizer as part of GitHub migration.

Reported by ramosian.glider on 2015-07-30 09:14:08

  • Labels added: ProjectAddressSanitizer

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

No branches or pull requests

1 participant