Skip to content

[SDK] Add destructor to PeriodicExportingMetricReader to fix shutdown race#4008

Open
jnillius wants to merge 5 commits intoopen-telemetry:mainfrom
jnillius:fix/periodic-metric-reader-destructor
Open

[SDK] Add destructor to PeriodicExportingMetricReader to fix shutdown race#4008
jnillius wants to merge 5 commits intoopen-telemetry:mainfrom
jnillius:fix/periodic-metric-reader-destructor

Conversation

@jnillius
Copy link
Copy Markdown

@jnillius jnillius commented Apr 16, 2026

Fixes #4007

Changes

Destroying a PeriodicExportingMetricReader without calling Shutdown()
leaves the background worker thread running inside cv_.wait_for() while
the mutex and condition variable members are destroyed. This causes a
use-after-destroy race detected by ThreadSanitizer.

Add an explicit destructor that calls Shutdown() and joins the worker
thread before member destruction, matching the pattern already used by
BatchSpanProcessor and BatchLogRecordProcessor.

Add a DestroyWithoutShutdown test to verify safe destruction without
an explicit Shutdown() call.

  • CHANGELOG.md updated for non-trivial changes
  • Unit tests have been added
  • Changes in public API reviewed — the only addition is the destructor declaration in the header; no existing API is changed

@jnillius jnillius requested a review from a team as a code owner April 16, 2026 13:48
@linux-foundation-easycla
Copy link
Copy Markdown

linux-foundation-easycla bot commented Apr 16, 2026

CLA Signed

The committers listed above are authorized under a signed CLA.

… race

Destroying a PeriodicExportingMetricReader without calling Shutdown()
leaves the background worker thread running inside cv_.wait_for() while
the mutex and condition variable members are destroyed. This causes a
use-after-destroy race detected by ThreadSanitizer.

Add an explicit destructor that calls Shutdown() and joins the worker
thread before member destruction, matching the pattern already used by
BatchSpanProcessor and BatchLogRecordProcessor.

Add a DestroyWithoutShutdown test to verify safe destruction without
an explicit Shutdown() call.
@jnillius jnillius force-pushed the fix/periodic-metric-reader-destructor branch from d2f7139 to 19f4a24 Compare April 16, 2026 13:51
@codecov
Copy link
Copy Markdown

codecov bot commented Apr 16, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 90.32%. Comparing base (07d40f5) to head (a43f14f).

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #4008      +/-   ##
==========================================
+ Coverage   90.32%   90.32%   +0.01%     
==========================================
  Files         230      230              
  Lines        7298     7302       +4     
==========================================
+ Hits         6591     6595       +4     
  Misses        707      707              
Files with missing lines Coverage Δ
...metrics/export/periodic_exporting_metric_reader.cc 78.36% <100.00%> (+0.94%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@marcalff marcalff added the pr:waiting-on-cla Waiting on CLA label Apr 16, 2026
@marcalff
Copy link
Copy Markdown
Member

@jnillius

Thanks for the bug report and fix.

Please sign the EasyCLA, and fix clang-format.

Copy link
Copy Markdown
Member

@dbarker dbarker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! Thanks for the PR. Please see feedback below on some minor points.

Comment thread sdk/test/metrics/periodic_exporting_metric_reader_test.cc Outdated
Comment thread sdk/src/metrics/export/periodic_exporting_metric_reader.cc Outdated
@ThomsonTan
Copy link
Copy Markdown
Contributor

Add an entry to CHANGELOG.md?

jnillius pushed a commit to jnillius/opentelemetry-cpp that referenced this pull request Apr 17, 2026
jnillius added a commit to jnillius/opentelemetry-cpp that referenced this pull request Apr 17, 2026
@jnillius jnillius force-pushed the fix/periodic-metric-reader-destructor branch from 6ddc6de to c4dc458 Compare April 17, 2026 06:22
@marcalff marcalff removed the pr:waiting-on-cla Waiting on CLA label Apr 17, 2026
jnillius added a commit to jnillius/opentelemetry-cpp that referenced this pull request Apr 17, 2026
@jnillius jnillius force-pushed the fix/periodic-metric-reader-destructor branch from c4dc458 to 6948bb0 Compare April 17, 2026 08:02
Copy link
Copy Markdown
Member

@marcalff marcalff left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please fix clang-format.

LGTM otherwise.

Copy link
Copy Markdown
Member

@dbarker dbarker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. Nice work.

- Delete copy/move constructors and assignment operators to satisfy
  cppcoreguidelines-special-member-functions (Rule of Five).
- Remove redundant worker_thread_.join() from destructor; Shutdown()
  already calls OnShutDown() which joins the thread.
- Use std::make_unique in DestroyWithoutShutdown test.
@jnillius jnillius force-pushed the fix/periodic-metric-reader-destructor branch from 6948bb0 to 00cfffb Compare April 17, 2026 13:44
Copy link
Copy Markdown
Member

@marcalff marcalff left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for the contribution.


PeriodicExportingMetricReader::~PeriodicExportingMetricReader()
{
if (!IsShutdown())
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this IsShutdown() check needed? Shutdown() is already idempotent on MetricReader. The only effect of this guard is to suppress the
"Cannot invoke shutdown twice!" warning. Worth a short
comment explaining that, or drop the guard to match the
BatchSpanProcessor dtor pattern.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PeriodicExportingMetricReader: missing destructor causes use-after-destroy race (ThreadSanitizer)

4 participants