tracing: Fix data source static state instantiation for DLLs

Previously, code defining a DLL-exported DataSource would fail to
build with Clang-CL. This was because of the following chain of
events:

1. The DataSource was defined as a __declspec(dllexport) subclass
   of perfetto::DataSource.

2. While instantiating the exported data source subclass, the
   compiler would also automatically instantiate the
   `static_state_` field.

3. The PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS macro would
   try to declare that a definition of `static_state_` exists
   elsewhere (i.e., in the corresponding .cc file). This would
   trigger an explicit specialization error since the static
   member was already implicitly instantiated in step 2.

The underlying issue here seems to be that the dllexport specifier
makes the compiler also implicitly instantiate static data members
for the exported class, without waiting until the end of the
translation unit like normal to see all possible definition
declarations.

We work around the problem by not making the DataSource subclass
__declspec(dllexport) in the first place. This exporting isn't
actually needed, because the DataSource template is fully defined
in the header file. To make sure DataSource instances are properly
synchronized across DLL boundaries, we just need to export static
members: `static_state_` and `tls_state_`.

However, doing this leads to the next problem with dllexport:
thread_local variables can't be marked dllexport. To work around
this, we also avoid exporting `tls_state_`. This means the
TLS pointer can have different storage in different translation
units, but because the pointer is simply caching the value to
the underlying thread-local storage, each instance ends up
pointing to the same memory.

Since the behavior with implicitly exporting static template fields
differs between clang-cl and MSVC, I've filed an upstream LLVM bug
to track the issue: https://bugs.llvm.org/show_bug.cgi?id=51661.

Test: Build and run base_unittests in Chrome w/ the
      use_perfetto_client_library=true GN arg
Bug: 189825391
Change-Id: Ic39744bf4327a53e1b4f75121597e86ca536dbe4
2 files changed
tree: 3474fb88801a59a1541581c7013fd0999918f880
  1. .github/
  2. bazel/
  3. build_overrides/
  4. buildtools/
  5. debian/
  6. docs/
  7. examples/
  8. gn/
  9. include/
  10. infra/
  11. protos/
  12. src/
  13. test/
  14. tools/
  15. ui/
  16. .clang-format
  17. .clang-tidy
  18. .gitattributes
  19. .gitignore
  20. .gn
  21. .style.yapf
  22. Android.bp
  23. Android.bp.extras
  24. BUILD
  25. BUILD.extras
  26. BUILD.gn
  27. CHANGELOG
  28. codereview.settings
  29. DIR_METADATA
  30. heapprofd.rc
  31. LICENSE
  32. meson.build
  33. METADATA
  34. MODULE_LICENSE_APACHE2
  35. OWNERS
  36. perfetto.rc
  37. PerfettoIntegrationTests.xml
  38. PRESUBMIT.py
  39. README.chromium
  40. README.md
  41. TEST_MAPPING
  42. traced_perf.rc
  43. WORKSPACE
README.md

Perfetto - System profiling, app tracing and trace analysis

Perfetto is a production-grade open-source stack for performance instrumentation and trace analysis. It offers services and libraries and for recording system-level and app-level traces, native + java heap profiling, a library for analyzing traces using SQL and a web-based UI to visualize and explore multi-GB traces.

See https://perfetto.dev/docs or the /docs/ directory for documentation.