open-telemetry / open-telemetry/opentelemetry-cpp
thread_local TracerProvider with BatchSpanProcessorFactory causes thread to hang
@marcalff is already working on this.
Since Mar 24, 2025.
- Dominant language
- C++
- Stars
- 1.4k
- Forks
- 632
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 75
Description
Describe your environment
OpenTelemetry-cpp 1.19.0
ISO C++ 14, Legacy MSVC.
Steps to reproduce
create a thread_local unique_ptr to a TracerProvider that uses a BatchSpanProcessor, and have the thread end without explicitly freeing the provider.
MRP:
#include <iostream>
#include <thread>
#include <opentelemetry/exporters/ostream/span_exporter_factory.h>
#include <opentelemetry/sdk/trace/batch_span_processor_factory.h>
#include <opentelemetry/sdk/trace/tracer_provider_factory.h>
namespace trace = opentelemetry::sdk::trace;
thread_local std::unique_ptr<trace::TracerProvider> provider;
void workerThread() {
auto exporter = opentelemetry::exporter::trace::OStreamSpanExporterFactory::Create(std::cout);
trace::BatchSpanProcessorOptions processorOptions;
auto processor = trace::BatchSpanProcessorFactory::Create(std::move(exporter), processorOptions);
provider = trace::TracerProviderFactory::Create(std::move(processor));
std::cout << "Provider created\n";
}
int main()
{
auto thread = std::thread(workerThread);
thread.join();
std::cout << "Thread joined\n"; //Execution never reaches this point
}
What is the expected behavior?
The thread should cleanly shutdown the tracer provider and batch span processor on exit.
What is the actual behavior?
The thread appears to deadlock during the implicit BatchSpanProcessor::Shutdown call.
Additional context
Trying to add some telemetry gathering to an application via a dll wrapping opentelemetry-cpp.
The nature of the application means that it uses multiple threads that functionally act as their own processes, so each thread has its own TracerProvider.
It's possible for these threads to end without notice being given to the dll, so we don't get a chance to cleanup the TracerProvider (ie. call provider.reset() in the above code)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.