Полный текст

Как был найден баг в компиляторе GoРасследование зашло в тупик, пока не удалось изучить дамп ядра в момент падения. И тут ждал прорыв: оказалось, что сбойная горутина была прервана (вытеснена) в самый неподходящий момент — посреди эпилога функции NetlinkSocket.Receive.Корень проблемы был в ассемблерном коде. Для функций с большим стеком компилятор Go на arm64 генерировал две отдельные ADD инструкции для коррекции указателя стека. Если вытеснение происходило ровно между ними, указатель оставался в невалидном, промежуточном состоянии.Позже сборщик мусора пытался прочитать этот повреждённый стек и падал. Это была гонка в одну инструкцию. Оставалось доказать теорию.