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. none değeri core dump’ları tamamen devre dışı bırakır, journal değ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.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir