When your hash becomes a string: Hunting Ruby's million-to-one memory bug
Разработчик Ruby-гема Karafka столкнулся с редким, но критическим багом, когда 2700 идентичных ошибок NoMethodError: undefined method 'default' for an instance of String обрушили систему. Ошибка возникала при доступе к elem[:partition] в FFI::Struct, хотя код нигде не использовал метод #default, характерный для Hash.
Исследование показало, что проблема в версиях FFI ниже 1.17.0, где отсутствуют write-барьеры, позволяющие сборщику мусора Ruby освобождать внутренние Hash-объекты. После освобождения память могла перераспределяться под другие объекты, например, строки. Баг проявляется с вероятностью "один к миллиону", но катастрофичен по последствиям. Пользователи использовали Alpine Linux с musl libc, что могло усугубить ситуацию из-за особенностей компиляции и выравнивания структур.