lewisje / address-sanitizer

Automatically exported from code.google.com/p/address-sanitizer
0 stars 0 forks source link

asan deadlock in ScopedInErrorReport destructor when print_stats=1 #306

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
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);
  }
  ...
}

Original issue reported on code.google.com by xiaoyur...@gmail.com on 6 May 2014 at 1:19

GoogleCodeExporter commented 9 years ago
This is the original patch for this issue.

Original comment by xiaoyur...@gmail.com on 6 May 2014 at 1:21

Attachments:

GoogleCodeExporter commented 9 years ago
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.

Original comment by konstant...@gmail.com on 6 May 2014 at 1:51

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

Original comment by konstant...@gmail.com on 12 May 2014 at 8:09

GoogleCodeExporter commented 9 years ago
Adding Project:AddressSanitizer as part of GitHub migration.

Original comment by ramosian.glider@gmail.com on 30 Jul 2015 at 9:14