merge revision(s) c224ca4fea: [Backport #21172]

Fix a race condition with interned strings sweeping.

	[Bug #21172]

	This fixes a rare CI failure.

	The timeline of the race condition is:

	- A `"foo" oid=1` string is interned.
	- `"foo" oid=1` is no longer referenced and will be swept in the future.
	- Another `"foo" oid=2` string is interned.
	- `register_fstring` finds `"foo" oid=1`, but since it is about to be swept,
	  removes it from `fstring_table` and insert `"foo" oid=2` instead.
	- `"foo" oid=1` is swept, since it has the `RSTRING_FSTR` flag,
	  a `st_delete` is issued in `fstring_table` which removes `"foo" oid=2`.

	I don't know how to reproduce this bug consistently in a single test
	case.
This commit is contained in:
nagachika 2025-03-16 18:02:45 +09:00
parent 1d3c19871d
commit 726bff43b4
2 changed files with 5 additions and 1 deletions

View file

@ -344,6 +344,10 @@ fstr_update_callback(st_data_t *key, st_data_t *value, st_data_t data, int exist
if (rb_objspace_garbage_object_p(str)) {
arg->fstr = Qundef;
// When RSTRING_FSTR strings are swept, they call `st_delete`.
// To avoid a race condition if an equivalent string was inserted
// we must remove the flag immediately.
FL_UNSET_RAW(str, RSTRING_FSTR);
return ST_DELETE;
}

View file

@ -11,7 +11,7 @@
# define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
#define RUBY_VERSION_TEENY 7
#define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
#define RUBY_PATCHLEVEL 131
#define RUBY_PATCHLEVEL 132
#include "ruby/version.h"
#include "ruby/internal/abi.h"