coredumpctl Komutu ile Linux’ta Çekirdek Döküm Dosyalarını Analiz Etme ve Sorun Giderme
Bir uygulama aniden çöktüğünde ve ekranda sadece “Segmentation fault (core dumped)” yazısını gördüğünde ne yapacağını bilmek, her sysadmin için kritik bir beceridir. Eskiden bu core dump dosyalarını analiz etmek için önce dosyayı bulmak, sonra doğru binary ile eşleştirmek, ardından GDB açmak gibi birden fazla adımdan geçmek gerekiyordu. Systemd ekosisteminin getirdiği coredumpctl komutu bu süreci ciddi ölçüde basitleştirdi. Artık tüm çökme kayıtları merkezi olarak systemd-coredump servisi tarafından toplanıyor ve coredumpctl aracılığıyla sorgulanabiliyor.
coredumpctl Nedir ve Nasıl Çalışır?
coredumpctl, systemd’nin core dump yönetim altyapısının kullanıcıya açılan arayüzüdür. Bir süreç çöktüğünde, Linux çekirdeği bu çöküşü systemd-coredump servisine iletir. Servis, çökmenin meta verilerini (hangi binary, hangi PID, hangi kullanıcı, ne zaman) journal’a kaydeder ve dump dosyasının kendisini yapılandırmaya göre ya sıkıştırılmış olarak /var/lib/systemd/coredump/ dizinine yazar ya da journal içinde saklar.
Bu merkezi yaklaşımın büyük avantajı şudur: Artık ulimit -c ayarlarını karıştırmak, core_pattern kernel parametresini elle düzenlemek veya çöken uygulamanın nerede bir dosya bıraktığını tahmin etmeye çalışmak zorunda değilsin.
Sistemde coredumpctl‘ın aktif olup olmadığını kontrol etmek için:
systemctl status systemd-coredump.socket
Eğer servis çalışmıyorsa ya da sistemin bazı kısıtlamaları varsa şu komutla kontrol edebilirsin:
cat /proc/sys/kernel/core_pattern
Çıktıda |/usr/lib/systemd/systemd-coredump gibi bir şey görüyorsan, tüm çökmeler otomatik olarak systemd tarafından yakalanıyor demektir.
Temel Kullanım ve Listeleme
Sistemdeki tüm kayıtlı core dump’ları listelemek için en basit komut şudur:
coredumpctl list
Bu komutun çıktısında şu bilgileri görürsün: zaman damgası, PID, UID, GID, sinyal numarası (örneğin SIGSEGV, SIGABRT), işlemin durumu ve çalıştırılabilir dosyanın yolu. Durumu “present” olan kayıtlarda gerçek dump dosyası mevcuttur, “missing” olanlar ise yalnızca journal kaydından ibarettir.
Belirli bir uygulamaya ait çökmeleri filtrelemek için binary adını parametre olarak geçebilirsin:
coredumpctl list nginx
Ya da belirli bir PID’e ait kaydı aramak için:
coredumpctl list --pid=12453
Zaman aralığına göre filtrelemek de mümkün. Örneğin sadece son 24 saatteki çökmeleri görmek istiyorsan:
coredumpctl list --since="24 hours ago"
Ya da belirli bir tarih aralığı vermek için:
coredumpctl list --since="2024-01-15 08:00" --until="2024-01-15 18:00"
Çökme Detaylarını İncelemek
Bir çökmenin ayrıntılarını görmek için info alt komutunu kullanırsın. En son yaşanan çöküşün bilgisine ulaşmak için:
coredumpctl info
Belirli bir PID için:
coredumpctl info 12453
info çıktısı oldukça zengindir. Çalıştırılabilir dosyanın tam yolu, komut satırı argümanları, çalışma dizini, çöküşü tetikleyen sinyal, çöküş anındaki ortam değişkenleri ve eğer mevcutsa stack trace özeti bu çıktıda yer alır. Stack trace kısmı tek başına bile pek çok durumda sorunun kaynağını işaret edebilir.
Örnek bir info çıktısında şunları görebilirsin:
PID: 12453 (myapp)
UID: 1000 (deploy)
GID: 1000 (deploy)
Signal: 11 (SEGV)
Timestamp: Mon 2024-01-15 14:23:11 TRT
Command Line: /opt/myapp/bin/myapp --config /etc/myapp/config.yml
Executable: /opt/myapp/bin/myapp
Control Group: /system.slice/myapp.service
Unit: myapp.service
Boot ID: abc123...
Machine ID: def456...
Hostname: prod-server-01
GDB ile Derinlemesine Analiz
coredumpctl‘ın en güçlü özelliklerinden biri, doğrudan GDB oturumu açabilmesidir. Hangi core dosyasını hangi binary ile eşleştireceğini düşünmene gerek kalmadan tek komutla debugger başlatabilirsin:
coredumpctl debug
Bu komut, en son kaydedilmiş çöküş için otomatik olarak doğru binary’i bulur ve GDB’yi açar. Belirli bir PID için:
coredumpctl debug 12453
GDB açıldıktan sonra kullanabileceğin temel komutlar:
# Stack trace görmek için
(gdb) bt
# Tüm thread'lerin stack trace'ini görmek için
(gdb) thread apply all bt
# Belirli bir frame'e geçmek için
(gdb) frame 3
# O frame'deki yerel değişkenleri görmek için
(gdb) info locals
# Belirli bir değişkenin değerini görmek için
(gdb) print variable_name
Debug sembollerinin olmadığı production ortamlarında bile bt komutu çoğu zaman işe yarar ve sorunun hangi kütüphaneden veya fonksiyondan kaynaklandığını gösterir.
Eğer uygulamanın debug sembol paketi mevcutsa önce onu kurman gerekir. Debian/Ubuntu tabanlı sistemlerde:
apt-get install myapp-dbgsym
# veya
apt-get install myapp-dbg
RHEL/CentOS tabanlı sistemlerde:
dnf debuginfo-install myapp
Core Dump Dosyasını Dışa Aktarmak
Bazen core dump dosyasını başka bir ortamda analiz etmen gerekebilir. Örneğin production sunucusundaki bir çöküşü kendi geliştirme makinesinde incelemek istiyorsun. coredumpctl dump komutu core dosyasını stdout’a ya da belirttiğin bir dosyaya yazar:
coredumpctl dump --output=/tmp/myapp.core 12453
Bu dosyayı ardından başka bir makineye kopyalayıp manuel olarak GDB ile açabilirsin:
gdb /opt/myapp/bin/myapp /tmp/myapp.core
Ya da sadece stack trace’i bir dosyaya kaydetmek istiyorsan:
coredumpctl info 12453 > /var/log/crash-reports/myapp-crash-20240115.txt
Bu yaklaşım özellikle çökmeleri takip sisteminize (Jira, GitLab Issues vb.) kaydetmek için kullanışlıdır.
Gerçek Dünya Senaryosu: Nginx Worker Çökmesi
Diyelim ki gece yarısı alarm geldi. Nginx belirli aralıklarla worker process’lerini kaybediyor. Sunucuya bağlanıp ilk olarak şunu çalıştırıyorsun:
coredumpctl list nginx
Çıktıda son 3 gün içinde 7 nginx çöküşü görüyorsun. En son ikisini incelemeye başlıyorsun:
coredumpctl info nginx
info çıktısında “Signal: 6 (ABRT)” görüyorsun. SIGSEGV değil SIGABRT. Bu genellikle uygulamanın kendisinin abort() çağırdığı anlamına gelir; heap corruption veya assert hatası olabilir.
Stack trace özeti şunu gösteriyor:
Stack trace of thread 1:
#0 0x00007f... in raise () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x00007f... in abort () from /lib/x86_64-linux-gnu/libc.so.6
#2 0x00007f... in __libc_message () from /lib/x86_64-linux-gnu/libc.so.6
#3 0x00007f... in malloc_printerr () from /lib/x86_64-linux-gnu/libc.so.6
#4 0x00007f... in _int_free () from /lib/x86_64-linux-gnu/libc.so.6
malloc_printerr ve _int_free görünce heap corruption ihtimali çok güçlü. Daha sonra GDB ile derinleşiyorsun:
coredumpctl debug nginx
(gdb) bt full
(gdb) thread apply all bt
Thread analizi sonucunda belirli bir modülün, özellikle de yakın zamanda güncellenen bir üçüncü taraf Nginx modülünün, memory yönetiminde sorun yarattığını tespit ediyorsun. Modülü devre dışı bırakıp sorunu çözüyorsun.
Gerçek Dünya Senaryosu: Python Uygulaması ve Segfault
Python uygulamaları normalde segfault vermez ama bir C extension kullandıklarında bu durum değişebilir. Diyelim ki bir ML servisi arada sırada çöküyor:
coredumpctl list python3
info çıktısında numpy veya tensorflow gibi bir kütüphanenin içinde çöktüğünü görüyorsun. Bu durumda Python’ın kendi debug build’ini veya ilgili kütüphanenin debug sürümünü kurmak gerekebilir. Ama önce şunu dene:
coredumpctl debug python3
(gdb) py-bt
py-bt komutu, GDB’nin Python extension’ı yüklendiğinde Python düzeyindeki stack trace’i gösterir. Hangi Python satırında, hangi fonksiyonda crash olduğunu net biçimde ortaya koyar. Bu bilgi çoğu zaman problemi belirlemek için yeterlidir.
Sistem Genelinde Core Dump Yönetimi
Depolama Ayarları
Core dump dosyaları büyük olabilir. /etc/systemd/coredump.conf dosyasıyla depolama politikasını yönetebilirsin:
cat /etc/systemd/coredump.conf
[Coredump]
Storage=external
Compress=yes
ProcessSizeMax=2G
ExternalSizeMax=2G
JournalSizeMax=767M
MaxUse=
KeepFree=
Bu parametrelerin anlamları:
- Storage=external: Core dosyaları
/var/lib/systemd/coredump/dizinine yazar.nonedeğeri core dump’ları tamamen devre dışı bırakır,journaldeğeri ise journal içine gömer. - Compress=yes: Dosyaları sıkıştırarak saklar, disk kullanımını önemli ölçüde azaltır.
- ProcessSizeMax: İşlenecek maksimum core dump boyutu. Bu boyutu aşan dump’lar atılır.
- ExternalSizeMax: Diske yazılacak maksimum boyut.
- MaxUse: Core dump dizininin kullanabileceği maksimum disk alanı.
- KeepFree: Diskte her zaman boş bırakılacak minimum alan.
Yapılandırmayı değiştirdikten sonra servisi yeniden başlatman gerekir:
systemctl daemon-reload
systemctl restart systemd-coredump
Eski Dump’ları Temizlemek
Disk doluysa eski core dump dosyalarını elle silebilirsin:
ls -lh /var/lib/systemd/coredump/
Tüm core dump dosyalarını temizlemek için:
coredumpctl clean
Ya da belirli bir süre önceki dump’ları temizlemek için systemd-tmpfiles kullanabilirsin. /etc/tmpfiles.d/coredump.conf dosyası genellikle bu dizin için otomatik temizleme kuralları içerir.
Filtreleme ve Otomasyon
Günlük kontroller veya monitoring scriptleri için coredumpctl çıktısını çeşitli şekillerde işleyebilirsin.
Son 1 saatte çökme olup olmadığını kontrol eden basit bir script:
#!/bin/bash
CRASHES=$(coredumpctl list --since="1 hour ago" --no-legend 2>/dev/null | wc -l)
if [ "$CRASHES" -gt "0" ]; then
echo "UYARI: Son 1 saatte $CRASHES çökme tespit edildi!"
coredumpctl list --since="1 hour ago"
# Slack veya mail notification buraya eklenebilir
exit 1
fi
echo "Son 1 saatte çökme yok."
exit 0
Belirli bir servis için çökme raporu üreten script:
#!/bin/bash
SERVICE=$1
OUTPUT_DIR="/var/log/crash-reports"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
mkdir -p "$OUTPUT_DIR"
if coredumpctl list "$SERVICE" --since="24 hours ago" --no-legend | grep -q .; then
REPORT_FILE="$OUTPUT_DIR/${SERVICE}_crash_${TIMESTAMP}.txt"
echo "=== Çökme Raporu: $SERVICE ===" > "$REPORT_FILE"
echo "Tarih: $(date)" >> "$REPORT_FILE"
echo "" >> "$REPORT_FILE"
coredumpctl list "$SERVICE" --since="24 hours ago" >> "$REPORT_FILE"
echo "" >> "$REPORT_FILE"
echo "=== Son Çökme Detayları ===" >> "$REPORT_FILE"
coredumpctl info "$SERVICE" >> "$REPORT_FILE"
echo "Rapor oluşturuldu: $REPORT_FILE"
fi
Prometheus ile Entegrasyon
Monitoring altyapınız Prometheus kullanıyorsa, çökme sayısını bir metric olarak dışa aktarabilirsin. Basit bir node exporter text collector yaklaşımı:
#!/bin/bash
# /etc/cron.d/coredump-metrics tarafından çalıştırılır
METRIC_FILE="/var/lib/node_exporter/textfile_collector/coredumps.prom"
TOTAL=$(coredumpctl list --no-legend 2>/dev/null | wc -l)
LAST_HOUR=$(coredumpctl list --since="1 hour ago" --no-legend 2>/dev/null | wc -l)
LAST_DAY=$(coredumpctl list --since="24 hours ago" --no-legend 2>/dev/null | wc -l)
cat > "$METRIC_FILE" << EOF
# HELP coredumps_total Sistemde kayıtlı toplam core dump sayısı
# TYPE coredumps_total gauge
coredumps_total $TOTAL
# HELP coredumps_last_hour Son 1 saatteki core dump sayısı
# TYPE coredumps_last_hour gauge
coredumps_last_hour $LAST_HOUR
# HELP coredumps_last_day Son 24 saatteki core dump sayısı
# TYPE coredumps_last_day gauge
coredumps_last_day $LAST_HOUR
EOF
Yaygın Sorunlar ve Çözümleri
Core dump dosyası “missing” görünüyor: Bu genellikle Storage=none ayarından ya da disk alanı yetersizliğinden kaynaklanır. Journal kaydı var ama dosya yazılamamış demektir. ProcessSizeMax değerini de kontrol et; uygulama bu sınırı aşıyorsa dump alınmaz.
GDB “no debugging symbols found” uyarısı veriyor: Debug paketini kur ya da uygulamayı -g flag’iyle derle. Symbols olmasa bile bt genellikle kütüphane isimlerini ve yaklaşık konumları gösterir; bu da çoğu durumda yeterlidir.
Belirli bir kullanıcının dump’larını göremiyorum: coredumpctl varsayılan olarak kendi UID’ine ait olmayan dump’ları göstermez. Root ile çalışman ya da CAP_DAC_READ_SEARCH capability’sine sahip olman gerekir.
Containerized uygulamaların dump’ları görünmüyor: Docker veya Kubernetes içindeki süreçler host’un core_pattern ayarını kullanır. Container’ın yeterli ulimit değerlerine sahip olduğunu ve --ulimit core=-1 parametresiyle başlatıldığını kontrol et.
Sonuç
coredumpctl, Linux sistem yöneticilerinin envanterinde olması gereken güçlü bir araçtır. Eskiden zahmetli olan core dump analizi artık birkaç komuta indirgenmiştir. Merkezi depolama sayesinde hangi uygulamanın ne zaman çöktüğünü kaçırmak neredeyse imkansız hale gelir; üstelik bu bilgiler sistem yeniden başlatılsa bile journal’da korunur.
Günlük kullanımda en çok işe yarayan iş akışı şudur: Önce coredumpctl list ile genel tabloyu gör, coredumpctl info ile ilgili çökmenin detaylarına bak, ardından coredumpctl debug ile GDB’ye dal. Çoğu sorun bu üç adımda çözüme kavuşur. Production ortamında debug sembollerini ayrı paketler halinde kurmak ve coredumpctl çıktısını monitoring sisteminizle entegre etmek ise uzun vadeli operasyonel olgunluk açısından büyük fark yaratır.
Bir sonraki segfault alarmında paniğe kapılmak yerine rahatça coredumpctl list yazıp ne olduğunu görebilmek, sysadmin hayatının küçük ama değerli tatminlerinden biridir.
