canistation / address-sanitizer

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

Find init-order-fiasco caused by template instantiations #215

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
There is no guaranteed ordering of the initialization of static data
members declared in class templates. Thus, using one to initialize
another is a bug. We may consider adding support for detecting these bugs to 
init-order checker in ASan (that would likely require modifying the frontend so 
that it would distinguish globals that come from template instantiations) from 
regular globals (that have well-defined initialization order).

Reproducer:
$ cat a.cc 
int fun() { return 42; }

template <typename A>
class C1 {
 public:
  static A foo;
};
template<typename A> A C1<A>::foo = fun();

template<typename B>
class C2 {
 public:
  static B foo;
};
template<typename B> B C2<B>::foo = C1<B>::foo + 1;

#include <stdio.h>

int main() {
  printf("%d %d\n", C1<int>::foo, C2<int>::foo);
  return 0;
}

$ ./bin/clang++ a.cc ; ./a.out
42 1
$ g++ a.cc ; ./a.out
42 43

Original issue reported on code.google.com by samso...@google.com on 30 Aug 2013 at 10:23

GoogleCodeExporter commented 9 years ago
see also: 
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140505/216077.html

Original comment by konstant...@gmail.com on 7 May 2014 at 7:47

GoogleCodeExporter commented 9 years ago
Another test case for actual init-order-fiasco caused by template
instantiations, which is not currently caught by ASan:

// source1.cc
int foo();
template<int N> struct S1 { static int x; };
template<int N> int S1<N>::x = foo();
int main(int argc, char *argv[]) {
  return S1<0>::x + argc - 1;
}

// source2.cc
int bar() { return 0; }
template<int N> struct S2 { static int x; };
template<int N> int S2<N>::x = bar();
int foo() { return S2<0>::x; }

The main reason we don't report an issue here is:
globals created from template instantiations have linkonce_odr linkage,
and we don't instrument such globals in ASan at all (in case we link with
source files built w/o ASan, where these globals are unmodified).

Original comment by samso...@google.com on 23 May 2014 at 12:59

GoogleCodeExporter commented 9 years ago
David Majnemer is adding first-class sections with comdat support.  Could we do 
this with comdats?  We'd need some way of saying, include this global in the 
list of globals to poison, if and only if the global from this TU won the 
comdat race in the linker.  I don't think the current ASan global list really 
works for this.  It would need to be something more like .init_array, where 
many separate pieces of data go into it.

Original comment by rnk@google.com on 23 May 2014 at 5:11

GoogleCodeExporter commented 9 years ago
Hm, nevermind, I don't think it would really help with initialization order.  
COMDATs would only allow redzones, I think.

Original comment by rnk@google.com on 23 May 2014 at 5:13

GoogleCodeExporter commented 9 years ago

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

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:06