Forwarded from Golang
🛠️ Cloudflare нашла редкий баг в компиляторе Go для ARM64 — ошибка повреждала стек и вызывала краши
Инженеры Cloudflare заметили странные fatal panics на ARM64-серверах, сопровождающиеся сообщениями вроде *“traceback did not unwind completely”*.
Ошибки указывали на то, что Go runtime не может корректно «размотать» стек после паники, а значит — стек повреждён.
После длительного расследования выяснилось: проблема была в самом компиляторе Go для ARM64.
Он иногда разбивал инструкцию на две отдельные операции:
Если между ними происходило асинхронное прерывание (async preemption), например, от планировщика или сборщика мусора, указатель стека (RSP) переходил в некорректное состояние.
В результате, когда Go runtime пытался «размотать» стек для трассировки ошибки, он сталкивался с повреждёнными адресами и завершался крашем.
Cloudflare смогла воспроизвести баг на минимальном примере: функция с большим стеком вызывала panic, и если прерывание происходило ровно между двумя частями инструкции, процесс завершался segmentation fault.
✅ Исправление уже включено в версии Go 1.23.12, 1.24.6 и 1.25.0.
Теперь компилятор избегает разбиения инструкции, используя промежуточный регистр — это гарантирует, что стек всегда корректен даже при прерывании выполнения.
Cloudflare подчёркивает: подобные ошибки встречаются крайне редко и проявляются только под высокой нагрузкой на ARM-серверах.
Но этот случай показывает, насколько сложно отлавливать низкоуровневые race condition-баги, которые могут оставаться незаметными годами, пока не сойдутся «идеальные» условия.
📌Подробнее: https://blog.cloudflare.com/how-we-found-a-bug-in-gos-arm64-compiler/
@Golang_google
Инженеры Cloudflare заметили странные fatal panics на ARM64-серверах, сопровождающиеся сообщениями вроде *“traceback did not unwind completely”*.
Ошибки указывали на то, что Go runtime не может корректно «размотать» стек после паники, а значит — стек повреждён.
После длительного расследования выяснилось: проблема была в самом компиляторе Go для ARM64.
Он иногда разбивал инструкцию на две отдельные операции:
ADD $framesize, RSP, RSP
Если между ними происходило асинхронное прерывание (async preemption), например, от планировщика или сборщика мусора, указатель стека (RSP) переходил в некорректное состояние.
В результате, когда Go runtime пытался «размотать» стек для трассировки ошибки, он сталкивался с повреждёнными адресами и завершался крашем.
Cloudflare смогла воспроизвести баг на минимальном примере: функция с большим стеком вызывала panic, и если прерывание происходило ровно между двумя частями инструкции, процесс завершался segmentation fault.
✅ Исправление уже включено в версии Go 1.23.12, 1.24.6 и 1.25.0.
Теперь компилятор избегает разбиения инструкции, используя промежуточный регистр — это гарантирует, что стек всегда корректен даже при прерывании выполнения.
Cloudflare подчёркивает: подобные ошибки встречаются крайне редко и проявляются только под высокой нагрузкой на ARM-серверах.
Но этот случай показывает, насколько сложно отлавливать низкоуровневые race condition-баги, которые могут оставаться незаметными годами, пока не сойдутся «идеальные» условия.
📌Подробнее: https://blog.cloudflare.com/how-we-found-a-bug-in-gos-arm64-compiler/
@Golang_google
👍17❤5🥰1
16 октября пройдёт совместный митап 2ГИС и Lamoda Tech — офлайн и онлайн. Доклады, факапы, еда, пиво и люди, которые говорят на одном языке — Go.
📍 Москва, Новоданиловская наб., 12, офис 2ГИС, 14 этаж
🕖 19:00 — 23:00
В программе:
— Дмитрий Буров, Lamoda Tech: «За кулисами асинхронности: корутины, горутины и правда между ними»
— Павел Шнель, 2ГИС: «Интеграции под нагрузкой: практики и последствия решений»
— Разгоны факапов от спикеров и участников. За лучшие факапы — фирменный мерч.
После — афтерпати и нетворкинг. Скучно не будет!
👉 Регистрация
Реклама. ООО "ДУБЛЬГИС" ИНН: 5405276278 Erid: 2RanymgKstm
📍 Москва, Новоданиловская наб., 12, офис 2ГИС, 14 этаж
🕖 19:00 — 23:00
В программе:
— Дмитрий Буров, Lamoda Tech: «За кулисами асинхронности: корутины, горутины и правда между ними»
— Павел Шнель, 2ГИС: «Интеграции под нагрузкой: практики и последствия решений»
— Разгоны факапов от спикеров и участников. За лучшие факапы — фирменный мерч.
После — афтерпати и нетворкинг. Скучно не будет!
👉 Регистрация
Реклама. ООО "ДУБЛЬГИС" ИНН: 5405276278 Erid: 2RanymgKstm
❤3
PostgreSQL – одна из самых мощных СУБД с открытым исходным кодом. Этот гайд подробно охватывает ключевые аспекты PostgreSQL: от внутренней архитектуры до приёмов оптимизации. Мы рассмотрим администрирование, производительность, расширения, инструменты, а также сравним популярные ORM для Python и Go. В конце приведён список продвинутых вопросов, часто встречающихся на собеседованиях.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🔥4❤2
Здесь на пальцах объясняют не только как писать SQL-запросы, а строить настоящие backend-сервисы с базой данных как у профи.
В этом курсе ты шаг за шагом создашь REST API на FastAPI + PostgreSQL:
от установки среды и первых таблиц - до масштабируемого приложения с безопасностью и CRUD-операциями.
🔹 На практике разберете:
• SQL-запросы, фильтры, агрегаты и подзапросы
• Связи между таблицами и нормализацию БД
• Взаимодействие Python и PostgreSQL
• Реализацию REST API и подключение базы
• Оптимизацию и разбор реальных задач с собеседований
⚡ После курса у вас будет свой работающий API-проект и реальные навыки работы с PostgreSQL в продакшене.
🎁 Сегодня –30% от цены!
🚀 Прокачаю свои знания: https://stepik.org/course/255542/
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3😁3👏2👍1🥰1
Долгое время Go-разработчики обходились без дженериков. Для универсальных алгоритмов приходилось использовать
interface{}
и приводить типы вручную, теряя типобезопасность и читаемость. С выходом дженериков Go наконец-то получил нативный способ писать универсальный, но строгий по типам код.
Дженерики позволяют описывать один алгоритм для разных типов, сохраняя преимущества статической типизации. Это делает код выразительнее, безопаснее и избавляет от дублирования.
Пример 1. Универсальное сравнение разных типов
func Compare[T ~int | ~int64 | ~float64 | ~string](a, b T) int {
if a < b {
return -1
} else if a > b {
return 1
}
return 0
}
Теперь можно сравнивать любые значения базовых типов — без кучи копий кода и без interface{}.
Пример 2. Типобезопасная коллекция Set
type Set[T comparable] map[T]struct{}
func NewSet[T comparable]() Set[T] { return make(Set[T]) }
func (s Set[T]) Add(v T) { s[v] = struct{}{} }
func (s Set[T]) Has(v T) bool { _, ok := s[v]; return ok }
func (s Set[T]) Delete(v T) { delete(s, v) }
func main() {
users := NewSet[string]()
users.Add("alice")
users.Add("bob")
nums := NewSet[int]()
nums.Add(1)
nums.Add(2)
fmt.Println(users.Has("bob")) // true
fmt.Println(nums.Has(3)) // false
}
Один тип Set теперь подходит и для string, и для int — без потери типобезопасности.
Практические советы
- Если функция используется только в одном месте, дженерик может быть избыточен.
- Дженерики - это про безопасность типов и читаемость, а не про автоматическое ускорение.
Применяйте их, когда реально хотите избавиться от дублирования и сохранить строгую типизацию.
Дженерики это не просто синтаксический сахар, а инструмент, который делает Go ближе к языкам уровня production-инженерии, где читаемость и надёжность важнее микрооптимизаций.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10❤5🔥4