GameServer çökme (crash) hatalarını kaynağından yakalamanın en etkili yolu!

GameServer çökme (crash) hatalarını kaynağından yakalamanın en etkili yolu!
  • Konuyu Başlatan Konuyu Başlatan DeltaSoft
  • Başlangıç tarihi Başlangıç tarihi

Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!

DeltaSoft

Yönetici
MAREŞAL
Katılım
12 May 2026
Mesajlar
87
Tepkime puanı
130
🔍 Use-After-Free Avı: Application Verifier + PageHeap
GameServer çökme (crash) hatalarını kaynağından yakalamanın en etkili yolu
1783075721139.webp



❓ Sorun Nedir?

Sunucu bazen kendiliğinden çöküyor ve debugger seni STL'nin (mutex, vector, map) iç kodlarına atıyor. Örneğin:

Kod:
pMap  = 0xdddddddddddddddd   // silinmiş (freed) bellek
pMap  = 0xffffffffffffff03   // çöp (garbage) değer

Bu değerler nullptr değildir, bu yüzden klasik kontrolün işe yaramaz:

Kod:
if (pMap == nullptr)   // 0xdddddddd bunu GEÇER, sonra deref'te çöker!

Bu tam olarak bir "use-after-free" hatasıdır: bir nesne delete edilmiş ama pointer'ı hâlâ başka bir yerde kullanılıyor.



⚡ Neden Normalde Fark Edilmez?

  • PageHeap KAPALI: Bellek silinse bile hâlâ haritalı (mapped) kalır. Eski değeri okur, sessizce çalışır gibi görünür. Hata gizli kalır, saatler/günler sonra rastgele çöker.
  • PageHeap AÇIK: Silinen blok anında "koruma sayfası"na (guard page) düşürülür. O belleğe ilk erişimde program hemen ve tam suç mahallinde çöker.

Kısaca: PageHeap sunucuyu "daha bozuk" yapmaz — hatayı geç değil, tam oluştuğu anda gösterir. Böylece gerçek suçluyu Call Stack'te net görürsün.



🛠️ Kurulum (Adım Adım)

1. Application Verifier'ı Aç
  1. Başlat menüsünde "Application Verifier" ara ve yönetici olarak çalıştır. (Windows SDK ile gelir.)
  2. Sol üstte File → Add ApplicationGameServer.exe seç.
  3. Sağ panelde sadece Basics → Heaps işaretli kalsın (varsayılan yeterli).
  4. Save de ve kapat.

2. Debugger Altında Çalıştır
  • Visual Studio'da projeyi Debug modda aç.
  • F5 ile başlat. Hata oluştuğunda VS otomatik durur.

💡 Alternatif (komut satırı):
Kod:
gflags /p /enable GameServer.exe /full
Kapatmak için:
Kod:
gflags /p /disable GameServer.exe



🎯 Çöktüğünde Ne Yapmalı?

Program durunca Call Stack (Çağrı Yığını) penceresini aç. STL/mutex iç fonksiyonlarını atla, ilk kendi kodun (GameServer) hangisiyse — gerçek suçlu odur.



📌 Gerçek Örnek: DB Yükleme Sırasında Crash

PageHeap açıkken sunucu başlangıçta bir tablo yüklerken çöktü. Suç mahalli:

C++:
if (!m_pMap->PutData(pData->nBaseItemID, pData))
    delete pData;                                          // pData silindi

g_pMain->RightClickExchangeItemList.push_back(pData->nBaseItemID);  // <-- SILINEN belleği okudu!

Tabloda aynı ID iki kez varsa PutData false döner → delete pData çalışır → alt satır silinmiş belleği okur ve çöker.

✅ Çözüm — değeri silmeden ÖNCE sakla:

C++:
uint32 nBaseItemID = pData->nBaseItemID;   // önce kopyala

if (!m_pMap->PutData(nBaseItemID, pData))
{
    delete pData;      // duplicate: kaydı at
    return true;
}

g_pMain->RightClickExchangeItemList.push_back(nBaseItemID);  // güvenli
return true;



🧠 Özet

  • nullptr kontrolü yetmez — freed/garbage değerler kontrolü geçer.
  • PageHeap hatayı gizlenmeden, tam oluştuğu anda gösterir.
  • Call Stack'te ilk kendi fonksiyonun = gerçek suçlu.
  • "delete → sonra kullan" kalıbından kaçın; değeri önce kopyala.

Faydalı olması dileğiyle. Sorularınız için yorum bırakabilirsiniz.
 
Son düzenleme:

Konuyu Görüntüleyen Kullanıcılar (Toplam:1)

Geri
Üst
×