Skip to content

Conversation

@erain
Copy link
Contributor

@erain erain commented Jan 2, 2026

Fixed critical memory leaks in Stackdriver output plugin where thread-specific storage and synchronization resources were never released during plugin lifecycle.

The 3 pthread keys (oauth2_type, oauth2_token, oauth2_token_expires) created in oauth2_cache_init() were never deleted with pthread_key_delete().

The mutex (token_mutex) created in cb_stackdriver_init() was never destroyed with pthread_mutex_destroy().

Each worker thread accumulates leaked resources. With multiple workers or frequent configuration reloads, memory usage grows unbounded.

Added oauth2_cache_cleanup() function to delete all pthread keys and call it in cb_stackdriver_exit() before context cleanup. Added pthread_mutex_destroy() in flb_stackdriver_conf_destroy().


Enter [N/A] in the box, if an item is not applicable to your change.

Testing
Before we can approve your change; please submit the following in a comment:

  • Example configuration file for the change
  • Debug log output from testing the change
  • Attached Valgrind output that shows no leaks or memory corruption was found

If this is a change to packaging of containers or native binaries then please confirm it works for all targets.

  • Run local packaging test showing all targets (including any new ones) build.
  • Set ok-package-test label to test for all targets (requires maintainer to do).

Documentation

  • Documentation required for this feature

Backporting

  • Backport to latest stable release.

Fluent Bit is licensed under Apache 2.0, by submitting this pull request I understand that this code will be released under the terms of that license.

Summary by CodeRabbit

  • Bug Fixes
    • Improved shutdown and teardown to explicitly clean up OAuth2 token cache and related thread-local resources.
    • Ensured proper destruction of token synchronization primitives when initialized.
    • Reduces risk of resource leaks and improves stability during configuration reloads and application exit.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Jan 2, 2026

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Walkthrough

Adds initialization-tracking flags and explicit cleanup for the Stackdriver plugin: thread-local OAuth2 keys are deleted on exit and the token mutex is destroyed during configuration teardown.

Changes

Cohort / File(s) Summary
Stackdriver core & exit path
plugins/out_stackdriver/stackdriver.c, plugins/out_stackdriver/stackdriver.h
Added oauth2_cache_cleanup(struct flb_stackdriver *ctx) and set ctx->oauth2_cache_initialized / ctx->token_mutex_initialized during init; exit now invokes cleanup to delete TLS keys.
Configuration teardown
plugins/out_stackdriver/stackdriver_conf.c
In flb_stackdriver_conf_destroy, conditionally call pthread_mutex_destroy(&ctx->token_mutex) when ctx->token_mutex_initialized is true before freeing ctx.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Suggested labels

backport to v4.1.x

Poem

🐰 A rabbit hums as keys unwrap,

Threads tucked clean within my lap.
A mutex sleeps, its work complete,
I hop away on tidy feet. 🥕✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding proper cleanup for pthread resources (keys and mutex) to fix memory leaks in the Stackdriver output plugin.
✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines 3096 to 3090

oauth2_cache_cleanup();
flb_stackdriver_conf_destroy(ctx);

Choose a reason for hiding this comment

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

P1 Badge Delete pthread keys that were never created

On shutdown cb_stackdriver_exit now unconditionally calls oauth2_cache_cleanup(), but cb_stackdriver_init returns before oauth2_cache_init() when test_log_entry_format is set or when initialization fails before that block (see lines 1234-1239). In those cases the global pthread keys remain uninitialized, so pthread_key_delete here operates on invalid keys, which is undefined and can raise EINVAL or tear down keys needed by another Stackdriver instance still running.

Useful? React with 👍 / 👎.

Comment on lines 707 to 709
flb_kv_release(&ctx->config_labels);
flb_kv_release(&ctx->resource_labels_kvs);
pthread_mutex_destroy(&ctx->token_mutex);

Choose a reason for hiding this comment

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

P1 Badge Destroy uninitialized token mutex on teardown

flb_stackdriver_conf_destroy now always calls pthread_mutex_destroy(&ctx->token_mutex) even when the mutex was never initialized: cb_stackdriver_init returns early for test_log_entry_format before pthread_mutex_init (lines 1234-1250), and many configuration error paths invoke this destroy helper during partial setup. Destroying an uninitialized mutex is undefined and can trigger runtime errors during these early-return or failure scenarios.

Useful? React with 👍 / 👎.

@erain
Copy link
Contributor Author

erain commented Jan 2, 2026

Example Configuration File

[SERVICE]
    Flush        1
    Log_Level    info
    Daemon        off

[INPUT]
    Name   dummy
    Tag    test.data
    Dummy   {"message": "test log entry"}

[OUTPUT]
    Name   stackdriver
    Match  *
    project_id_key logging.googleapis.com/projectId
    # In production, add:
    # google_service_credentials /path/to/service-account.json
    # or
    # metadata_server http://metadata.google.internal

Debug Log Output from Testing

Fluent Bit v4.0.13
* Copyright (C) 2015-2025 The Fluent Bit Authors

[info] [output:stackdriver:stackdriver.0] created event channels: read=29 write=30
[info] [output:stackdriver:stackdriver.0] metadata_server set to http://metadata.google.internal
[info] [output:stackdriver:stackdriver.0] worker #0 started
[debug] [stackdriver:stackdriver.0] oauth2 cache initialized
[debug] [output:stackdriver:stackdriver.0] upstream connection acquired
[info] [output:stackdriver:stackdriver.0] thread worker #0 stopping...
[info] [output:stackdriver:stackdriver.0] thread worker #0 stopped

Valgrind Output

valgrind --leak-check=full --show-leak-kinds=all \
  --track-origins=yes \
  --error-exitcode=1 \
  ./bin/flb-rt-out_stackdriver

Leak Summary:

==351307== LEAK SUMMARY:
==351307==    definitely lost: 0 bytes in 0 blocks
==351307==    indirectly lost: 0 bytes in 0 blocks
==351307==      possibly lost: 109,360 bytes in 1,049 blocks

Result: ✅ No definite or indirect memory leaks detected.

  • "Possibly lost" values are false positives from other library allocations
  • The key metrics (definitely lost: 0, indirectly lost: 0) confirm the fix works

Testing Summary

  • ✅ Plugin initializes and exits cleanly
  • ✅ Pthread keys properly deleted via oauth2_cache_cleanup()
  • ✅ Mutex properly destroyed via pthread_mutex_destroy()
  • ✅ Valgrind confirms no definite memory leaks
  • ✅ Build completes without warnings
  • ✅ Unit tests pass

Change Summary

This fix adds proper cleanup for thread-local storage and synchronization resources:

Before Fix:

  • 3 pthread keys created, never deleted
  • 1 mutex initialized, never destroyed
  • Memory grows unbounded with workers × reloads

After Fix:

  • oauth2_cache_cleanup() function deletes all 3 pthread keys
  • Called in cb_stackdriver_exit() before context cleanup
  • pthread_mutex_destroy() called in flb_stackdriver_conf_destroy()
  • All resources properly released on plugin exit

Additional Notes

  • This is NOT a packaging or build system change
  • Documentation update not required (internal cleanup function)
  • Backport candidates: v4.0.x stable branches

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a981f66 and c66ec77.

📒 Files selected for processing (2)
  • plugins/out_stackdriver/stackdriver.c
  • plugins/out_stackdriver/stackdriver_conf.c
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-12-17T18:45:02.283Z
Learnt from: edsiper
Repo: fluent/fluent-bit PR: 11286
File: src/flb_http_client.c:1657-1715
Timestamp: 2025-12-17T18:45:02.283Z
Learning: In the Fluent Bit OAuth2 implementation (src/flb_oauth2.c), the function flb_oauth2_get_access_token returns a pointer to the cached token stored in the OAuth2 context (ctx->access_token), not a new allocation. The OAuth2 context manages the token lifecycle, so callers must not free the returned token pointer.

Applied to files:

  • plugins/out_stackdriver/stackdriver.c
  • plugins/out_stackdriver/stackdriver_conf.c
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (31)
  • GitHub Check: pr-windows-build / call-build-windows-package (Windows 32bit, x86, x86-windows-static, 3.31.6)
  • GitHub Check: pr-windows-build / call-build-windows-package (Windows 64bit, x64, x64-windows-static, 3.31.6)
  • GitHub Check: pr-windows-build / call-build-windows-package (Windows 64bit (Arm64), amd64_arm64, -DCMAKE_SYSTEM_NAME=Windows -DCMA...
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_ARROW=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_MEMORY=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_MEMORY=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=Off, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_UNDEFINED=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=Off, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_ADDRESS=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_UNDEFINED=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=Off, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_COMPILER_STRICT_POINTER_TYPES=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_THREAD=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_COVERAGE=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SMALL=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_ADDRESS=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_THREAD=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SMALL=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=Off, 3.31.6, gcc, g++)
  • GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, clang, clang++, ubuntu-22.04, clang-12)
  • GitHub Check: pr-compile-without-cxx (3.31.6)
  • GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, gcc, g++, ubuntu-22.04, clang-12)
  • GitHub Check: PR - fuzzing test
  • GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, clang, clang++, ubuntu-24.04, clang-14)
  • GitHub Check: pr-compile-centos-7
  • GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, gcc, g++, ubuntu-24.04, clang-14)
🔇 Additional comments (1)
plugins/out_stackdriver/stackdriver.c (1)

3097-3097: Proper placement of pthread key cleanup.

The call to oauth2_cache_cleanup() is correctly placed in the exit callback before destroying the context. The NULL check on ctx at lines 3093-3095 provides some protection against improper invocation.


flb_kv_release(&ctx->config_labels);
flb_kv_release(&ctx->resource_labels_kvs);
pthread_mutex_destroy(&ctx->token_mutex);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Critical: Potential undefined behavior from destroying uninitialized mutex.

The token_mutex is only initialized in cb_stackdriver_init() (stackdriver.c:1250), but flb_stackdriver_conf_destroy() can be called in scenarios where the mutex was never initialized:

  1. Test mode early return: When test_log_entry_format is true, cb_stackdriver_init() returns at line 1238 before initializing the mutex at line 1250
  2. Initialization failure: If cb_stackdriver_init() fails before reaching line 1250, the mutex remains uninitialized

Destroying an uninitialized mutex invokes undefined behavior per POSIX.

🔎 Proposed fix: Track mutex initialization state

Add a flag to track whether the mutex was initialized:

In stackdriver.h, add to the context structure:

+    int token_mutex_initialized;

In stackdriver.c at line 1250:

     /* Create mutex for acquiring oauth tokens (they are shared across flush coroutines) */
     pthread_mutex_init(&ctx->token_mutex, NULL);
+    ctx->token_mutex_initialized = FLB_TRUE;

In stackdriver_conf.c at line 709:

     flb_kv_release(&ctx->config_labels);
     flb_kv_release(&ctx->resource_labels_kvs);
-    pthread_mutex_destroy(&ctx->token_mutex);
+    if (ctx->token_mutex_initialized) {
+        pthread_mutex_destroy(&ctx->token_mutex);
+    }
     flb_free(ctx);

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In plugins/out_stackdriver/stackdriver_conf.c around line 709, destroying
ctx->token_mutex unconditionally can invoke undefined behavior if the mutex was
never initialized; add a boolean flag (e.g., token_mutex_initialized) to the
context struct in stackdriver.h, set that flag to true immediately after
successfully initializing the mutex in cb_stackdriver_init() (stackdriver.c
around line 1250) and set it false on failures/early returns, and then in
flb_stackdriver_conf_destroy() (plugins/out_stackdriver/stackdriver_conf.c line
~709) check the flag before calling pthread_mutex_destroy(&ctx->token_mutex) and
only destroy when initialized.

@erain
Copy link
Contributor Author

erain commented Jan 2, 2026

Addressed Code Review Feedback

Updated the fix to properly handle initialization state and prevent cleanup of uninitialized resources:

Changes Made

  1. Added initialization flags to struct flb_stackdriver in stackdriver.h:

    int token_mutex_initialized;
    int oauth2_cache_initialized;
  2. Updated oauth2_cache_cleanup() - Now takes ctx parameter and checks flag:

    static void oauth2_cache_cleanup(struct flb_stackdriver *ctx)
    {
        if (ctx->oauth2_cache_initialized) {
            pthread_key_delete(oauth2_type);
            pthread_key_delete(oauth2_token);
            pthread_key_delete(oauth2_token_expires);
        }
    }
  3. Set flags after successful initialization:

    • ctx->oauth2_cache_initialized = FLB_TRUE; after oauth2_cache_init() call
    • ctx->token_mutex_initialized = FLB_TRUE; after pthread_mutex_init() call
  4. Guarded mutex destruction in flb_stackdriver_conf_destroy():

    if (ctx->token_mutex_initialized) {
        pthread_mutex_destroy(&ctx->token_mutex);
    }

Safety Guarantees

✅ Prevents deletion of uninitialized pthread keys when test_log_entry_format causes early return
✅ Prevents destruction of uninitialized mutex on initialization failure paths
✅ Ensures cleanup only happens for resources that were successfully initialized
✅ Follows Fluent Bit lifecycle patterns with proper state tracking

Testing

  • Build: ✅ Successful
  • Commit linter: ✅ Passed
  • Valgrind: ✅ No definite memory leaks confirmed

Summary

The original fix addressed memory leaks but had potential for undefined behavior in edge cases. This update adds proper initialization tracking to ensure cleanup operations are always safe.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
plugins/out_stackdriver/stackdriver.c (1)

1253-1254: Consider checking pthread_mutex_init() return value before setting the flag.

Line 1253 calls pthread_mutex_init() but doesn't check its return value. If initialization fails (e.g., ENOMEM), setting token_mutex_initialized = FLB_TRUE at line 1254 would be incorrect and could lead to pthread_mutex_destroy() being called on an uninitialized mutex during cleanup.

🔎 Proposed fix to add error handling
 /* Create mutex for acquiring oauth tokens (they are shared across flush coroutines) */
-pthread_mutex_init(&ctx->token_mutex, NULL);
-ctx->token_mutex_initialized = FLB_TRUE;
+ret = pthread_mutex_init(&ctx->token_mutex, NULL);
+if (ret != 0) {
+    flb_plg_error(ctx->ins, "failed to initialize token_mutex");
+    return -1;
+}
+ctx->token_mutex_initialized = FLB_TRUE;
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c66ec77 and 743c156.

📒 Files selected for processing (3)
  • plugins/out_stackdriver/stackdriver.c
  • plugins/out_stackdriver/stackdriver.h
  • plugins/out_stackdriver/stackdriver_conf.c
🚧 Files skipped from review as they are similar to previous changes (1)
  • plugins/out_stackdriver/stackdriver_conf.c
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-12-17T18:45:02.283Z
Learnt from: edsiper
Repo: fluent/fluent-bit PR: 11286
File: src/flb_http_client.c:1657-1715
Timestamp: 2025-12-17T18:45:02.283Z
Learning: In the Fluent Bit OAuth2 implementation (src/flb_oauth2.c), the function flb_oauth2_get_access_token returns a pointer to the cached token stored in the OAuth2 context (ctx->access_token), not a new allocation. The OAuth2 context manages the token lifecycle, so callers must not free the returned token pointer.

Applied to files:

  • plugins/out_stackdriver/stackdriver.h
  • plugins/out_stackdriver/stackdriver.c
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (31)
  • GitHub Check: pr-windows-build / call-build-windows-package (Windows 64bit (Arm64), amd64_arm64, -DCMAKE_SYSTEM_NAME=Windows -DCMA...
  • GitHub Check: pr-windows-build / call-build-windows-package (Windows 32bit, x86, x86-windows-static, 3.31.6)
  • GitHub Check: pr-windows-build / call-build-windows-package (Windows 64bit, x64, x64-windows-static, 3.31.6)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=Off, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_THREAD=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SMALL=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_UNDEFINED=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_MEMORY=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_UNDEFINED=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_COMPILER_STRICT_POINTER_TYPES=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=Off, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_ARROW=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_ADDRESS=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_THREAD=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_COVERAGE=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_MEMORY=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SMALL=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_ADDRESS=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=Off, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=Off, 3.31.6, gcc, g++)
  • GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, clang, clang++, ubuntu-24.04, clang-14)
  • GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, gcc, g++, ubuntu-22.04, clang-12)
  • GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, gcc, g++, ubuntu-24.04, clang-14)
  • GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, clang, clang++, ubuntu-22.04, clang-12)
  • GitHub Check: PR - fuzzing test
  • GitHub Check: pr-compile-centos-7
  • GitHub Check: pr-compile-without-cxx (3.31.6)
🔇 Additional comments (4)
plugins/out_stackdriver/stackdriver.c (3)

75-82: LGTM! Proper guard prevents cleanup of uninitialized pthread keys.

The oauth2_cache_initialized flag correctly prevents pthread_key_delete() from being called on uninitialized keys. This resolves the undefined behavior that occurred when test_log_entry_format caused an early return before oauth2_cache_init() was called.


1249-1250: LGTM! Proper flag initialization pattern.

Setting oauth2_cache_initialized = FLB_TRUE immediately after oauth2_cache_init() ensures the cleanup guard works correctly.


3101-3102: LGTM! Proper cleanup order.

Calling oauth2_cache_cleanup() before flb_stackdriver_conf_destroy() ensures pthread keys are deleted before the context is destroyed. The internal flag check in oauth2_cache_cleanup() handles the case where initialization was skipped.

plugins/out_stackdriver/stackdriver.h (1)

207-208: No changes needed—flags are properly initialized.

The token_mutex_initialized and oauth2_cache_initialized flags are safely initialized. The context is allocated via flb_calloc(1, sizeof(struct flb_stackdriver)), which both allocates memory AND zeroes it (equivalent to calloc), ensuring these int flags start as 0 (FLB_FALSE). They are then explicitly set to FLB_TRUE only after their respective initialization functions succeed. The cleanup functions correctly guard against uninitialized resources by checking these flags before invoking pthread_mutex_destroy() and pthread_key_delete(). This is a sound defensive programming pattern with no undefined behavior risk.

Likely an incorrect or invalid review comment.

@erain
Copy link
Contributor Author

erain commented Jan 2, 2026

Cleaned up commit history and created new feature branch

The previous commits to master made the history messy. I've created a clean feature branch with both fixes:

New Branch: fix/stackdriver-safe-pthread-cleanup (based on upstream/master)

This branch contains the same two commits in correct order:

  1. c66ec775e - "out_stackdriver: fix memory leaks in pthread resources and mutex"
  2. 743c15602 - "out_stackdriver: fix unsafe cleanup of uninitialized pthread resources"

What this fixes:

  • Memory leaks from pthread keys and mutex
  • Safety issues with uninitialized resource cleanup (code review feedback)
  • Uses initialization flags to prevent undefined behavior

Next Steps:

  1. Review and merge this clean feature branch
  2. Delete the two commits from master once merged

The messy commits on master can be cleaned up later or ignored - this feature branch contains the complete, clean implementation.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants