fix(tracer): prevent stale ctx.tracing crash on HTTPS keepalive connections#13232
Open
janiussyafiq wants to merge 3 commits intoapache:masterfrom
Open
fix(tracer): prevent stale ctx.tracing crash on HTTPS keepalive connections#13232janiussyafiq wants to merge 3 commits intoapache:masterfrom
janiussyafiq wants to merge 3 commits intoapache:masterfrom
Conversation
Baoyuantop
approved these changes
Apr 17, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Description
When
apisix.tracingis enabled, the core tracer instruments every request phase — includingssl_client_hello_phase— by allocating a tracing table fromlua-tablepooland storing it inngx.ctx.tracing. On HTTPS keepalive connections, OpenResty reuses the samengx.ctxobject across multiple HTTP requests on the same TLS session.The bug occurs in the following sequence:
ssl_client_hello_phasecallstracer.start(), which allocatesctx.tracingvia tablepool and initialisestracing.spans.tracer.release()is called in the log phase, returning the tracing table to the pool.lua-tablepoolinternally callstable.clear()on release, zeroing all fields —tracing.spansbecomesnil— butctx.tracingstill holds a reference to this now-cleared table.tracer.start()findsctx.tracingis non-nil (a cleared table is still truthy in Lua) and skips re-initialisation.span.new()then crashes attable.insert(tracing.spans, self)becausespansisnil.This fix addresses the root cause at two layers:
tracer.start(): The initialisation guard is extended fromif not tracing thentoif not tracing or not tracing.spans then. Sincelua-tablepoolalways zeroestracing.spanson release viatable.clear(), this reliably detects a stale or cleared tracing table and re-initialises it correctly — including on HTTPS keepalive second requests and any diverged HTTP/2 contexts.tracer.release(): Aif spans thenguard is added before iterating and releasing the spans table, making release safe even when called on a partially-cleared state. The explicit nil assignments are intentionally avoided to preserve the tablepool contract — re-allocation and de-allocation of tables is expensive, andlua-tablepoolalready handles clearing internally.Which issue(s) this PR fixes:
Fixes #13200
Checklist
t/node/tracer.t)