IS4Code / YSF

YSF Server Functions
Other
98 stars 34 forks source link

Pickup crash and how to produce + Streamer Plugin #144

Open devbluen opened 2 years ago

devbluen commented 2 years ago

Hello everybody. I ended up discovering a glitch that causes the server to freeze. I will explain below

In "OnPlayerDisconnect" if you use "CallRemoteFunction" and create a new callback that causes the pickup to be destroyed, the server freezes for no reason.

To reproduce this problem is easy. Create a DynamicPickup stay close to it and I destroy it by disconnecting using the CallRemoteFunction that redirects to another callback.

Note: This bug has only been tested with the "DestroyDynamic" streamer plugin

Example:

new Picp[MAX_PLAYERS];
public OnPlayerSpawn(playerid)
{
new Float:TempPos[3];
GetPlayerPos(playerid, TempPos[0], TempPos[1], TempPos[2]);
Picp[playerid] = CreateDynamicPickup(1239, 1, TempPos[0], TempPos[1], TempPos[2], 0, 0, playerid, 60.0, -1, 0);
return true;
}

public OnPlayerDisconnect(playerid, reason)
{
CallRemoteFunction("Test_Destroy", "d", playerid);
return true;
}

forward Test_Destroy(playerid);
public Test_Destroy(playerid)
{
DestroyDynamicPickup(Picp[playerid]);
return true;
}

This code above is just an example, if you want to reproduce this is the correct way.

I will emphasize again. For this problem to happen you need to be close to the pickup and the callback must be called via "OnPlayerDisconnect" with "CallRemoteFunction"

devbluen commented 2 years ago

To help with identification. The problem can be fixed instantly if before destroying the pickup you virtualize it in another world where no player can see it.

Example:

Streamer_SetIntData(STREAMER_TYPE_PICKUP, Picp[playerid], E_STREAMER_WORLD_ID, 99999);
DestroyDynamicPickup(Picp[playerid]);
v1934 commented 1 year ago

Is there any news regarding this issue and the one previously reported by me in https://github.com/IS4Code/YSF/issues/141

I keep getting these crashes, and I read this issue here regarding calling DestroyDynamicPickup remotely in OnPlayerDisconnect but I'm not doing anything like that on my server. In fact, the only place where I destroy pickups other than admin actions (which are all logged and they didn't happen at the moment of crash) is OnPlayerPickUpDynamicPickUp and it also didn't happen at that moment, because I have logs added before this happens.

What causes this indeed is player disconnection, but it is not triggered by any manual DestroyDynamicPickup in my case but from Streamer's pickup streaming mechanism. My last crash happened exactly when a player (actually my admin) disconnected from the server, yet there wasn't even any log about his disconnection. The crash happened in between:

[25/03/2023 22:28:59] [debug] Server crashed due to an unknown error
[25/03/2023 22:28:59] [debug] Native backtrace:
[25/03/2023 22:28:59] [debug] #0 f7a32e8b in _ZN10StackTraceC1EPv () from plugins/crashdetect.so
[25/03/2023 22:28:59] [debug] #1 f7a2bbcf in _ZN11CrashDetect20PrintNativeBacktraceERSoPv () from plugins/crashdetect.so
[25/03/2023 22:28:59] [debug] #2 f7a2cdbc in _ZN11CrashDetect20PrintNativeBacktraceEPv () from plugins/crashdetect.so
[25/03/2023 22:28:59] [debug] #3 f7a2d226 in _ZN11CrashDetect11OnExceptionEPv () from plugins/crashdetect.so
[25/03/2023 22:28:59] [debug] #4 f7a32adc in ?? () from plugins/crashdetect.so
[25/03/2023 22:28:59] [debug] #5 f7f63570 in __kernel_rt_sigreturn () from linux-gate.so.1
[25/03/2023 22:28:59] [debug] #6 f7958129 in _ZN7CPlugin14RebuildRPCDataEhPN6RakNet9BitStreamEt () from plugins/YSF.so
[25/03/2023 22:28:59] [debug] #7 f796860d in _ZN14CHookRakServer5RPC_2EPvPhPN6RakNet9BitStreamE14PacketPriority17PacketReliabilityj8PlayerIDbb () from plugins/YSF.so
[25/03/2023 22:28:59] [debug] #8 080ac299 in ?? () from ./samp03svr
[25/03/2023 22:28:59] [debug] #9 080c8e8f in ?? () from ./samp03svr
[25/03/2023 22:28:59] [debug] #10 080cb1a5 in ?? () from ./samp03svr
[25/03/2023 22:28:59] [debug] #11 080c8cb8 in ?? () from ./samp03svr
[25/03/2023 22:28:59] [debug] #12 f6262135 in sampgdk_DestroyPickup () from plugins/streamer.so
[25/03/2023 22:28:59] [debug] #13 f628d1d1 in _ZN8Streamer13streamPickupsEv () from plugins/streamer.so
[25/03/2023 22:28:59] [debug] #14 f62a6f82 in _ZN8Streamer20startAutomaticUpdateEv () from plugins/streamer.so
[25/03/2023 22:28:59] [debug] #15 f62a704f in ProcessTick () from plugins/streamer.so
[25/03/2023 22:28:59] [debug] #16 080d1ce2 in ?? () from ./samp03svr
[25/03/2023 22:28:59] [debug] #17 080aef6c in ?? () from ./samp03svr
[25/03/2023 22:28:59] [debug] #18 080aa13a in ?? () from ./samp03svr
[25/03/2023 22:28:59] [debug] #19 f7a70e46 in __libc_start_main () from /lib/i386-linux-gnu/libc.so.6
[25/03/2023 22:28:59] [debug] #20 0804b4e1 in ?? () from ./samp03svr

So moving the pickup anywhere won't help, it's caused by Streamer using the built-in DestroyPickup native when streaming.