Uneori un canal se oprește brusc: jucătorii sunt deconectați, iar în folderul canalului apare un fișier mare numit `game.core`. Acel fișier e ca o **fotografie a memoriei** programului în clipa în care a căzut. Cu unealta potrivită, `gdb`, poți afla din el în ce funcție și pe ce rând din cod s-a întâmplat. Nu trebuie să fii programator ca să faci primii pași. Trebuie doar să nu pierzi fotografia și să știi s-o citești.
game.core împreună cu exact binarul game care a căzut și jurnalele. Pe serverul de test rulezi gdb ./game game.core, apoi bt și bt full. Citești de sus în jos: primul rând e locul crash-ului, următoarele arată cine l-a chemat.Nivel: Avansat. Ce trebuie să știi înainte: ce e sursa, compilarea game (ca să înțelegi simbolurile de depanare) și lecția serverul nu pornește.
Cuvinte pe care le vei întâlni
| Cuvânt | Ce înseamnă |
|---|---|
| Crash | Oprirea bruscă a programului din cauza unei erori. |
Core dump (fișier .core) | Copia memoriei programului din momentul crash-ului. |
| gdb | Unealta care citește un core dump și îți arată unde s-a oprit programul. |
Backtrace (bt) | Lista funcțiilor active la crash: cine pe cine a chemat. |
| Frame | Un rând din backtrace: o funcție, cu fișierul și rândul ei. |
| Pointer invalid | O „adresă” spre ceva care nu mai există (de exemplu un jucător deja ieșit). Cauza multor crash-uri. |
Pasul 1: Nu pierde dovezile
Primul instinct e să repornești repede. Repornește, dar după ce salvezi fișierele. Atenție mai ales la scripturile de curățenie: în pachetul verificat, clear.sh din fiecare core șterge game.core și jurnalele.
Găsește fișierele .core:
find /usr/home/game -name "*.core"Pe FreeBSD, fișierul apare de obicei în folderul din care rula procesul (de exemplu channel1/game1/game.core). Apoi salvează tot într-un folder separat:
mkdir -p /usr/home/crash/2026-11-02-ch1-game1
cd /usr/home/game/channel1/game1
mv game.core /usr/home/crash/2026-11-02-ch1-game1/
cp syserr syslog /usr/home/crash/2026-11-02-ch1-game1/
cp /usr/home/game/share/bin/game /usr/home/crash/2026-11-02-ch1-game1/De ce copiezi și game? Pentru că un core se citește corect doar cu exact binarul care l-a produs. Dacă mâine pui un game nou, core-ul de azi nu se mai potrivește cu el.
Notează și ora crash-ului și ce se întâmpla în joc (un eveniment, un dungeon, un jucător anume).
Pasul 2: Verifică dacă sistemul păstrează core-urile
Dacă după un crash nu apare niciun .core, verifică:
sysctl kern.coredump kern.corefile
ulimit -c
df -h /usr/homekern.coredumptrebuie să fie1(sistemul are voie să scrie core-uri).kern.corefilearată numele fișierului; implicit e%N.core, adică numele programului plus.core.ulimit -ctrebuie să fieunlimitedsau un număr mare;0înseamnă „nu scrie core”.df -harată spațiul liber. Un core poate avea sute de MB.
Pasul 3: Instalează gdb pe serverul de test
Analiza o faci pe serverul de test, nu pe live. Copiezi acolo folderul din /usr/home/crash (cu WinSCP, în modul Binary). Apoi:
pkg install gdbPasul 4: Deschide core-ul și cere backtrace-ul
cd /usr/home/crash/2026-11-02-ch1-game1
gdb ./game game.coreÎn gdb scrii pe rând:
bt
bt full
info threads
quitbtarată lista scurtă a funcțiilor.bt fullarată aceeași listă plus valorile variabilelor din fiecare funcție.info threadsarată câte fire de execuție avea programul.quitiese.
Salvează tot ce afișează (copiezi textul din PuTTY într-un fișier) ca să-l poți compara mai târziu.
Pasul 5: Citește rezultatul
Iată un exemplu dintr-un caz real, pe alt pachet (rândurile și numerele diferă la tine):
#0 CEntity::GetDesc (this=0x3) ...
#1 CItem::UpdatePacket () at item.cpp:230
#2 CItem::SetSocket (...) at item.cpp:1329
#3 quest::item_set_socket (L=...) at questlua_item.cpp:141Citește-l de sus în jos:
| Rând | Ce spune |
|---|---|
#0 | Aici a căzut: în GetDesc, cu this=0x3. O adresă atât de mică nu e un obiect real, deci e un pointer invalid. |
#1 | Funcția a fost chemată din UpdatePacket, în item.cpp, rândul 230. |
#2 | Care a fost chemată de SetSocket. |
#3 | Care a fost chemată dintr-un quest (item_set_socket). |
Concluzia, pe românește: un quest a schimbat un item care aparținea cuiva care nu mai exista (de exemplu un jucător deconectat între timp). De aici începe căutarea: ce quest folosește funcția aceea și în ce moment.
Dacă vezi ?? în loc de nume sau mesajul no debugging symbols found, binarul nu are simboluri de depanare (a fost „strip”-uit) sau nu e același binar care a căzut. Binarele din pachetul verificat au simbolurile incluse (file arată with debug_info, not stripped).
Dacă backtrace-ul arată haotic, cu funcții fără legătură între ele, memoria fusese deja stricată înainte de crash. Locul unde a căzut nu e locul unde s-a greșit. Pentru astfel de cazuri există unelte mai avansate (de exemplu o compilare specială cu AddressSanitizer, pe serverul de test), care prind prima scriere greșită.
Pasul 6: Repară și verifică
- Reproduci scenariul pe serverul de test (același quest, aceeași acțiune).
- Aplici o singură reparație, ca în prima modificare în sursă sau în quest.
- Repeți scenariul de mai multe ori. Dacă nu mai cade, faci deploy după procedura sigură.
Atenție: core-ul conține date private
Un core e memoria serverului: poate conține parola bazei de date din CONFIG, date ale jucătorilor, mesaje. Nu-l publica pe forumuri și nu-l trimite oricui. Dacă ceri ajutor, trimite doar textul de la bt, după ce îl citești.
Greșeli des întâlnite
- Rulezi
clear.shsau repornești înainte să salvezi core-ul. Dovada dispare. - Citești core-ul cu alt binar decât cel care a căzut. Rezultatul e fără sens.
- Schimbi mai multe funcții „să vezi dacă dispare”. Nu mai știi ce a reparat și poți introduce alte buguri.
- Ignori crash-urile rare. Un crash care apare o dată pe săptămână poate fi un bug care, folosit intenționat, oprește serverul oricând.
Întrebări frecvente
A căzut db, nu game. Se face la fel?
Da. Fișierul se numește de obicei db.core, în folderul db, și îl deschizi cu gdb ./db db.core, cu binarul db care a căzut. Un db pornit înainte ca MySQL să fie gata poate cădea imediat: verifică și ordinea de pornire.
Pot folosi gdb pe serverul live?
Poți, dar nu e recomandat: ocupă procesor și memorie. Copiază dovezile pe test.
Nu înțeleg nimic din bt full. Ce fac?
Pentru început, uită-te doar la numele funcțiilor și fișierelor din primele 5 rânduri. Deja îți spun în ce zonă a jocului e problema: questuri, iteme, party, comerț.
Ce urmează
Mergi la compatibilitatea protocolului game–client. Toate lecțiile sunt în lista tutorialelor Metin2.
Server Metin2 gata de joc
Găzduire Metin2 în România, cu instalare de serverfiles, bază de date MySQL și protecție Anti-DDoS inclusă.