Skip to content

Conversation

@carlhoerberg
Copy link
Member

Summary

  • Fixes GC finalization cycle warnings in SNI callback implementation
  • Moves callback box storage from instance variables to class-level hash
  • Adds explicit cleanup in finalize method

Problem

The SNI callback implementation was causing "GC Warning: Finalization cycle involving (???)" warnings during specs. This occurred because:

  • Contexts held callback boxes through instance variable @sni_callback_box
  • Callbacks could return other contexts
  • All contexts have finalizers for OpenSSL cleanup
  • This created circular finalization dependencies the GC couldn't resolve

Solution

Changed callback storage from instance variables to class-level hash:

  • @@sni_callback_boxes stores boxes keyed by context handle
  • Contexts only hold primitive handle pointers, not direct callback references
  • Breaks finalization cycle since callbacks live outside context object graph
  • Added finalize method to explicitly free callback boxes and clean up storage

Test plan

  • make test SPEC=spec/sni_spec.cr - 10 examples, 0 failures, 0 GC warnings
  • make test SPEC=spec/stdlib/openssl_keylog_spec.cr - 0 GC warnings
  • Full test suite passes

🤖 Generated with Claude Code

The SNI callback storage was causing finalization cycle warnings because
contexts directly referenced callback boxes through instance variables,
while the callbacks themselves could return other contexts, creating
circular dependencies that the GC couldn't safely finalize.

This fix moves callback box storage from instance variables to a
class-level hash keyed by context handle. This breaks the finalization
cycle because contexts no longer directly reference the callbacks through
their object graph - they only hold primitive handle pointers.

When a context is finalized, it looks up and explicitly frees its
callback box from the class storage, ensuring proper cleanup without
circular dependencies.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
@carlhoerberg carlhoerberg requested a review from a team as a code owner December 16, 2025 14:32
@claude
Copy link

claude bot commented Dec 16, 2025

Claude finished @carlhoerberg's task —— View job


Code Review Complete

Todo List:

  • Read and analyze src/stdlib/openssl_sni.cr
  • Check for potential issues
  • Report findings

Issues Found

Memory leak potential in finalize method (src/stdlib/openssl_sni.cr:94):

GC.free(callback_box)

Calling GC.free on a boxed value is incorrect and potentially dangerous. Boxed values should be freed with Box.free, not GC.free. The current implementation could lead to undefined behavior or corruption.

Suggested fix:

Box(Proc(String, OpenSSL::SSL::Context::Server?)).free(callback_box)

@carlhoerberg carlhoerberg marked this pull request as draft December 17, 2025 18:58
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.

3 participants