1a63932a8SVitaly Buka // Build a library with origin tracking and an executable w/o origin tracking.
2a63932a8SVitaly Buka // Test that origin tracking is enabled at runtime.
3a63932a8SVitaly Buka // RUN: %clangxx_lsan -O0 %s -DBUILD_SO -fPIC -shared -o %t-so.so
4a63932a8SVitaly Buka // RUN: %clangxx_lsan -O0 %s -ldl -o %t && not %run %t 2>&1 | FileCheck %s
5*678f88e0SVitaly Buka // RUN: %clangxx_lsan -O0 %s -ldl -o %t -DSUPPRESS_LEAK && %run %t
6a63932a8SVitaly Buka 
7a63932a8SVitaly Buka #ifdef BUILD_SO
8a63932a8SVitaly Buka 
9a63932a8SVitaly Buka #  include <stdlib.h>
10a63932a8SVitaly Buka 
11a63932a8SVitaly Buka extern "C" {
my_alloc(unsigned sz)12a63932a8SVitaly Buka void *my_alloc(unsigned sz) { return malloc(sz); }
13a63932a8SVitaly Buka } // extern "C"
14a63932a8SVitaly Buka 
15a63932a8SVitaly Buka #else // BUILD_SO
16a63932a8SVitaly Buka 
17a63932a8SVitaly Buka #  include <assert.h>
18a63932a8SVitaly Buka #  include <dlfcn.h>
19a63932a8SVitaly Buka #  include <stdlib.h>
20a63932a8SVitaly Buka #  include <string>
21a63932a8SVitaly Buka 
22a63932a8SVitaly Buka #  ifdef SUPPRESS_LEAK
__lsan_default_suppressions()23a63932a8SVitaly Buka extern "C" const char *__lsan_default_suppressions() {
24a63932a8SVitaly Buka   return "leak:^<unknown module>$";
25a63932a8SVitaly Buka }
26a63932a8SVitaly Buka #  endif
27a63932a8SVitaly Buka 
main(int argc,char ** argv)28a63932a8SVitaly Buka int main(int argc, char **argv) {
29a63932a8SVitaly Buka 
30a63932a8SVitaly Buka   std::string path = std::string(argv[0]) + "-so.so";
31a63932a8SVitaly Buka 
32a63932a8SVitaly Buka   dlerror();
33a63932a8SVitaly Buka 
34a63932a8SVitaly Buka   void *handle = dlopen(path.c_str(), RTLD_LAZY);
35a63932a8SVitaly Buka   assert(handle != 0);
36a63932a8SVitaly Buka   typedef void *(*fn)(unsigned sz);
37a63932a8SVitaly Buka   fn my_alloc = (fn)dlsym(handle, "my_alloc");
38a63932a8SVitaly Buka 
39*678f88e0SVitaly Buka   for (int i = 0; i < 100; ++i)
40*678f88e0SVitaly Buka     my_alloc(i);
41a63932a8SVitaly Buka 
42a63932a8SVitaly Buka   dlclose(handle);
43a63932a8SVitaly Buka   return 0;
44a63932a8SVitaly Buka }
45a63932a8SVitaly Buka 
46a63932a8SVitaly Buka #endif // BUILD_SO
47a63932a8SVitaly Buka 
48a63932a8SVitaly Buka // CHECK: Direct leak
49