Segmentation Fault pytanie
Andrzejek
24.01.2016
Witam, czy sprawdzanie graczy przy pomocy
for(new i=0; i<=get_maxplayers(); i++) {
}
1. może być przyczyną błędu Segmentation Fault ??
2. i czy lepiej sprawdzać tak
new players[32], plnum;
get_players(players, plnum, "flagi dodatkowe");
for(new i = 0; i < plnum; i++) {
}
grankee
25.01.2016
Lepiej pierwszą metodą a na początku w pętli
if(!is_user_connected(i)) continue
warunek możesz zmieniać dowolnie np is_user_alive itp, zależnie od potrzeb
get_players działa wadliwie
Andrzejek
25.01.2016
Lepiej pierwszą metodą a na początku w pętli
if(!is_user_connected(i)) continuewarunek możesz zmieniać dowolnie np is_user_alive itp, zależnie od potrzeb
get_players działa wadliwie
Ty się nie przejmuj jaki warunek będzie, bo zawsze sprawdzam czy gracz jest połączony. Mi chodzi o to czy pierwsza metoda ma jakiś wpływ na działanie serwer, obciążanie i wole dostać takie informacje od osób, które to sprawdziły obie metody.
grankee
25.01.2016
Odniosłem wrażenie trochę niemiłego tonu. Skąd wniosek, że nie sprawdzałem obu metod? W ogóle to może wypisz tu listę osób, którym zezwalasz na wypowiadanie się w tak 'trudnej' sprawie.
Napisałem wyraźnie, get_players działa wadliwie, po co się zastanawiać nad wydajnością pierwszej metody jeśli nie ma lepszej od niej?
Jak masz dwa samochody i jeden nie ma koła to czym kierujesz się w decyzji którym pojechać? Osiągami do setki?
Przeczytaj co masz nad avatarem i zachowaj odrobinkę skromności
Użytkownik grankee edytował ten post 25.01.2016 21:25
Andrzejek
25.01.2016
Odniosłem wrażenie trochę niemiłego tonu. Skąd wniosek, że nie sprawdzałem obu metod? W ogóle to może wypisz tu listę osób, którym zezwalasz na wypowiadanie się w tak 'trudnej' sprawie.
Napisałem wyraźnie, get_players działa wadliwie, po co się zastanawiać nad wydajnością pierwszej metody jeśli nie ma lepszej od niej?
Jak masz dwa samochody i jeden nie ma koła to czym kierujesz się w decyzji którym pojechać? Osiągami do setki?
Przeczytaj co masz nad avatarem i zachowaj odrobinkę skromności
Ojejku spokojnie, przecież nigdzie nie napisałem że ty nie sprawdziłeś obu metod, ale poczekam jeszcze jak inni się wypowiedzą
DarkGL
25.01.2016
Oczywiście że może być powodem błędu bo nie wiadomo co robisz w tej pętli.
Andrzejek
25.01.2016
Oczywiście że może być powodem błędu bo nie wiadomo co robisz w tej pętli.
No przykładowo sprawdzam ilość żywych graczy co sekundę? Lub coś innego i też wykonuje co sekundę.
grankee
26.01.2016
Przykładowo jeśli sprawdzasz tylko ilość żywych graczy co sekundę to z technicznego punktu widzenia obie metody nie powodują tego błędu, ale w praktyce potrafią się dziać cuda, których nie idzie wyjaśnić. Inna sprawa, że metoda z użyciem get_players może przynosić fałszywe dane.
(Jako przykład niewyjaśnionych cudów mogę tutaj podać próbę znalezienia błędu w prawidłowym kodzie przeze mnie i GwynBleidd'a, kod był w porządku, jednak funkcja zatrzymywała się w pewnym momencie bez przyczyny, zero orrorów. Po dodaniu jednej linijki if kod szedł dalej i działał, po cofnięciu zmian - skasowaniu dodanej linijki kod zaczął działać jak należy. Zastanawialiśmy się tak głęboko, że doszliśmy w rozważaniach do teorii kwantowej....dalej nie będę pisał )
Jednak jeśli używasz metody get_players i wykonujesz inne operacje na graczu, którego nie ma na serwerze bądź jest martwy a get_players zwraca Ci błędnie, że gracz jest na serwerze albo że jest żywy to jak najbardziej może być ten błąd tym spowodowany.
Błąd segmentation fault jest naruszeniem ochrony pamięci. Występuje zwykle kiedy program/plugin skorzysta z pamięci wcześniej dla niego niezaalokowanej, np. dokona zapisu w pamięci przeznaczonej tylko do odczytu (stałe) albo używanej przez jądro systemu... Wydaje mi się, że można tego nawet dokonać poprzez odwołanie się do nieistniejącego elementu tablicy, zapisu nieprawidłowej wartości dla danego typu zmiennej do tej zmiennej, przepełnienia jej 'pojemności' poprzez szybkie podnoszenie wartości itp...
Prościej by było gdybyś podał fragment kodu, który podejrzewasz o wywoływanie tego błędu oraz powiązanych z nim funkcji.
Użytkownik grankee edytował ten post 26.01.2016 01:25
Master Yoga
26.01.2016
Zwykłe przeoczenie, ponieważ podczas powtarzania się pętli nie sprawdzałem czy gracz jest żywy/połączony i/lub czy Client jest graczem.
Oczywiście niezwłocznie to poprawiałem i jak do tej pory sytuacja sie nie powtórzyła.
Andrzejek
26.01.2016
Przykładowo jeśli sprawdzasz tylko ilość żywych graczy co sekundę to z technicznego punktu widzenia obie metody nie powodują tego błędu, ale w praktyce potrafią się dziać cuda, których nie idzie wyjaśnić. Inna sprawa, że metoda z użyciem get_players może przynosić fałszywe dane.
(Jako przykład niewyjaśnionych cudów mogę tutaj podać próbę znalezienia błędu w prawidłowym kodzie przeze mnie i GwynBleidd'a, kod był w porządku, jednak funkcja zatrzymywała się w pewnym momencie bez przyczyny, zero orrorów. Po dodaniu jednej linijki if kod szedł dalej i działał, po cofnięciu zmian - skasowaniu dodanej linijki kod zaczął działać jak należy. Zastanawialiśmy się tak głęboko, że doszliśmy w rozważaniach do teorii kwantowej....dalej nie będę pisał
)
Jednak jeśli używasz metody get_players i wykonujesz inne operacje na graczu, którego nie ma na serwerze bądź jest martwy a get_players zwraca Ci błędnie, że gracz jest na serwerze albo że jest żywy to jak najbardziej może być ten błąd tym spowodowany.
Błąd segmentation fault jest naruszeniem ochrony pamięci. Występuje zwykle kiedy program/plugin skorzysta z pamięci wcześniej dla niego niezaalokowanej, np. dokona zapisu w pamięci przeznaczonej tylko do odczytu (stałe) albo używanej przez jądro systemu... Wydaje mi się, że można tego nawet dokonać poprzez odwołanie się do nieistniejącego elementu tablicy, zapisu nieprawidłowej wartości dla danego typu zmiennej do tej zmiennej, przepełnienia jej 'pojemności' poprzez szybkie podnoszenie wartości itp...
Prościej by było gdybyś podał fragment kodu, który podejrzewasz o wywoływanie tego błędu oraz powiązanych z nim funkcji.
Bym musiał chyba całego moda tu podesłać, ale tego niestety nie zrobię. Errorów zero, po necie czytałem różne poradnik co jest lepsze w użyciu i dodawałem to do swojego kodu i nie wiem co może być przyczyną.
U mnie hlds siadał wywalając ten error przy zbyt dużej ilości wysyłanych błędnych informacji.
Zwykłe przeoczenie, ponieważ podczas powtarzania się pętli nie sprawdzałem czy gracz jest żywy/połączony i/lub czy Client jest graczem.
Oczywiście niezwłocznie to poprawiałem i jak do tej pory sytuacja sie nie powtórzyła.
A której pętli używałeś get_players? Bo ja też sprawdzam na początku pętli czy graczy jest połączony.
Andrzejek
26.01.2016
Ani jednej ani drugiej.
Ja używam get_playersnum()
I jak się sprawuję?
Master Yoga
26.01.2016
2.
Funkcja get_maxplayers() tak na dobra sprawę pobiera ci ilość slotów
Zakładając, że masz 25 slotowy serwer to petla powtórzy sie 25 razy nawet jak będzie tylko 3 graczy.
Pamiętaj, że gracz żywy to nie zawszę gracz połączony.
Nie mam powodów by narzekać funkcja get_playersnum() pobiera aktualna ilość graczy należycie ponadto ma parametr który wyklucza badz włącza graczy którzy dopiero sie łączą z serwerem.
grankee
26.01.2016
Nie mam powodów by narzekać funkcja get_playersnum() pobiera aktualna ilość graczy należycie ponadto ma parametr który wyklucza badz włącza graczy którzy dopiero sie łączą z serwerem.
Załóżmy następującą sytuację:
Wchodzi gracz, dostaje id 1
wchodzi kolejny, dostaje id 2
itd..
mamy na serwerze 10 graczy, których id jest od 1 do 10.
wychodzą gracze o id 3, 4, 5
mamy na serwerze 7 graczy o id: 1,2,6,7,8,9,10
funkcja get_playersnum() zwraca nam 7, bo tylu jest graczy.
Dajesz pętlę:
for(new a=1;a<=get_playersnum();a++)
pętla wykonuje się 7 razy dla id: 1,2,3,4,5,6,7
wykonujesz operacje na nieistniejących bytach 3,4,5 natomiast pomijasz graczy o id 8,9,10.
W efekcie może wystąpić błąd Segmentation Fault, albo inny powodujący crash, może lecz nie musi. Pewne jest jedno: pomijasz 3 graczy.
Funkcja get_maxplayers() tak na dobra sprawę pobiera ci ilość slotów
Zakładając, że masz 25 slotowy serwer to petla powtórzy sie 25 razy nawet jak będzie tylko 3 graczy.
Czy aby na pewno na serwerze x-slotowym gracz nie może dostać id x+1?
Wydaje mi się, że taką sytuację miałem kiedyś, serwer miał 15 slotów a ktoś miał id 16.
Dlatego uważam, że powtarzanie pętli 32 razy i sprawdzanie w środku czy dany gracz istnieje, jest połączony, żywy itd. zależnie od potrzeb, jest napewniejszą i najbezpieczniejszą metodą, a przy tym względnie optymalną.
Pamiętaj, że gracz żywy to nie zawszę gracz połączony.
A nie odwrotnie? Jak coś nie istnieje to ja może być żywe?
Andrzejek
26.01.2016
Get_players nie jest juz wspierane.
2.
Funkcja get_maxplayers() tak na dobra sprawę pobiera ci ilość slotów
Zakładając, że masz 25 slotowy serwer to petla powtórzy sie 25 razy nawet jak będzie tylko 3 graczy.
Pamiętaj, że gracz żywy to nie zawszę gracz połączony.
Nie mam powodów by narzekać funkcja get_playersnum() pobiera aktualna ilość graczy należycie ponadto ma parametr który wyklucza badz włącza graczy którzy dopiero sie łączą z serwerem.
Te argumenty mnie przekonały i zacznę używać get_playersnum(), bo nie wiem po co mam powtarzać 25 razy pętle jak na serwerze jest 3 graczy, jak zastosuje aktualna ilość graczy to zawsze jakiejś mniejsze obciążenie.
@edit
grankeenie zauważyłem postu twojego i w sumie też masz rację. To już sam nie wiem
Master Yoga
27.01.2016
I w sumie to mnie masz. Brawo ty.Nie mam powodów by narzekać funkcja get_playersnum() pobiera aktualna ilość graczy należycie ponadto ma parametr który wyklucza badz włącza graczy którzy dopiero sie łączą z serwerem.
Załóżmy następującą sytuację:
Wchodzi gracz, dostaje id 1
wchodzi kolejny, dostaje id 2
itd..
mamy na serwerze 10 graczy, których id jest od 1 do 10.
wychodzą gracze o id 3, 4, 5
mamy na serwerze 7 graczy o id: 1,2,6,7,8,9,10
funkcja get_playersnum() zwraca nam 7, bo tylu jest graczy.
Dajesz pętlę:for(new a=1;a<=get_playersnum();a++)pętla wykonuje się 7 razy dla id: 1,2,3,4,5,6,7
wykonujesz operacje na nieistniejących bytach 3,4,5 natomiast pomijasz graczy o id 8,9,10.
W efekcie może wystąpić błąd Segmentation Fault, albo inny powodujący crash, może lecz nie musi. Pewne jest jedno: pomijasz 3 graczy.
Czy aby na pewno na serwerze x-slotowym gracz nie może dostać id x+1?Funkcja get_maxplayers() tak na dobra sprawę pobiera ci ilość slotów
Zakładając, że masz 25 slotowy serwer to petla powtórzy sie 25 razy nawet jak będzie tylko 3 graczy.
Wydaje mi się, że taką sytuację miałem kiedyś, serwer miał 15 slotów a ktoś miał id 16.
Dlatego uważam, że powtarzanie pętli 32 razy i sprawdzanie w środku czy dany gracz istnieje, jest połączony, żywy itd. zależnie od potrzeb, jest napewniejszą i najbezpieczniejszą metodą, a przy tym względnie optymalną.
Pamiętaj, że gracz żywy to nie zawszę gracz połączony.
A nie odwrotnie? Jak coś nie istnieje to ja może być żywe?
Choć to sytuację czysto hipotetyczne ilość graczy się zmienia ktoś wchodzi, ktoś wychodzi ciężko pominąć gracza, ale to możliwe.
Spokojnie, to że mam ilość graczy nie znaczy, że na każdym mogę bezbłędnie wykonać operację, dlatego też przed wykonaniem jakichś operacji jest szereg warunków

Nie, nie odwrotnie. A grankee napisałem, że byt nie istnieję??
A jeżeli zostanie zerwane połączenie miedzy klientem a serwerem i w tym czasie zostaną wykonane jakieś funkcję to byt zostanie od razu zniszczony a klient rozłączony?? Nawet po dłuższym lagu ( ale bez przesady )możesz wrócić do gry.
Popracuj jeśli chcesz na najnowszym ZP tam czasem potrafią sie dziać cuda

W sumie to najlepszym sposobem byłoby tu zastosowanie pętli i instrukcji continue.
Zgadzasz sie grankee

Andrzejek
27.01.2016
Ale get_playersnum() mogę użyć w funkcji, która jest wykonywana co 1 sek. Ale w pętlach co sprawdzam tylko raz zastosuje get_maxplayer();
grankee
27.01.2016
Nie, nie odwrotnie. A grankee napisałem, że byt nie istnieję??
A jeżeli zostanie zerwane połączenie miedzy klientem a serwerem i w tym czasie zostaną wykonane jakieś funkcję to byt zostanie od razu zniszczony a klient rozłączony?? Nawet po dłuższym lagu ( ale bez przesady )możesz wrócić do gry.
Popracuj jeśli chcesz na najnowszym ZP tam czasem potrafią sie dziać cuda
Nie napisałeś, że byt nie istnieje, ale to właśnie wywnioskowałem, ponieważ gracz niepołączony=brak entity. Jeśli gracz się łączy to byt się tworzy, jeśli gracz się rozłącza to byt zostaje usunięty. Opisana przez Ciebie sytuacja to jedynie brak przesyłania pakietów między klientem a serwerem z rozmaitych powodów. W praktyce jednak gracz jest cały czas połączony i możesz wykonywać operacje na jego bycie, po prostu gracz zobaczy zmiany po wznowieniu przesyłu danych serwer->gracz. Gracz przestaje być połączony 'w oczach' serwera tylko w trzech przypadkach: wyjdzie z gry(disconnect, retry, połączenie z innym serwerem), z powodu braku przesyłu danych serwer rozłączy gracza po upływie czasu timeout, serwer zostanie wyłączony. W każdym z tych przypadków byt gracza przestaje istnieć.
W sumie to najlepszym sposobem byłoby tu zastosowanie pętli i instrukcji continue.
Zgadzasz sie grankee ??
Dla mnie zawsze najlepszy, bo 100% niezawodny sposób to:
for(new a=1;a<=32;a++) { if(!is_user_connected(a)) continue //kod }
oczywiście warunek wg potrzeb.
Andrzejek
28.01.2016
Dla mnie zawsze najlepszy, bo 100% niezawodny sposób to:
for(new a=1;a<=32;a++) { if(!is_user_connected(a)) continue //kod }oczywiście warunek wg potrzeb.
A dlaczego 32 a nie get_maxplayers?
grankee
28.01.2016
A dlaczego 32 a nie get_maxplayers?
Wydaje mi się, że taką sytuację miałem kiedyś, serwer miał 15 slotów a ktoś miał id 16.
Dlatego uważam, że powtarzanie pętli 32 razy i sprawdzanie w środku czy dany gracz istnieje, jest połączony, żywy itd. zależnie od potrzeb, jest napewniejszą i najbezpieczniejszą metodą, a przy tym względnie optymalną.