staticanalysis / data-race-test

Automatically exported from code.google.com/p/data-race-test
0 stars 0 forks source link

tsanv2: instrumentation of thread-safe function static objects #94

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
Here is what we currently have:

const Foo *GetFoo() {
  static const Foo *foo = new Foo();
  return foo;
}

const Foo *GetFoo() {
  static const Foo *foo = new Foo();
   65b90:       41 56                   push   %r14
   65b92:       53                      push   %rbx
   65b93:       50                      push   %rax
   65b94:       48 8b 7c 24 18          mov    0x18(%rsp),%rdi
   65b99:       e8 62 4f 0c 00          callq  12ab00 <__tsan_func_entry>
   65b9e:       48 8d 3d ab 42 54 0c    lea    0xc5442ab(%rip),%rdi        # c5a9e50 <guard variable for test108::GetFoo()::foo>
   65ba5:       e8 66 55 09 00          callq  fb110 <__tsan_read1>
   65baa:       8a 05 a0 42 54 0c       mov    0xc5442a0(%rip),%al        # c5a9e50 <guard variable for test108::GetFoo()::foo>
   65bb0:       84 c0                   test   %al,%al
   65bb2:       75 5e                   jne    65c12 <test108::GetFoo()+0x82>
   65bb4:       48 8d 3d 95 42 54 0c    lea    0xc544295(%rip),%rdi        # c5a9e50 <guard variable for test108::GetFoo()::foo>
   65bbb:       e8 60 06 07 00          callq  d6220 <__cxa_guard_acquire>
   65bc0:       85 c0                   test   %eax,%eax
   65bc2:       74 4e                   je     65c12 <test108::GetFoo()+0x82>
   65bc4:       bf 04 00 00 00          mov    $0x4,%edi
   65bc9:       e8 e2 fd 06 00          callq  d59b0 <operator new(unsigned long)>
   65bce:       48 89 c3                mov    %rax,%rbx
   65bd1:       48 8d 3d d8 a7 0c 00    lea    0xca7d8(%rip),%rdi        # 1303b0 <_IO_stdin_used+0x20>
   65bd8:       be ea 13 00 00          mov    $0x13ea,%esi
   65bdd:       48 89 da                mov    %rbx,%rdx
   65be0:       e8 9b 51 07 00          callq  dad80 <AnnotateTraceMemory>
   65bf3:       48 8d 3d 4e 42 54 0c    lea    0xc54424e(%rip),%rdi        # c5a9e48 <test108::GetFoo()::foo>
   65bfa:       e8 11 f0 0a 00          callq  114c10 <__tsan_write8>
   65bff:       48 89 1d 42 42 54 0c    mov    %rbx,0xc544242(%rip)        # c5a9e48 <test108::GetFoo()::foo>
   65c06:       48 8d 3d 43 42 54 0c    lea    0xc544243(%rip),%rdi        # c5a9e50 <guard variable for test108::GetFoo()::foo>
   65c0d:       e8 de 06 07 00          callq  d62f0 <__cxa_guard_release>
   65c12:       48 8d 3d 2f 42 54 0c    lea    0xc54422f(%rip),%rdi        # c5a9e48 <test108::GetFoo()::foo>
   65c19:       e8 a2 01 0a 00          callq  105dc0 <__tsan_read8>
   65c1e:       48 8b 1d 23 42 54 0c    mov    0xc544223(%rip),%rbx        # c5a9e48 <test108::GetFoo()::foo>
   65c25:       e8 06 4f 0c 00          callq  12ab30 <__tsan_func_exit>
   65c2a:       48 89 d8                mov    %rbx,%rax
   65c2d:       48 83 c4 08             add    $0x8,%rsp
   65c31:       5b                      pop    %rbx
   65c32:       41 5e                   pop    %r14
   65c34:       c3                      retq   

It uses sort of fast-pathed double checked initialization:
if (guard_for_foo == 0) {
  if (__cxa_guard_acquire(&guard_for_foo)) {
    // user code
    __cxa_guard_release(&guard_for_foo);
  }
}

The problem is with lock-free read @65baa, we do not know that it is 
synchronization and so can't properly handle it. Possible solutions are 
somewhat awkward and subject to either false positives or negatives.
It would be nice to intercept it in the compiler.

Original issue reported on code.google.com by dvyu...@google.com on 2 Apr 2012 at 11:25

GoogleCodeExporter commented 9 years ago
This load looks like this in LLVM IR: 
%1 = load atomic i8* bitcast (i64* @guard variable for foo()::x to i8*) 
acquire, align 8

We'll need to append TBAA to this load in order to recognize 
that this is a guard var (we can not rely on the var name).
I am on it. 

Original comment by konstant...@gmail.com on 11 Apr 2012 at 12:35

GoogleCodeExporter commented 9 years ago
FTR:

I'll need to add something like
  CGM.DecorateInstruction(LI, CGM.getTBAAInfoForGuardVariable());
to ItaniumCXXABI::EmitGuardedInit (tools/clang/lib/CodeGen/ItaniumCXXABI.cpp)
and implement getTBAAInfoForGuardVariable in CodeGenTBAA.cpp

Currently I am waiting for anther code review in the same files. 

Original comment by konstant...@gmail.com on 11 Apr 2012 at 12:53