Skip to content

Exporting spans from inside DLL on Windows does not work. #3176

@rsomla1

Description

@rsomla1

This issue is specific to Windows environment and using DLL libraries.

I build a simple executable which sets span exporter and creates a span. It also calls a library function that crates another span. Here is the main executable

int main(int argc, const char* argv[])
try
{
  // Configure trace provider that exports to stdout

  using prv_factory = trace_sdk::TracerProviderFactory;
  using prc_factory = trace_sdk::SimpleSpanProcessorFactory;
  using exp_factory = exporter::trace::OStreamSpanExporterFactory;

  trace::Provider::SetTracerProvider(
    std::shared_ptr<trace::TracerProvider>{
      prv_factory::Create(prc_factory::Create(exp_factory::Create(std::cout)))
    }
  );

  // Get provider and create a span

  auto provider = trace::Provider::GetTracerProvider();
  auto tracer = provider->GetTracer("try", "0.0.1");
  auto span = tracer->StartSpan("main");
  trace::Scope scope{tracer->WithActiveSpan(span)};

  // Call library function that creates another span.
  // Expecting that it will use trace provider configured above.

  foo();

  cout << "Done!" << endl;
}
catch(...) {}

Function foo() defined in a DLL library does this

extern "C" EXPORT void foo()
{
  auto provider = trace::Provider::GetTracerProvider();
  auto tracer = provider->GetTracer("lib", "0.0.1");
  auto span = tracer->StartSpan("foo");

  cout << "foo DONE!" << endl;
}

When I build this code on Linux it produces the expected output with two spans, the "foo" span a child of "main" span:

~/cpp/otel-issue/build./try
foo DONE!
{
  name          : foo
  trace_id      : 79194137338009900a5afe676c2c2471
  span_id       : 6f26aecf124938e5
  tracestate    :   parent_span_id: 0d9ec5b22ac67a29
  start         : 1732718683944699646
  duration      : 24848
  description   :   span kind     : Internal
  status        : Unset
  attributes    :   events        :   links         :   resources     :         service.name: unknown_service
        telemetry.sdk.version: 1.17.0
        telemetry.sdk.language: cpp
        telemetry.sdk.name: opentelemetry
  instr-lib     : lib-0.0.1
}
Done!
{
  name          : main
  trace_id      : 79194137338009900a5afe676c2c2471
  span_id       : 0d9ec5b22ac67a29
  tracestate    :   parent_span_id: 0000000000000000
  start         : 1732718683944630175
  duration      : 216489
  description   :   span kind     : Internal
  status        : Unset
  attributes    :   events        :   links         :   resources     :         service.name: unknown_service
        telemetry.sdk.version: 1.17.0
        telemetry.sdk.language: cpp
        telemetry.sdk.name: opentelemetry
  instr-lib     : try-0.0.1
}

However, if I build and run the same code on Windows the output is as follows without the "foo" span:

C:\Work\MySQL\cpp\build-internals>Release\try.exe
foo DONE!
Done!
{
  name          : main
  trace_id      : c265485eac059ec46d9d170a4f004d81
  span_id       : e615d927b958fde0
  tracestate    :
  parent_span_id: 0000000000000000
  start         : 1732718442900722900
  duration      : 694400
  description   :
  span kind     : Internal
  status        : Unset
  attributes    :
  events        :
  links         :
  resources     :
        telemetry.sdk.language: cpp
        telemetry.sdk.name: opentelemetry
        telemetry.sdk.version: 1.17.0
        service.name: unknown_service
  instr-lib     : try-0.0.1
}

As you can see I am testing with otel 1.17.0. My guess is that in case of Windows the connection between tracer provider configured in the main application and the one obtained inside DLL is broken. Therefore the function inside DLL gets the phony provider which ignores all traces sent to it. This is why the span from foo() is not seen in the Windows output.

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingdo-not-staleissue:blockingThis issue is preventing other fixespriority:p1Issues that are blockingtriage/acceptedIndicates an issue or PR is ready to be actively worked on.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions