Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
mac shlib dependencies fixes #1891
mac shlib dependencies fixes #1891
Changes from all commits
97d3942
eb5d695
9665120
File filter
Filter by extension
Conversations
Jump to
There are no files selected for viewing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we link
gRPC::grpc++
intoopentelemetry_exporter_otlp_grpc
,opentelemetry_exporter_otlp_grpc_log
andopentelemetry_exporter_otlp_grpc_metrics
? If we build otel-cpp as static libraries, they will link it just by linkopentelemetry_exporter_otlp_grpc_client
, and if we build otel-cpp as dynamic libraries, I think the global variables of gRPC are both inopentelemetry_exporter_otlp_grpc_client
,opentelemetry_exporter_otlp_grpc
,opentelemetry_exporter_otlp_grpc_log
andopentelemetry_exporter_otlp_grpc_metrics
, the symbol overlap problem still exists.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ays7 - Can you reply to @owent concerns here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@owent
gRPC::grpc++
must be linked either directly or via shared dependency into all libs that make direct gRPC API calls to satisfy Mac shared library linker -- Mac shared libraries are linked like executables on linux -- all referenced symbols must be resolved to somewhere.One way to achieve this is by exposing gPRC as a public dependency of
opentelemetry_exporter_otlp_grpc_client
, which is a common dependency of the 3 libs you mentioned -- that was my original suggestion.For the static linking: here is my understanding: when linking shared libs on linux, linker first attempts to resolve referenced symbols to one of linked in shared libraries & if that fails to one of linked in static libraries -- in a later case code from the static library is copied into the output.
With that in mind, in the weird scenario of static gRPC/dynamic OTEL libraries mix, what happens is - bulk of gPRC library code is embedded into
opentelemetry_exporter_otlp_grpc_client
and all other otlp libs [which are dependent on_client
] reference gRPC code from the_client
.so and not explicitly linked static gRPC library.There is a potential issue if, say, both
opentelemetry_exporter_otlp_grpc_log
&opentelemetry_exporter_otlp_grpc_metrics
call certain function that is not called insideopentelemetry_exporter_otlp_grpc_client
-- in that case both_log
&_metrics
may get a copy of some gRPC lib code. Fortunately there are no gRPC symbols like that at this point, but maybe it is indeed safer to declare gRPC lib as common PUBLIC dependency as I originally suggested?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can not link static gRPC into more than one dynamic libraries and executable. There will be more than one copy of some global variables in gRPC and some of them will be initialized more than once and some will not be initialized for ever.So the solution is just link gRPC into one dynamic library, that is
opentelemetry_exporter_otlp_grpc_client
, other libraries should only use the API fromopentelemetry_exporter_otlp_grpc_client
and can not use gRPC APIs directly.Here is a simple sample to reproduce the problem in gRPC.
a.h
a.cpp
b.cpp
c.cpp
Compile and run
As you see, the global variable
0x55af97755338
is constructed twice and destroyed twice,And the internal API use differentstatic bar s_;
. I didn't test it on macOS but i guess it has the same problem.It's more complicated in gRPC and it will make gRPC do not work in some dynamic libraries.Actually, if we set gRPC as private dependency of
opentelemetry_exporter_otlp_grpc_client
, and when we buildopentelemetry_exporter_otlp_grpc_client
into a static library. All the targets will links gRPC automatically by just linkopentelemetry_exporter_otlp_grpc_client
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@owent Thanks for the test - I will play with it soon.
In a mean time here is another idea: anything particularly wrong with combining all
_otlp_grpc_
libraries into a singleopentelemetry_exporter_otlp_grpc
library?And one more thing: if static gRPC library can only be linked into one DLL then any application that use gRPC [either directly or indirectly via, say, third party dependency] will be in conflict with
otlp_grpc
libraries. Which logically means that use of static gRPC libraries is a bad idea. Right?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer spilt modules one by one personally, the build system may built all libraries but most users will use only part of them.
It will cost more memory and CPU if we pack all codes into one library, we have a project which will cost about 8+GB memory to link every executable in this project and it's easy OOM when we link them concurrency.We have done many jobs to split dependencies into small libraries to solve this problem.
Yes, in my understanding, it's safer to use static or dynamic libraries for all dependencies, not mixed. There were issues report this problem when only use otlp-cpp, so I think the only thing we can do is keep it right when users only use and link otlp-cpp’s SDK.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ays7 - Do you have any questions on above comments?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lalitb Sorry, I don't think I see a way out: static linking gRPC is a bad idea one way or another. IMHO.
Looks like @owent is exploring some alternatives with PR #2005 -- perhaps this PR can be abandoned [as long as #2005 fixes mac build too]