Hacker News Digest

Тег: #bug

Постов: 2

When your hash becomes a string: Hunting Ruby's million-to-one memory bug (mensfeld.pl)

Разработчик 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, что могло усугубить ситуацию из-за особенностей компиляции и выравнивания структур.

by phmx • 04 ноября 2025 г. в 12:36 • 119 points

ОригиналHN

#ruby#ffi#memory-management#garbage-collection#bug#alpine-linux#musl-libc

Комментарии (59)

  • Обсуждение выявило, что причиной проблемы была давно исправленная ошибка в ffi, а не в Ruby или в коде клиента.
  • Участники спора оспаривают, стоит ли считать статью «LLM-шлаком» из-за плохого стиля, даже если сама техническая информация в ней точна.
  • Некоторые участники считают, что стиль может быть вызван тем, что автор предпочитает кодить, а не писать, и что технически важная информация была доставлена.
  • Другие участники спора отмечают, что статья была полезна и что важно сосредоточиться на техническом содержании, а не на стиле написания.

Compiler Bug Causes Compiler Bug: How a 12-Year-Old G++ Bug Took Down Solidity (osec.io)

Краткий обзор

  • Проблема: компилятор Solidity (solc) падает на Ubuntu 22.04 при компиляции корректного кода.
  • Причина: сочетание трёх факторов
    1. 12-летний баг G++ (< 14) в разрешении перегрузок.
    2. Устаревший паттерн сравнения в Boost.
    3. Новые правила симметричных сравнений C++20.

Цепочка событий

  1. Баг G++ (2012, GCC-53499): при boost::rational<T> == 0 компилятор до 14-й версии выбирает нечлен-шаблон вместо член-шаблона.
  2. C++20 добавляет автоматическую перестановку аргументов: 0 == rational<T>rational<T> == 0.
  3. Boost 1.74 предоставляет обе версии оператора, что приводит к бесконечной рекурсии и переполнению стека.

Минимальный пример

template<typename T>
struct rational {
    template<class U>
    bool operator==(const U&) const { return true; }
};

template<class U, class T>
bool operator==(const rational<T>&, const U&) { return false; }

int main() {
    rational<int> r;
    return r == 0;   // g++11 выбирает free-функцию
}

Как починить

  • Обновить GCC ≥ 14 или Clang, или
  • Собрать Solidity без C++20 (-std=c++17), или
  • Патч Boost/использовать свежий Boost ≥ 1.82.

Итог
Ни один компонент по отдельности не «сломан», но их комбинация приводит к крашу компилятора на валидном коде.

by luu • 12 августа 2025 г. в 05:04 • 155 points

ОригиналHN

#solidity#gcc#c++#boost#c++20#compiler#bug#smart-contracts

Комментарии (74)

  • 12-летний баг разрешения перегрузок в GCC + новый оператор <=> C++20 = краш компилятора Solidity.
  • Проблема в том, что «каждый компонент по отдельности не сломан», но вместе дают сбой.
  • Участники обвиняют чрезмерную сложность C++, отсутствие тестов при обновлении стандарта и «бесконечные надстройки» вроде spaceship-оператора.
  • Кто-то предлагает «python2to3-момент» для C++, другие считают смарт-контракты плохой идеей из-за неизбежных багов.
  • Лицензия SPDX в примере вызывает вопросы, но Solidity требует её наличие, иначе ошибка компиляции.