Repository navigation
Register C globals holding Ruby objects with the GC - #611
Merged
Merged
Conversation
Contributor
|
ci failed, Does this need to be conditional for ruby 3.2+? |
Contributor
Author
|
Yes, good catch @aharpervc. |
plribeiro3000
force-pushed
the
register-globals-with-gc
branch
from
September 30, 2026 22:27
7ab12b9 to
2fa810b
Compare
CoderJoshDK
approved these changes
Oct 1, 2026
andyundso
reviewed
Oct 1, 2026
Comment on lines
+11
to
+14
| mTinyTds = rb_define_module("TinyTds"); | ||
| cTinyTdsError = rb_const_get(mTinyTds, rb_intern("Error")); | ||
| rb_global_variable(&mTinyTds); | ||
| rb_global_variable(&cTinyTdsError); |
Member
There was a problem hiding this comment.
small thing here: can you call rb_global_variable directly after the assignment of mTinyTds?
Contributor
Author
There was a problem hiding this comment.
Done, each rb_global_variable now comes right after the assignment it registers, so mTinyTds is registered before cTinyTdsError is looked up. This also matches how client.c and result.c already do it. Amended into df658bc.
The extension keeps TinyTds::Error, TinyTds, TinyTds::Client, TinyTds::Result, Kernel and Date in C globals that were never registered with the GC. After compaction cTinyTdsError could point to a moved object, so the next FreeTDS message or error handled by rb_tinytds_raise_error crashed the process with a segmentation fault instead of raising TinyTds::Error. Register each of them with rb_global_variable, the same way opt_escape_regex and the opt_* values already are, and add a regression test that forces compaction before a failing connection. Fixes rails-sqlserver#608
plribeiro3000
force-pushed
the
register-globals-with-gc
branch
from
October 1, 2026 20:43
2fa810b to
df658bc
Compare
andyundso
approved these changes
Oct 2, 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.
Summary
tiny_tds_ext.c,client.candresult.ckeepTinyTds,TinyTds::Error,TinyTds::Client,TinyTds::Result,KernelandDatein C globals that were never registered with the GC.cTinyTdsErrorcan point to a moved object, so the next FreeTDS message or error handled byrb_tinytds_raise_errorcrashes the process with a segmentation fault instead of raisingTinyTds::Error.rb_global_variable, the same wayopt_escape_regex,opt_escape_dblquoteand theopt_*values inresult.calready are.Test
test/gc_compaction_test.rbruns the minimal repro from #608 in a subprocess: it forces compaction withGC.verify_compaction_referencesand connects to a closed port. It needs no SQL Server and is skipped where compaction is unsupported.Verified locally on macOS, Ruby 4.0.6, FreeTDS 1.5.4:
SIGSEGV(rb_exc_new->unexpected_type)TinyTds::Erroris raised and the test passesbundle exec rake formatleaves the C files unchanged.Fixes #608