runtime: LTTNG-UST 2.13 changes soname breaking loading of libcoreclrtraceptprovider
There’s an ABI breaking change between LTTNG-ust 2.12 and 2.13, so they’ve reved their soname from liblttng-ust.so.0 to liblttng-ust.so.1. We link against the former. Given some distros will start supporting newer versions, customers will likely end up upgrading packages and realize they can’t load libcoreclrtraceptprovider.so. We should investigate avenues to support multiple versions as needed using compilation tricks like the ones used in System.Security for openssl. Other possibility is to only support 2.13 and that brings us come code sanity advantages - this would only happen in .NET 7+ realistically.
About this issue
- Original URL
- State: open
- Created 3 years ago
- Reactions: 1
- Comments: 39 (39 by maintainers)
@am11 thank you for the analysis! I’ll take a look into the possibilities of shimming lttng and consider your suggestion.
Current workaround is to disable event trace by deleting the following block before build: https://github.com/dotnet/runtime/blob/9d4ce4048c08317e320d5b826df7f12d50b7d083/src/coreclr/clrfeatures.cmake#L5-L7
Supporting both ABI versions of liblttng-ust in parallel would require more work than a few liner fix.
Yes, but eventing is one of those things that often doesn’t get updated much, but it gets updated by more than their known maintainers. Maintaining it outside the manifest is brittle. That’s the main reason the python scripts have changed. It could easily be a little C# app that we stick in clr.prereqs and reads the manifest; we could stub them for bring up or generate them in a separate machine if needed if all we are trying to do is get rid of the Python dependency. There’s prior art for this with the DAC table generation.
Agree that we have precedent for duplicate lists that have to be kept in sync, I’d just rather not add another one. 😃
After some digging, it turned out
lttng/tracepoint.hheader (the one we use) does things quite differently than libssl, libnuma ones. It differs in the following manner:TACEPOINT_*macros which (during the macro expansion) binds to__tracepoints__initmethod and the related code chunks.__tracepoints__inititself usesdlopen(3)and uses the ABI-versioned flavorliblttng-ust.so.0,liblttng-ust.so.1(For 2.13).so.0loaded. e.g. https://github.com/lttng/lttng-ust/blob/d2a010d/src/lib/lttng-ust-tracepoint/tracepoint.c#L611-L642Here is the expansion of macros for our generated
tpdotnetruntimemonoprofiler.h:the dump looks like this: http://sprunge.us/J5rsv3 (and file tpdotnetruntimemonoprofiler.h: http://sprunge.us/LPmIuJ). Search for
__tracepoints__initordlopen("liblttng. It is quite noisy, so I made a copy, removed#include "palrt.h"etc. and kept only one probe, here is the shorter version of this expansion: http://sprunge.us/BK0q1V, at the very end of this file is the code of interest.I will defer to @janvorli as to the best approach for lttngshim. One option is that we install both versions on the official build machine, and compile both v0 and v1 implementations in our code with our pseudo init; which will probe for .so.1, and if not found, .so.0, then select the implementation based on the result. This approach will prevent us from stamping out symbols of
liblttng-ust{-tracepoint}.soand we will still be using their init mechanism (which seem to take care of “shared access” scenarios).