2 puan yazan GN⁺ 2025-09-24 | 2 yorum | WhatsApp'ta paylaş
  • Go dili Valgrind desteğini resmi olarak ekledi
  • Bu değişiklikle bellek hatası tespiti ve debug yetenekleri güçlendi
  • Geliştiriciler artık bellek sızıntılarını ve erişim hatalarını daha kolay tespit edebilecek
  • Valgrind ile uyumluluğun iyileştirilmesi sayesinde portlama ve bakım çalışmaları daha verimli yürütülebilecek
  • Farklı platformlarda Go kodunun kararlılığını değerlendirmek kolaylaşacak

Go'ya Valgrind desteği eklenmesinin önemi

  • Go'ya Valgrind desteği eklenmesiyle geliştiriciler artık bellek hatası tespit araçlarını resmi olarak kullanabilecek
  • Bu değişiklik sayesinde Go kodunda use-after-free, bellek sızıntısı ve hatalı bellek erişimi gibi sorunlar incelenebilecek
  • Valgrind, farklı dillerde bellek sorunlarını tespit etmek için yaygın olarak kullanılıyor; Go topluluğu açısından bu, güvenilirlik ve dayanıklılığı artıran önemli bir değişiklik
  • Eklenen özellik, çeşitli platformlarda Go programları üzerinde debug, kalite doğrulama ve kararlılık değerlendirmesi gibi işleri kolaylaştırıyor
  • Bu güncellemenin asıl önemi, Go çalışma zamanı katmanına Valgrind için enstrümantasyon kodunun eklenmiş olması

Valgrind nedir?

  • Valgrind, bellek hataları, thread hataları ve bellek sızıntıları gibi sorunları inceleyen açık kaynaklı bir geliştirme aracı
  • C, C++ gibi sistem programlama dillerinde yaygın olarak kullanılır ve bellek yönetimi sorunlarının doğru tespitini sağlar

Bu özelliğin eklenmesine dair özet

  • Bu değişiklikle gelen kod enstrümantasyonu (instrumentation), Go çalışma zamanında dinamik olarak ayrılan bellekle ilgili olayların Valgrind tarafından doğru şekilde izlenmesini sağlar
  • Geliştiriciler Go programlarını Valgrind ile çalıştırarak potansiyel bellek sorunlarını veya hatalı pointer erişimlerini etkili biçimde teşhis edebilir
  • Sonuç olarak bu, Go tabanlı altyapı veya servislerde yüksek kaliteli kodun korunması ve sorunların önceden önlenmesi açısından avantaj sağlar

Değişikliğin beklenen etkileri

  • Go projelerinde bellek hatası tespiti ve kod kalitesini iyileştirme süreçlerinin daha hassas hale gelmesi bekleniyor
  • Farklı platformlara dağıtılan Go kodunun uyumluluğunu ve güvenilirliğini sağlamak daha kolay olabilir

2 yorum

 
taptaps 2025-09-25

Go diliyle ilgili gönderilere bakınca, yorumlarda mutlaka
'Rust'ta öyle değil', 'Rust'ta buna gerek yok' gibi şeyler oluyor sanki haha

 
GN⁺ 2025-09-24
Hacker News yorumu
  • Ben bu CL'nin yazarıyım; bu iyileştirmeyle bellek başlatma izleme özelliğini, kripto kodunun belirli bir süre içinde çalışıp çalışmadığını test etmekte (sabit zamanlılık testi) kullanmayı denemek istiyorum. Bu, yaklaşık 15 yıl önce agl'nin önerdiği ve BoringSSL'de yapılan yaklaşıma benziyor: ilgili bağlantı. Çünkü bu özelliği test etmek gerçekten çok zor. Ayrıca Go'da Valgrind kullanımını etkinleştirirken runtime'ın bellek işleme davranışını doğru biçimde izleyip izleyemeyeceğimizi araştırmak gibi başka ilginç etkiler de bekliyorum. Ancak bu desteğin hâlâ deneysel aşamada olduğunu vurgulamak isterim; tüm yapılandırmaların sorunsuz çalıştığından %100 emin değilim ve anlaşılması zor uyarılar daha fazla ortaya çıkabilir.
    • Topluluğun geliştirmeye yardımcı olabileceği alanlar var mı merak ediyorum.
    • Bence gerçekten harika bir özellik. Umarım bu sayede Go'daki başka sorunlar da bulunur. Ama karmaşık izleme yerine, şifreleme fonksiyonuna farklı girişler verip çalışma süresini doğrudan ölçerek hepsi aynıysa sabit zamanlılık sağlanıyor mu diye bakmak mümkün olmaz mı diye merak ediyorum. Örneğin Garbage Collection ya da OS gürültüsü varken bile birçok input verip süreleri ölçtükten sonra epsilon hata payı içindeyse yeterli olabilir gibi geliyor. Ayrıca bazı CPU'larda koşullu dallanma sayacı var; rr debugger bunu kullanıyor. Bu değerle şifre çözme öncesi ve sonrası branch sayısını karşılaştırmak da mümkün olabilir (agl'nin yazısındaki, dallanmalar aynı olmalı ki sabit zamanlılık sağlansın görüşüyle bağlantılı). Bir de ilk 10 şifre çözmenin maksimum süresine küçük bir pay ekleyip, sonrasında her şifre çözmede time padding uygulayarak (noop çalıştırmak gibi) süreyi zorla eşitlemek mümkün olabilir. Üst sınır aşılırsa programın assert ile çökmesi de düşünülebilir. Tabii OS tarafından zamanlamadan çıkarılma gibi durumlarda bu yöntem zorlaşır.
  • Valgrind başlıklarını ağaca ekleyip cgo ile çeşitli Valgrind istemci isteği makrolarını çağırmak yerine, tek bir assembly fonksiyonuyla gerekli komutları doğrudan göndererek istemci isteğini tetikleme yolunun seçilmesi çok iyi olmuş. Bu tür bir yaklaşım bootstrap toolchain için gerçekten arzu edilir: en küçük yapı taşlarını oluşturup geri kalan her şeyi dil düzeyinde ele almak.
    • Eğer bu yöntem seçilmeseydi ve mevcut yaklaşım ya da başka alternatiflerden kaçınılsaydı, Go'nun süreçleri basit tutup buna rağmen neredeyse eşdeğer performans sunmasını sağlamak için ne yapmak gerekirdi merak ediyorum. Bence bu, ileride de çözülmesi gerekecek bir mesele.
  • rsc'nin hâlâ aktif biçimde katkı veriyor olması güzel, özellikle de commit mesajlarına yorum eklemesi etkileyici. Yaş aldıkça commit mesajlarının önemini daha fazla hissediyorum. Sadece "valgrind eklendi" gibi bir not bırakmak, sonradan arşivleme yaparken pek yardımcı olmuyor.
    • rsc gerçekten rockstar seviyesinde bir geliştirici. Artık issue ve PR yönetiminde AI kullanmayı denemek gibi yeni şeyler de yapıyor; oldukça fazla sonuç almasını bekliyorum.
  • Bu özellik ancak tüm paketlerde testler uygulanıyorsa etkili olur; aksi hâlde alakasız uyarıların arasında kaybolur. Bu yüzden Python kodunda Valgrind kullanmak zor.
    • Eğer bu doğruysa, aynı şey C ve C++ için de geçerli olmalı. Ben Python + Boost C++ hibrit bir programda Valgrind kullandım; suppressions dosyası üzerinde bir saat uğraştıktan sonra sorunsuz kullanabildim.
    • Aşırı fazla bilgiyi düzenleyip özetlemek için yerel bir LLM faydalı olabilir. Bu yüzden Valgrind gibi pilleri içinde gelen bir toolchain'in rolü çok önemli.
    • Go ortamında "tüm paketler test ediliyor" demek tam olarak ne anlama geliyor merak ediyorum.
  • Valgrind gizli bir süper güç. Yazdığım yazılımların çoğunda testleri make check ile çalıştırıyor, ardından aynı testleri Valgrind altında bir kez daha make check-valgrind ile çalıştırıyorum. İkincisi yalnızca geliştirici PC'sinde kullanılıyor. Bu yöntemle bellek sızıntılarını ve ince hataları sık sık yakalıyorum.
    • Kısmen katılıyorum, ama iş multi-threading'e gelince (Go'nun yoğun kullandığı bir alan) Valgrind'in soyutlama katmanı pek iyi çalışmıyor. En son C++ koduyla epey derine indiğimde gördüğüm kadarıyla kendi scheduler'ını kullandığı için, gerçek dünyadaki eşzamanlılık ve race condition sorunları Valgrind altında pek görünmüyor. Bir de genel olarak performans kaybı oldukça büyük. Yine de birçok kez çok yardımcı oldu; varlığını sürdürmesine minnettarım.
  • Bu destek gerçekten çok havalı; bu sayede bazı ek hatalar ortaya çıkacak gibi görünüyor. Merak ettiğim şey neden Valgrind'in seçildiği. Bence Clang AddressSanitizer (asan) ve MemorySanitizer (msan) daha fazla hata türü buluyor (örneğin use-after-return) ve çok daha hızlı.
    • Go, clang/llvm kullanmadığı için bu araçlar uygulanamaz.
    • Go'nun zaten birkaç yıldır kendi msan/asan desteği var.
    • Valgrind çok daha hızlıdır ve çalışan programlara sonradan attach edilerek de kullanılabilir.
    • Valgrind; bellek izleme, bellek profilleme gibi çeşitli yetenekleriyle performans izleme açısından da çok güçlü.
  • Çok etkileyici. Go'daki en büyük sorunlardan biri profilleme ile sık görülen bellek sızıntısı/baskısı durumu; şu anda bunu çözmek için iyi bir alternatif araç bilmiyorum.
    • Daha fazla ayrıntı duymak isterim; tam olarak ne tür profilleme sorunları yaşıyorsunuz? Eğer inuse bellek profili bellek sızıntısını izlemek için yeterli değilse (gorefs kullanıp kullanmadığınızı merak ediyorum), ne tür bellek baskısının sorun yarattığını anlatırsanız yardımcı olur. goref deposu Bu arada Datadog'da continuous profiling üzerinde çalışıyorum ve Go runtime profiling'e düzenli katkı veriyorum.
    • Garbage collected bir dilde "kalıcı bellek sızıntısı" nasıl ortaya çıkabiliyor merak ediyorum.
    • İdeal olarak, diğer dillerde olduğu gibi neyin stack'e konacağını açıkça kontrol edebilmek gerekirdi diye düşünüyorum (yalnızca escape analysis'e güvenmek yerine). Şu anda -gcflags -m=3 seçeneği ya da VSCode Go eklentisindeki ui.codelenses, ui.diagnostic.annotations gibi ayarlarla uğraşmak gerekiyor; bu da rahatsız edici.
    • Go'da "kalıcı bellek sızıntısı/baskısı" bağlamında, bir goroutine oluşturuyorsanız onu nasıl kesin biçimde temizleyeceğinizi bilmeden oluşturmamanız gerekir.
    • pprof da aslında oldukça iyi çalışıyor; hangi ek özellikleri istediğinizi merak ediyorum.
  • Bu deneme fena görünmüyor. İstemci isteği mekanizması değişirse bir risk olabilir, ama başlıklar neredeyse hiç değişmiyor (özellikle yeni platformlar eklenirken). Go yalnızca amd64 ve arm64 ile ilgilendiği için sorun daha da az. Bu iyileştirmenin asıl faydası bellek sızıntısını önlemekten çok, başlatılmamış belleği doğru biçimde saptayabilmesi. Çünkü bellek yeniden kullanıldığında "poisoning" (bilerek kullanılamaz hâle getirme) yapılmıyorsa analiz zorlaşıyor. Bu özellik cachegrind ve callgrind dışındaki araçlar için de oldukça yararlı.
  • Bu iyileştirme bana bir kazançtan çok, Go ekosistemi açısından küçük bir başarısızlık gibi geliyor. Valgrind'i gerçekten çok seviyorum ve C geliştiricisi olduğum dönemde sık kullanırdım. Ama Go'nun özellikle Valgrind'e ihtiyaç duyması, dilde ya da ekosistemde eksik kalan şeyler olduğu hissini veriyor. Yaklaşık 6 yıldır Rust kullanıyorum ve hiç Valgrind'e ihtiyaç duymadım (ekipteki bir kişinin bir kez kullanması dışında). Bunun muhtemelen cgo yüzünden olduğunu biliyorum ama yine de biraz geriye gidiş hissi veriyor.
    • Go ile ilgili üst sıralardaki yorumlarda neden hep Rust'tan söz edilip hafif alaycı bir ton oluyor anlamak zor. Giderek savunmacı ama aynı zamanda üstünlük taslayan bir hava oluşuyor.
    • Bu özelliğin temel amacı doğru bellek izlemekten çok, sabit zamanlı kod testi gibi kullanım senaryoları. ilgili açıklama hâlâ bir miktar geçerli.
    • Rust'ta da Valgrind'i az da olsa kullandım. Çok sık gerekmedi ama gerektiği durumlar kesinlikle var. Rust çok farklı ortamlarda kullanılabilen bir dil; üst düzey fonksiyonel koddan, düşük seviyeli C benzeri mikrodenetleyici koduna kadar uzanıyor. Hiç unsafe kullanmayan yerler de var, zorunlu olduğu yerler de. Ayrıca FFI üzerinden C kullanmak da oldukça yaygın; dolayısıyla bir noktada ihtiyaç doğabiliyor. Eskiden nginx için Rust modülü geliştirirken (resmî ya da gayriresmî binding'ler yokken) sık hata yaptığım için Valgrind'in yardımı dokunmuştu.
    • Ne kadar unsafe kod yazdığınıza, ne kadar unsafe crate ya da C/C++ kütüphanesi bağladığınıza göre kullanım sıklığı değişir. Java, .NET ve Node'da da harici bağımlılıklar yüzünden ihtiyaç duyulan durumlar ortaya çıkabiliyor.