TGViewer
dev notes dev notes @junsenior · 1.39K subscribers
Post #285 1.13K
Посмотрел еще один доклад, который долго лежал у меня в закладках, на этот раз про отладку параллельного кода в Go - https://www.youtube.com/watch?v=D_S9qQ7jzkQ

Я последнее время активно юзаю Obsidian для конспектирования любой полезной инфы, и доклад выше не стал исключением. Чтобы эти заметки пылились не только у меня в базе знаний, ниже - конспект интересных моментов и тезисов.

Очевидно, что отладка параллельного кода сильно сложнее, чем отладка последовательного кода, выполняющегося в одном потоке. Самая большая при такой отладке - он часто имеет не повторяющееся поведение при одинаковых входных данных и параметрах железа, где он запускается.

Пакет https://github.com/xiegeo/coloredgoroutine подсвечивает вывод каждой горутины отдельным цветом, что может быть полезно при отладке.

Использование флага GODEBUG=schedtrace позволит вывести отладочную информацию про то, как планировщик управляет горутинами:

➜ GODEBUG=schedtrace=5000 ./main
SCHED 0ms: gomaxprocs=10 idleprocs=8 threads=3 spinningthreads=1 needspinning=0 idlethreads=0 runqueue=1 [0 0 0 0 0 0 0 0 0 0]


Еще один полезный лайфхак для отладки горутин - это добавление в них меток. Например, запускаем код, где поднимаются несколько воркеров:

func main() {
go func() {
// some work...
}()

go func() {
// some work...
}()

go func() {
// some work...
}()


В любом отладчике горутина будет помечена номером, обозначающим порядковый номер, под которым эта горутина запустилась. Но чтобы понять, какой именно воркер соответствует какому именно номеру, можно добавить теги:


func main() {
go func() {
labels := pprof.Labels("fetcher", "main_goroutine")
pprof.Do(ctx, labels, func(ctx context.Context) {
// some work
})
}()

go func() {
labels := pprof.Labels("worker_1", "main_goroutine")
pprof.Do(ctx, labels, func(ctx context.Context) {
// some work
})
}()

go func() {
labels := pprof.Labels("worker_2", "main_goroutine")
pprof.Do(ctx, labels, func(ctx context.Context) {
// some work
})
}()

// ...
}


И затем, в отладчике можно вывести горутину по конкретному тегу:

(dlv) goroutines -l -with label fetcher
Goroutine 21 - User: ./main.go:20 main.main.func1.1 (0x1003befcc) [chan send]
Labels: "fetcher":"main_goroutine"
[1 goroutines]


Хорошая статья, где описывается как это сделать более подробно и где автор показывает ряд других решений для добавления меток в горутины: https://blog.jetbrains.com/go/2020/03/03/how-to-find-goroutines-during-debugging/#using-a-custom-library-to-enable-debugging-labeling

Вторая часть доклада - про deadlock'и и про то, как с ними бороться.
Из полезного, либа, которая помогает найти дедлоки - https://github.com/sasha-s/go-deadlock
К примеру, автор этой библиотеки с помощью нее же нашел потенциальные дедлоки в коде cockroach db: https://github.com/cockroachdb/cockroach/issues/7972
YouTube Debugging concurrency programs in Go Recently the interest in concurrent programming has grown dramatically. Unfortunately, parallel programs do not always have reproducible behavior. Even when they are run with the same inputs, their results can be radically different. In this talk, I’ll show…
  • 🔥 5
  • ❤ 3
  • 👍 3
More from @junsenior
  1. Sep 28, 2026Сошлись две вещи. Первая - мой проект safemap.ai, про который я уже писал выше - интеракти…
  2. Sep 17, 2026Post #356
  3. Sep 15, 2026Увидел тут в x.com статистику вакансий по PHP и статистику вакансий по hh.ru в целом. Я на…
  4. Sep 12, 2026Вдохновившись проектом, где делали интерактивную карту с тем, как работает Postgres (писал…
  5. Sep 8, 2026OpenAI выложили блогпост https://openai.com/index/navier-stokes-solution/ Мы публикуем реш…
  6. Sep 8, 2026Если кто не знал, вокруг этого сейчас разгорается очень большой скандал с OpenAI. Кратко,…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →