%100 CPU Kullanan Ama Hiçbir Şey Yapmayan Programlar: strace'in Resmen Bittiği Yer
Sunucu fanları uçak gibi ötüyor, CPU %100'e vurmuş. Ama strace çalıştırdığınızda ekran bomboş. Neden? Kernel Space ile User Space arasındaki görünmez duvarı ve 'perf' aracıyla kodun zihnine girmeyi öğreniyoruz.
Sistem yöneticisinin kabusu bazen sessizliktir, bazen de gürültüdür.
Sunucu odasına (veya laptopunuza) girdiğinizde o tanıdık sesi duyarsınız: Fanlar son devirde dönüyordur. Sanki bir uçak kalkışa hazırlanıyor gibidir. Terminale koşup top veya htop komutunu çalıştırırsınız. Ve karşınızda o suçluyu görürsünüz: En tepede, kırmızı renklerle parlayan, %100 CPU tüketen bir süreç (Process).
Refleksleriniz hemen devreye girer. Bugüne kadar öğrendiğiniz (ve önceki yazılarımızda anlattığımız) o süper kahramanı çağırırsınız: strace. “Bakalım bu haylaz arkada ne işler çeviriyor?” dersiniz. Komutu yazarsınız: strace -p <PID>
Ve… Hiçbir şey. Koca bir hiç. İmleç yanıp söner. Ekrana ne bir read, ne bir write, ne de bir futex düşer. Bazen çok nadiren, araya sıkışmış anlamsız bir gettimeofday düşer, sonra yine sessizlik.
Şimdi büyük bir paradoksla karşı karşıyasınız:
topdiyor ki: “Bu adam deliler gibi çalışıyor, ter döküyor, CPU’yu sömürüyor!”stracediyor ki: “Bu adam hiçbir şey yapmıyor, parmağını bile kıpırdatmıyor.”
Kim yalan söylüyor? Cevap: İkisi de doğru söylüyor. Sorun, sizin baktığınız yerde. Bugün, strace mikroskobunu çöpe atıp, perf (Linux Profiling Tools) cihazını elimize alacağımız gündür. Çünkü sorun artık Kernel’da (Devlet Dairesi) değil, uygulamanın kendi beyninin (User Space) içinde.
🧱 1. Duvarın Ötesi: User Space vs Kernel Space
Bu serideki ilk analojimizi hatırlayın: Program (Vatandaş) ve Kernel (Devlet Memuru/Arşivci).
strace sadece ve sadece, vatandaşın memurdan bir şey istediği anı (System Call) kaydeder.
- “Dosya ver” (
read) - “Ağa bağlan” (
connect) - “Saati söyle” (
time)
Ama eğer vatandaş, kendi evine kapanıp, perdeleri çekip, kendi kendine matematik problemi çözmeye başlarsa? Veya bir kağıdı alıp üzerine sonsuza kadar “A” harfi yazıp silerse? Memur (Kernel) bundan haberdar olabilir mi? Hayır. Memur sadece kapı çalındığında iş yapar. Vatandaş kapıyı çalmıyorsa, memur (ve dolayısıyla strace) kördür.
İşte CPU Bound (İşlemci Odaklı) işlemler tam olarak budur. Program, dış dünyadan (Disk, Ağ) hiçbir şey istemez. Sadece işlemci (ALU) üzerinde aritmetik veya mantıksal işlemler yapar.
strace bu noktada biter. Artık Profiling (Profil Çıkarma) dünyasına hoş geldiniz.
🔬 2. Yeni Silahımız: perf (Linux Profiling Tool)
Eğer strace bir güvenlik kamerasıysa (kapıdan gireni çıkanı izler), perf bir zihin okuyucudur (beynin hangi bölgesinin aktif olduğunu izler).
perf, Linux çekirdeğinin içine gömülü bir performans analiz aracıdır. Çalışma mantığı Sampling (Örnekleme) üzerinedir:
- Saniyede (örneğin) 1000 kez CPU’yu durdurur (Interrupt).
- O an CPU’nun hangi Instruction Pointer (IP) adresinde (yani kodun hangi satırında) olduğuna bakar.
- Bunu kaydeder ve CPU’yu devam ettirir.
Bu işlemi yeterince uzun süre yaparsanız, istatistiksel olarak programın vaktini en çok nerede harcadığını %99 doğrulukla bulursunuz.
Kurulum (Eğer Yoksa)
Çoğu minimal sistemde gelmez.
1
2
3
4
5
# Ubuntu/Debian
sudo apt install linux-tools-common linux-tools-generic linux-tools-$(uname -r)
# RHEL/CentOS/Fedora
sudo yum install perf
🎥 3. Canlı İzleme: perf top
Hadi şu %100 CPU yiyen hayalet süreci yakalayalım. Komutumuz tipk top gibidir, ama fonksiyonları gösterir:
1
sudo perf top -p <PID>
(Eğer PID vermezseniz tüm sistemi izler).
Karşınıza şöyle bir ekran çıkacaktır:
1
2
3
4
5
Samples: 45K of event 'cycles', Event count (approx.): 123456789
Overhead Shared Object Symbol
95.50% my_bad_program [.] heavy_calculation_function
2.10% libc-2.31.so [.] _int_malloc
0.50% [kernel] [k] do_syscall_64
Bu Tabloyu Nasıl Okuruz?
- Overhead: İşlemcinin harcadığı vaktin yüzdesi. %95.50 çok ciddi bir rakam.
- Shared Object: Bu kod nerede?
my_bad_programın kendisinde mi, yoksa çağırdığı bir kütüphanede (libc,libssl) mi? - Symbol: Fonksiyonun adı. İşte suçlu burada:
heavy_calculation_function.
Artık sorunun diskte, ağda veya kernel’da olmadığını biliyorsunuz. Sorun, yazılımcının yazdığı heavy_calculation_function isimli fonksiyonda.
🕵️♂️ 4. Vaka Analizi: “Sonsuz Döngü” (Infinite Loop)
Bir Python scripti yazdınız ama yanlışlıkla sonsuz döngüye soktunuz.
1
2
3
4
5
6
7
# bad_loop.py
def hesapla():
i = 0
while True:
i = i + 1 # Sonsuza kadar topla
hesapla()
Bunu çalıştırın. Bir çekirdeği %100 kullanacaktır. strace -p <PID> yapın. Ekran bomboş olacaktır. Çünkü i + 1 işlemi Kernel’ı ilgilendirmez. Tamamen CPU ve RAM (Register) arasında döner.
Şimdi perf top -p <PID> yapın:
1
2
3
Overhead Shared Object Symbol
40.00% python3.8 [.] _PyEval_EvalFrameDefault
20.00% python3.8 [.] PyLong_FromLong
Gördünüz mü? Python yorumlayıcısının (_PyEval_EvalFrameDefault) sürekli çalıştığını yakaladınız. Bu, kodun sürekli bir döngüde “yorumlandığını” (execute edildiğini) kanıtlar.
💡 İpucu: Derlenen dillerde (C/C++, Go, Rust) fonksiyon adını net görürsünüz. Yorumlanan dillerde (Python, Ruby, Java) ise genellikle o dilin sanal makinesinin (VM) fonksiyonlarını görürsünüz (Örn:
JVM,V8,PyEval). Daha derin analiz için o dillere özel profiler’lar (py-spy, async-profiler) gerekebilir amaperfsize “Sorun CPU Bound” teşhisini koydurur.
🧬 5. Vaka Analizi: “Deli Gibi Şifreleme” (Crypto Mining veya SSL)
Bazen sunucunuz hacklenmiştir ve bir Crypto Miner çalışıyordur. Veya uygulamanız yanlışlıkla sürekli SSL Handshake yapıyordur. perf top çıktısında şunları görürseniz tetikte olun:
1
2
3
Overhead Symbol
80.12% sha256_transform_avx2
10.05% aes_encrypt_block
sha256, md5, aes, gzip gibi kelimeler görüyorsanız, işlemci Matematiksel Hesaplama ile meşguldür.
- Bu beklenen bir şey mi? (Video işleme, sıkıştırma sunucusu?)
- Yoksa beklenmedik bir şey mi? (Hacklenme, sonsuz şifreleme döngüsü?)
strace bunu asla gösteremezdi. Çünkü şifreleme, saf matematiktir ve User Space’te yapılır.
🛠️ 6. “Symbol not found” (Hex Adresler) Sorunu
Bazen perf top çalıştırırsınız ve fonksiyon isimleri yerine sadece anlamsız Hex adresler görürsünüz:
1
2
3
Overhead Symbol
60.00% 0x0000000004f2a1
30.00% 0x0000000004f2b5
Bunun sebebi, kullandığınız programın “Stripped” (Sembollerinden arındırılmış) olmasıdır. Derlenirken debug sembolleri (isim etiketleri) silinmiştir. Production ortamlarında bu normaldir (Dosya boyutu küçülsün diye).
Çözüm: Eğer bu bir sistem paketi ise (örn: nginx, libc), o dağıtımın Debug Info paketlerini kurmanız gerekir.
- Ubuntu:
nginx-dbgsym,libc6-dbgsym - CentOS:
debuginfo-install glibc
Bu paketleri kurduğunuzda perf, o hex adreslerin hangi fonksiyona denk geldiğini haritalayabilir.
🔥 7. İleri Seviye: Flame Graphs (Alev Grafikleri)
perf top anlık izleme için harikadır ama raporlamak zordur. Patronunuza “Bak burada yüzde 90 yazıyor” demek yerine, havalı ve renkli bir grafik göstermek isterseniz dünyaca ünlü Flame Graph (Brendan Gregg) tekniğini kullanmalısınız.
Mantık basittir:
perf record: Veriyi 10-20 saniye boyunca diske kaydet.perf script: Kaydı okunabilir metne çevir.FlameGraph.pl: Metni grafiğe çevir (SVG).
Sonuçta oluşan grafik, fonksiyonların birbirini çağırma hiyerarşisini (Stack Depth) ve harcadığı zamanı (Width) gösterir. En geniş bar, en suçlu fonksiyondur.
🚦 Özet: Araç Seçim Rehberi (Cheat Sheet)
Kafalar karışmasın. Hangi durumda hangi aracı çekeceksiniz?
| Belirti (Semptom) | Olası Sorun | Doğru Araç |
|---|---|---|
| CPU %0, Program Bekliyor | Network, Disk, Kilit (Lock) | strace (Kraldır) |
| CPU %100, Fan Sesi Var | Sonsuz Döngü, Hesaplama | perf (User Space) |
| CPU %3-5 ama yavaş | Karışık (Hem I/O Hem CPU) | İkisi de (strace -c + perf) |
| Memory Şişiyor | Memory Leak | valgrind, heaptrack |
👋 Son Söz: Gözlemcinin Perspektifi
Bu blog serisinde, Linux sistem programlamanın en derinlerine indik.
open/readile dosyalara dokunduk.connect/bindile ağ kablolarına girdik.epollile zamanı yönettik.killile ölümü tanıdık.- Ve şimdi
perfile, bir programın “zihnine” (CPU Instruction’larına) girmeyi öğrendik.
strace dış dünyayla olan ilişkiyi, perf ise iç dünyadaki çalkantıyı gösterir. Usta bir sistemci, elindeki çekicin her çiviye uymayacağını bilen, alet çantasındaki her aletin sınırlarını bilen kişidir.
Gördüğünüz gibi, “Neden çalışmıyor?” sorusunun tek bir cevabı yok. Ama doğru aleti, doğru zamanda kullandığınızda, cevabı bulamamanız imkansız.
Serimiz burada (şimdilik) sona eriyor. Ama Linux devasa bir okyanus. Öğrendiğiniz bu temel prensipler (Kernel Space, User Space, Syscall, Signal, Interrupt), karşınıza çıkacak en karmaşık Kubernetes, Docker veya Cloud sorunlarında bile feneriniz olacak.
Sorunsuz kernel’lar, düşük latency’ler ve temiz loglar dileğiyle. Ve unutmayın: Her şey bir dosyadır, süreçler fanidir, ama loglar (eğer disk dolmazsa) kalıcıdır.
