Depanarea plugin-urilor amx mod x - Comunitatea rusă pentru scripting amxx

Debugging - stadiul de dezvoltare a plug-in-ului, pe care îl detectează, localizează și elimină erorile. Pentru a înțelege unde a apărut eroarea, trebuie să:
  • Recunoașteți valorile curente ale variabilelor;
  • și aflați în ce mod se desfășura programul.







AMX Mod X are deja un built-in debugger, care este suficient pentru a ne rezolva problemele. Valoarea amx_debug ar trebui să fie 1. Modul de depanare pentru un anumit plug-in este inclus în modul următor: în fișier. /addons/amxmodx/configs/plugins.ini în fața pluginului necesar, scrieți cuvântul de depanare. de exemplu:


După aceasta, modificați harta pe server sau reporniți serverul (comanda de repornire). Acum, jurnalele AMXX (. / Addons / amxmodx / bușteni) vom fi capabili să învețe în detaliu în ce stadiu există un bug în plugin. Jurnalurile cu erori în directorul de jurnale se numesc error_X.txt. unde X este data la care a fost creat acest fisier.
Să presupunem că avem un plugin cu următorul conținut, care, atunci când playerul intră pe server, scrie numele său la variabila globală g_Name. De asemenea, am înregistrat comanda consola amx_names_reset la zero această variabilă printr-o buclă cu un număr fix de pași. Acest cod a fost compilat fără erori, dar acest lucru nu înseamnă că va funcționa așa cum ar trebui. După rularea acestui plugin, precum și prin utilizarea comenzii amx_names_reset din consola din directorul de jurnale, am găsit un jurnal cu erori.

debug.sma:
Cod: Selectați toate #include

#define PLUGIN "Exemplu Debug Plugin"
#define VERSION "1.0"
#define AUTOR "DJ_WEST"

noul g_Name # 91; 33 # 93; # 91; 32 # 93;

public plugin_init ()
register_plugin (PLUGIN.VERSION.AUTHOR)
register_concmd ("amx_names_reset". "Names_Reset")
>

public client_putinserver (id)
nou s_Name # 91; 32 # 93;

get_user_name (id.s_Name.charsmax (s_Name))

g_Names # 91; id # 93; = s_Name

server_print ("% s a intrat în joc". s_Name)
>

public Nume_Reset (id)
pentru (nou i = 1; i <= 33 ; i ++)
g_Names # 91; eu # 93; = ""

server_print ("Resetarea numelor")
>

Acum ne uităm la ciclul nostru:
Cod: Selectați toate
pentru (nou i = 1; i <= 33 ; i ++)
g_Names # 91; eu # 93; = ""

Vedem că ciclul este efectuat de la i = 1 la i <= 33 при этом i используется в g_Names. Но если вспомнить размерность массива g_Names, то понимаем, что когда i дойдет до 33, то это будет за пределами g_Names, следовательно нам нужно исправить код на:
Cod: Selectați toate
pentru (nou i = 1; i <= 32 ; i ++)
g_Names # 91; eu # 93; = ""

Compilați pluginul din nou, verificați din nou și vedeți că totul funcționează bine. Amintiți-vă că acesta este doar un exemplu de depanare. De fapt, erorile pot fi diferite, iar dacă plugin-ul este mare, căutarea erorii poate dura mult mai mult.

Nu-mi scrie în droguri. dacă aveți nevoie de ajutor în mod gratuit. Orice întrebări pe forum.

Opțiuni:
-A alinierea în octeți a segmentului de date și a stiva
-un cod de asamblare de ieșire
-C # 91; + / - # 93; codificare compactă pentru fișierul de ieșire (implicit = -)
-c codul sau numele paginii; ex 1252 pentru Windows Latin-1
-Calea directorului activ Dpath
-d0 nu există informații simbolice, nu există verificări în timp de execuție
-d1 # 91; implicit # 93; run-time verificări, fără informații simbolice
-d2 informații complete de depanare și verificare dinamică
-d3 informații complete de depanare, verificări dinamice, fără optimizare
-e setați numele fișierului de eroare (compilație silențioasă)
-H pentru a trimite un mesaj de notificare
-eu calea pentru includerea fișierelor
-l creez fișier lista (numai preproces)
-o setați numele de bază al fișierului de ieșire
-p setați numele fișierului "prefix"
-r # 91; numele # 93; scrieți un raport de referință încrucișat la consolă sau la un fișier specificat

După cum puteți vedea, implicit este -d1. Prin urmare, ca în compilație, nu există chei care definesc depanarea Vechi. Dacă scrieți -d3. informațiile din depanare pot obține ceva mai mult.

Dacă specificați -d0. atunci nu vor exista informații de depanare. Acest lucru va complica dezasamblarea și va face imposibilă depanarea. Dacă dacă îl activați în setări sau adăugați depanare la pornire, atunci plugin-ul nu va porni deloc în modul de depanare.

În consecință, dimensiunile plug-in-urilor diferă cu aceste opțiuni. Cele mai multe informații de depanare, pluginul "mai greu".

Pentru a pune corect o întrebare, trebuie să știți mai mult de jumătate din răspuns.
Cerberus - înlocuirea amxbanilor și mult mai mult

Încredere, dar verificați
Așa cum este scris aici, cheia standard este d1, dar din anumite motive dezasamblatorii pot vizualiza informații simbolice. Să facem un mic experiment - să compilați plugin-ul cu standardul "compile.exe" și să îl dețineți cu chei diferite, apoi să despachetați din fișierele amxx 32 bit (64 poate fi, dar nu are sens).







Fișierele din atașament privesc prin HexEditor - care dorește să vadă cum arată de fapt toate elementele

Se poate observa că „kz_scout2 Compiler.amx“ și „kz_scout2 D2.amx“, la fel ca și „compile.exe“ folosește doar deducem că de fapt opțiunea o- în incapacitate de plată -D2 cheie este, mai degrabă decât cum să scrie -d1

Deși este posibil să se facă un criteriu suplimentar: d2 adaugă informații simbolice - care include o listă a fișierelor utilizate în compilarea (în „kz_scout2 Compiler.amx“ văzut calea completă la codul sursă la momentul compilarii: D) „șirul“ cu pozițiile lor, „A“ - numele funcțiilor , variabile și domeniul de aplicare a acestora de DPI, tag-uri, și nu destul de clar pentru mine până la câmpuri de tip gunoi „Automat“ și „stat“. Toate acestea sunt înregistrate în sfârșitul fișierului, deci este destul de vizibile atunci când se compară fișiere
În conformitate cu aceste informații a fost compilat:
1 fișier, 8 linii, 4 variabile (MYSTATIC, id, givescout, plugin_init), 15 etichete (Float, bool, orice), 1 "Automat", 0 "Stat".

Vedeți cineva editat compilatorul și lazhanulsya (Puteți chiar să vă dezabonați pentru acest "bug")

Shl de modul în care descrierea opțiunilor compilatorului este în Trebuie să vă înregistrați pentru a vedea link-urile. și acolo puteți de asemenea să rețineți că cheia implicită este de fapt diferită.

#include
#include

/ ** săriți autoloading deoarece este opțional * /
#define AMXMODX_NOAUTOLOAD
#include

noua g_menuPoziția # 91; 33 # 93;
noul g_menuPlayers # 91; 33 # 93; # 91; 32 # 93;
noul g_menuPlayersNum # 91; 33 # 93;
g_menu nou # 91; 33 # 93;

noul g_menuSelect # 91; 33 # 93; # 91; 254 # 93;
noul nume g_menuSelectNum # 91; 33 # 93;

#define MAX_CLCMDS 24

nou g_clcmdName # 91; MAX_CLCMDS # 93; # 91; 32 # 93;
nou g_clcmdCmd # 91; MAX_CLCMDS # 93; # 91; 254 # 93;
nou g_clcmdMisc # 91; MAX_CLCMDS # 93; # 91; 2 # 93;
noul g_clcmdNum

public plugin_natives ()
set_module_filter ("module_filter")
set_native_filter ("native_filter")
>

public plugin_init ()
register_plugin ("Meniu de jucători", AMXX_VERSION_STR, "Echipa AMXX Dev")
register_dictionary ("common.txt")
register_dictionary ("admincmd.txt")
register_dictionary ("plmenu.txt")


register_clcmd ("amx_laccmdmenu", "cmdlaccmdmenu", ADMIN_KICK, "- afișează meniul clientului")


register_menucmd (meniul de registru ("Meniu Cmds Client"), 1023, "actionlaccmdmenu")

noi clcmds_ini_file # 91; 254 # 93;
get_configsdir (clcmds_ini_file, 253)
format (clcmds_ini_file, 253, "% s / clcmdslac.ini", clcmds_ini_file)
load_settings (clcmds_ini_file)

/ * Meniu cmds client * /

public actionlaccmdmenu (id, cheie)
comutator (cheie)
cazul 7:
++g_menuOption # 91; id # 93;
g_menuOption # 91; id # 93; % = g_menuSelectNum # 91; id # 93;
displaylaccmdmenu (id, g_menuPoziția # 91; id # 93;)
>
cazul 8: displaylaccmdmenu (id, ++ g_menuPosition # 91; id # 93;)
cazul 9: displaylaccmdmenu (id, --g_menuPoziția # 91; id # 93;)
default:
noul jucător = g_menuPlayers # 91; id # 93; # 91; g_menuPosition # 91; id # 93; * 7 + cheie # 93;
noi pavilioane = g_clcmdMisc # 91; g_menuSelect # 91; id # 93; # 91; g_menuOption # 91; id # 93; # 93; # 93; # 91; 1 # 93;

dacă (is_user_connected (player))
noua comandă # 91; 512 # 93; authid # 91; 32 # 93; nume # 91; 32 # 93; userid # 91; 32 # 93;

înlocui (comanda, charsmax (comanda), "% userid%", userid)
înlocui (comanda, charsmax (comanda), "% authid%", authid)
înlocuiți (comanda, charsmax (comandă), "% name%", nume)

dacă (steaguri 1)
server_cmd ("% s", comanda)
server_exec ()
> altfel dacă (steaguri 2)
client_cmd (id, "% s", comanda)
altfel dacă (steaguri 4)
client_cmd (player, "% s", comanda)
>

dacă (steaguri 8)
displaylaccmdmenu (id, g_menuPoziția # 91; id # 93;)
>
>

displaylaccmdmenu (id, pos)
dacă (poz <0)
întoarcere

noul meniuBloc # 91; 512 # 93;
nou b = 0
nou i
nume nou # 91; 32 # 93;
nou start = pos * 7

dacă (start> = g_menuPlayersNum # 91; id # 93;)
start = pos = g_menuPoziția # 91; id # 93; = 0

Noul len = format (menuBody, 511, g_coloredMenus. "\ y% L \ R ./.^ n \ w ^ n". "% L ./.^n^n", id, "CL_CMD_MENU", pos + 1 , (g_menuPlayersNum # 91; id # 93; / 7 + ((g_menuPlayersNum # 91; id # 93;. 7%) 1. 0)))
capăt nou = start + 7
tastele noi = MENU_KEY_0 | MENU_KEY_8

dacă (sfârșitul> g_menuPlayersNum # 91; id # 93;)
end = g_menuPlayersNum # 91; id # 93;

pentru (nou a = start; i = g_menuPlayers # 91; id # 93; # 91; a # 93;
get_user_name (i, nume, 31)

dacă (! g_menuSelectNum # 91; id # 93; || (acces (i, ADMIN_IMMUNITY) i! = id))
++b

dacă (g_coloredMenus)
len + = format (meniuBio # 91; len # 93 ;, 511-len, "\ d ..% s ^ n \
altfel
len + = format (meniuBody # 91; len # 93 ;, 511-len, "#.% s ^ n", nume)
> alte chei | = (1<

dacă (is_user_admin (i))


altfel
len + = format (meniuBody # 91; len # 93 ;, 511-len, "% s ^ n", ++ b, nume)
>
>

dacă (g_menuSelectNum # 91; id # 93;)
len + = format (menuBody # 91; len # 511;, 93-len "^ n8% s ^ n", g_clcmdName # 91; g_menuSelect # 91; id # 93; # 91; g_menuOption # 91; id # 93 ; # 93; # 93;)
altfel
len + = format (meniuBody # 91; len # 93 ;, 511-len, "^ n8.% L ^ n", id, "NO_CMDS")

dacă (sfârșitul! = g_menuPlayersNum # 91; id # 93;)
format (meniuBloc # 91; len # 93 ;, 511-len, "^ n9.% L. ^ n0.% L", id, "MORE", id, poz. "BACK".
chei | = MENU_KEY_9
>
altfel
format (meniuBloc # 91; len # 93 ;, 511-len, "^ n0.% L", id, poz. "BACK".

show_menu (id, taste, meniuBody, -1, "Meniu Cmds client")
>

public cmdlaccmdmenu (id, nivel, cid)
dacă (! cmd_access (id, nivel, cid, 1))
returnați PLUGIN_HANDLED

pentru (nou a = 0; a dacă (acces (id, g_clcmdMisc # 91; a # 93; # 91; 0 # 93;))
g_menuSelect # 91; ID # 93; # 91; g_menuSelectNum # 91; ID # 93; # 93 ++; = a

displaylaccmdmenu (id, g_menuPoziția # 91; id # 93; = 0)

load_settings (szFilename # 91; # 93;)
dacă (! file_exists (szFilename))
retur 0

text nou # 91; 256 # 93; szFlags # 91; 32 # 93; szAccess # 91; 32 # 93;
nou a, pos = 0

în timp ce (g_clcmdNum dacă (text # 91; 0 # 93; == ';') continuați

if (parse (text, g_clcmdName # 91; g_clcmdNum # 93; 31, g_clcmdCmd # 91; g_clcmdNum # 253;, 93, szFlags, 31, szAccess, 31)> 3)
în timp ce (înlocuiți (g_clcmdCmd # 91; g_clcmdNum # 93 ;, 253, "\", "^" "))
// nu face nimic
>

g_clcmdMisc # 91; g_clcmdNum # 93; # 91; 1 # 93; = read_flags (szFlags)
g_clcmdMisc # 91; g_clcmdNum # 93; # 91; 0 # 93; = read_flags (szAccess)
g_clcmdNum ++
>
>







Trimiteți-le prietenilor: