SoftwareGuy / Ignorance

Ignorance utilizes the power of ENet to provide a reliable UDP networking transport for Mirror Networking.
Other
248 stars 31 forks source link

Player crash on second server client connection #59

Closed David548219 closed 4 years ago

David548219 commented 4 years ago

Describe the bug Player crashes after client connects in the second host instance with Ignorance Threaded. Switching to Telepathy makes program run normally. This issue only happens if server is terminated with clients still on, if server is empty is operates normally (local client in host mode does not count). This issue happens both in Host and Server only modes.

from error.log

enet.dll caused an Access Violation (0xc0000005) in module enet.dll at 0033:0aa5399e.

Stack Trace of Crashed Thread 6280: 0x00007FF80AA5399E (enet) enet_peer_send 0x00000059125D6FB6 (Mirror) ENet.Native.enet_peer_send() 0x00000059125D6EF3 (Mirror) ENet.Peer.SendAndReturnStatusCode() 0x0000005912581B2B (Mirror) Mirror.IgnoranceThreaded.ServerWorkerThread() ...

Repro project

To Reproduce Steps to reproduce the behavior:

  1. Build Player for Windows x86_64 with Mono backend
  2. Open 2 instances of the player
  3. Launch Host/Server on first instance
  4. Connect to first instance from the second.
  5. Stop Host/Server on first instance
  6. Launch Host/Server on first instance
  7. Connect to first instance from second.

Expected behavior First instance successfully accepts connection.

Actual behavior First instances crashes.

Desktop

Additional context Error log: https://pastebin.com/9gEZuHVb Player log: https://pastebin.com/HedR6jLK Crash dump: https://www.dropbox.com/s/v6c8bt0ob29zjyq/crash_2020-04-28_213157180.zip?dl=1

SoftwareGuy commented 4 years ago

Thanks for the really detailed bug report. I will pursue this and patch it once I've found the root cause of it. Looking at the log, it seems that the last thing before the crash is:

ERROR: We already know this client in our Peer to ConnectionID Mapping?!
(Filename: C:\buildslave\unity\build\Runtime/Export/Debug/Debug.bindings.h Line: 35)

I have the feeling that the Peer object pointer doesn't exist anymore and we're pointing to some random location in memory... which is no bueno and thus commits suicide. Maybe I'm not cleaning something up before letting ENET get going again, or I screwed up somewhere.

SoftwareGuy commented 4 years ago

Just FYI, I'm going to omit testing on Unity 2020 - that thing is in beta and I don't support alpha/beta versions of Unity. If I can fix it in 2019.2, good chance it'll be fixed in later versions too. Unless there's a burning reason you want to use 2020 with Ignorance, that'll be low priority.

Getting a repro project setup. Then I'll start testing.

SoftwareGuy commented 4 years ago

Well no crash when testing, but I get error code -43 which is for that version of native ENET, means "ENET_PEER_SENDFAILGENERIC". Using a Debug DLL would say "Cannot send data. Peer is not connected, the channel id is above the maximum channels supported or the packet data length is above the maximum packet size"_... Interesting.

Let me take a look at a possible fix.

David548219 commented 4 years ago

No testing with Unity 2020.1 is completely understandable, that's one of the reasons I verified problem on 2019.2. Even if it will be present in 2020.1 after fix, issue can be reopened once 2020.1 gets released. Thank you for rapid reaction, usually takes much longer to get replies.

SoftwareGuy commented 4 years ago

Alright, can you please find this in IgnoranceThreaded.cs:

                print("Flushing...");
                serverWorkerHost.Flush();

...and then put underneath it...

                print("Testing clear fix");
                ConnectionIDToPeers.Clear();
                PeersToConnectionIDs.Clear();

This seems to solve the issue. I think it was me expecting that the dictionaries would clear themselves but that wasn't the case.

David548219 commented 4 years ago

I will do more throughout test later today, but using the provided code snipped fixes the crash and server operates normally as per the steps I described. Thanks!