aslain.dev
0%
01 Hizmetler 02 Hakkımda 03 Projeler 04 Stack 05 Blog 06 İletişim
← Tüm makaleler Metin2

Metin2 Core Crash Çözümü: Core Dump Okuma Rehberi

Bir Metin2 sunucusu işletiyorsan, er ya da geç bir metin2 core crash ile karşılaşırsın: oyun çekirdeği (game süreci) aniden kapanır, oyuncular bağlantıyı kaybeder ve geride bir core dump dosyası kalır. Çoğu kişi bu noktada paniğe kapılıp süreci yeniden başlatır ve sorunu görmezden gelir. Oysa o core dump, çökmenin tam nedenini satır satır anlatan en değerli kaynaktır. Bu rehberde core dump'ı gdb ile nasıl okuyacağını, backtrace'i nasıl yorumlayacağını ve en sık görülen çökme nedenlerini nasıl kalıcı olarak çözeceğini adım adım göstereceğim.

Core dump nedir ve neden önemlidir?

Bir süreç ölümcül bir sinyal (genellikle SIGSEGV — geçersiz bellek erişimi) aldığında, işletim sistemi sürecin o anki bellek görüntüsünü diske yazabilir. Buna core dump denir. FreeBSD üzerinde dosya genellikle game.core, Linux'ta ise core veya core.PID adıyla, sürecin çalışma dizininde oluşur. İçinde çağrı yığını (call stack), register değerleri ve değişkenlerin son hali bulunur. Yani çökme anını dondurulmuş bir fotoğraf gibi yakalar.

Önemli bir nokta: core dump üretiminin açık olması gerekir. Aksi halde elinde analiz edecek hiçbir şey olmaz.

# Mevcut limiti gör
ulimit -c
# Sınırsız core dump'a izin ver (game'i başlatmadan önce)
ulimit -c unlimited

Linux'ta core dosyasının nereye ve hangi isimle yazılacağını core_pattern belirler. Çekirdeğin core'u başka bir yere (ör. systemd-coredump) yönlendirmediğinden emin ol:

cat /proc/sys/kernel/core_pattern
# Basit, çalışma dizinine PID'li dosya için:
echo 'core.%p' > /proc/sys/kernel/core_pattern

gdb ile core dump'ı açmak

Analizin kalbi gdb'dir. Çökme nedenini görmek için core dosyasını, onu üreten tam olarak aynı game binary'siyle birlikte açman gerekir; farklı bir derlemeyle açarsan adresler tutmaz ve backtrace anlamsız çıkar.

# FreeBSD
gdb ./game game.core
# Linux
gdb ./game core.12345

gdb açıldığında ilk komutun bt (backtrace) olmalı. Bu, çökme anındaki çağrı zincirini en içteki fonksiyondan dışarıya doğru listeler:

(gdb) bt
#0  0x081a2b3c in CHARACTER::GetLevel (this=0x0) at char.cpp:1042
#1  0x0819f0a1 in CHARACTER::ComputePoints (this=0x0) at char_battle.cpp:88
#2  ...

Yukarıdaki örnekte this=0x0 kritik ipucudur: bir null pointer üzerinde GetLevel() çağrılmış. Daha fazla bağlam için şu komutlar işini görür:

  • bt full — her stack frame'deki yerel değişkenleri de gösterir.
  • thread apply all bt — çok iş parçacıklı çökmelerde tüm thread'lerin yığınını döker.
  • frame 1 ardından print *this — belirli bir karenin değişkenlerini incelemeni sağlar.
  • info registers — register durumunu gösterir.

Debug sembolleri olmadan backtrace okunmaz

Eğer bt çıktısında fonksiyon adları yerine ?? () ve sadece adresler görüyorsan, binary'n strip edilmiş yani sembolleri atılmıştır. Bu durumda yapacak fazla bir şey yok. Çözüm, kaynağı -g bayrağıyla derlemek ve sembolleri korumaktır.

# Makefile / derleme bayraklarına ekle
CFLAGS += -g
# Sürümü dağıtmadan önce strip ETME; ayrı bir debug kopyası tut

İyi bir alışkanlık: canlıda çalışan binary'nin -g ile derlenmiş, strip edilmemiş bir kopyasını ayrı sakla. Bir core düştüğünde o kopyayla aç; canlı performans için ayrı, strip'li sürümü kullanıyorsan bile adresler aynı derleme olduğu sürece eşleşir.

Sık görülen çökme nedenleri

Yıllar içinde Metin2 kaynak kodlarında en sık karşıma çıkan metin2 core crash sebepleri şunlar:

  • Null/serbest bırakılmış CHARACTER pointer'ı: Bir oyuncu çıkış yaptıktan sonra hâlâ ona referans veren bir quest timer, parti ya da p2p mesajı varsa, geçersiz pointer üzerinden erişim çökmeye yol açar. Backtrace'te this=0x0 veya garip bir adres bunun işaretidir.
  • Bozuk proto verisi: item_proto, mob_proto ya da quest'lerde var olmayan bir vnum'a erişim. Eksik bir item/mob tanımı, dizin dışı erişimle çöker.
  • Quest hataları: Lua tarafındaki bir mantık hatası native fonksiyona geçersiz argüman yollar. syserr.txt dosyasında çökmeden hemen önceki SYSERR satırları genelde quest adını verir.
  • Paket/buffer taşması: Hatalı boyutlandırılmış bir paket yapısı (struct) ya da güvenilmeyen istemci girdisi, sınır dışı okuma/yazmaya neden olur.
  • Çift serbest bırakma (double free): Aynı nesnenin iki kez delete edilmesi; özellikle event/timer iptallerinde sık görülür.

Backtrace seni bir dosya ve satıra götürdükten sonra, o satırdaki pointer'ın geçerliliğini kontrol eden bir koruma eklemek çoğu zaman en hızlı kalıcı çözümdür:

// Önce: ch null gelirse çöker
ch->ComputePoints();

// Sonra: savunmacı kontrol
if (ch == NULL)
    return;
ch->ComputePoints();

Log'ları core ile birlikte oku

Core dump tek başına değil. game sürecinin çalışma dizinindeki syserr.txt ve syslog.txt dosyaları, çökmeden önceki son olayları zaman damgalarıyla tutar. Pratik bir yöntem: çökme anının zaman damgasını al, syserr.txt içinde o saniyeyi ara.

tail -n 100 syserr.txt
grep -n "SYSERR" syserr.txt | tail -n 20

Çoğu zaman backtrace sana "nerede" çöktüğünü, syserr.txt ise "hangi olaydan sonra" çöktüğünü söyler. İkisini birleştirince "neden" ortaya çıkar.

Çökmeyi tekrar üretmek ve doğrulamak

Bir düzeltme yaptıktan sonra mutlaka çökmeyi yeniden tetiklemeyi dene: hangi item, hangi quest, hangi NPC etkileşimi çökertiyordu? Adımları bir test sunucusunda tekrar et. Düzeltmenin işe yaradığını ancak çökme bir daha üretilemediğinde doğrulamış olursun. Aksi halde sadece semptomu bastırmış, kök nedeni gözden kaçırmış olabilirsin.

Sık Sorulan Sorular

Core dump dosyası oluşmuyor, neden?

En yaygın neden, ulimit -c değerinin 0 olmasıdır; game'i başlatan kabukta ulimit -c unlimited ayarla. Linux'ta ayrıca core_pattern'ın core'u systemd-coredump'a yönlendirmediğini ve dizinde yazma izni olduğunu kontrol et.

Backtrace'te fonksiyon adları yok, sadece adresler var. Ne yapmalıyım?

Binary'n strip edilmiş demektir. Kaynağı -g bayrağıyla yeniden derle, sembolleri koru ve core'u bu sembollü kopyayla aç. Strip edilmiş bir binary'den anlamlı bir yığın çıkaramazsın.

Çökme rastgele oluyor, sabit bir adım yok. Nasıl yakalarım?

Birden fazla core dump topla ve hepsinin backtrace'ini karşılaştır. Aynı fonksiyon veya satır tekrar ediyorsa kök neden orasıdır. Tekrar etmeyen, bellek bozulmasına işaret eden durumlarda valgrind ya da AddressSanitizer ile test derlemesi çalıştırmak ipucu verir.

Sunucun kararlı kalmıyorsa, core dump'ları analiz edip tekrar eden çökmeleri kaynak seviyesinde çözmene yardımcı olabilirim. Metin2 game core hata ayıklaması ve sunucu kararlılığı için benimle iletişime geç.

Bu kategorideki tüm yazılar →

Devamı için