Page 13 of 14

Re: NT Crash Thread

Posted: Sun Jul 12, 2015 9:39 am
by Faux
At first, I thought this was me, because I had a debug assertion with the same error code about an iterator outside the range. It was there because I hadn't resized the vector based on the max debuffs and buffs rules. I fixed it locally and the error went away. But I haven't committed that code yet.

My dev time is a bit low right now (I basically have an hour or two tops between 9:30 and 11:30pm) to get some stuff done. I'm trying to get a few things done to support Zippy's charge through the combat system, but I'll try taking a look at the SQL implementation. I know nothing about it though so I'm not sure how much it will help.

Re: NT Crash Thread

Posted: Tue Jul 14, 2015 11:28 am
by Xinux

Code: Select all

 	WorldServer.exe!Client::GetAccountID() Line 264	C++
>	WorldServer.exe!Net::SendClientChunkInfo(std::shared_ptr<Client> & client, int coord_x, int coord_y) Line 722	C++
 	WorldServer.exe!CommandProcess::CommandSummon(std::shared_ptr<Client> & client, Separator * sep, unsigned char command_index, bool world_client) Line 1442	C++
 	WorldServer.exe!CommandProcess::Process(std::shared_ptr<Client> & client, Separator * sep, unsigned char command_index, bool world_client) Line 229	C++
 	WorldServer.exe!Net::HandleWorldChatPacket(std::shared_ptr<Client> & client, PacketStruct * packet_struct) Line 796	C++
 	WorldServer.exe!Net::Process() Line 313	C++
 	WorldServer.exe!main(int argc, char * * argv) Line 240	C++
 	WorldServer.exe!__tmainCRTStartup() Line 241	C
 	WorldServer.exe!mainCRTStartup() Line 164	C
 	kernel32.dll!76d9338a()	Unknown
 	[Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]	
 	ntdll.dll!77659f72()	Unknown
 	ntdll.dll!77659f45()	Unknown


Re: NT Crash Thread

Posted: Tue Jul 14, 2015 12:50 pm
by Moldew
If this is beneficial at all - someone online told me she was stuck in APW and couldn't move. I .goto'ed to her to check it out, then I got stuck too. I .rift'ed out and was still stuck in the chunk I .rift'ed to. I tried to .summon her and we crashed.

Re: NT Crash Thread

Posted: Tue Jul 14, 2015 1:30 pm
by Valorith
This is why we can't have nice things

Re: NT Crash Thread

Posted: Tue Jul 21, 2015 9:05 am
by Xinux
This one again.

Code: Select all

>	WorldServer.exe!Mutex::ReadLock() Line 99	C++
 	WorldServer.exe!UDPServer::GetClient(unsigned int account_id) Line 196	C++
 	WorldServer.exe!ChunkServer::GetClient(unsigned int account_id) Line 188	C++
 	WorldServer.exe!UDPServer::KickDupeClients(unsigned int account_id, unsigned int connection_id) Line 270	C++
 	WorldServer.exe!Net::HandleCharacterSelected(std::shared_ptr<Client> & client, PacketStruct * packet_struct) Line 588	C++
 	WorldServer.exe!Net::Process() Line 195	C++
 	WorldServer.exe!main(int argc, char * * argv) Line 249	C++
 	WorldServer.exe!__tmainCRTStartup() Line 241	C
 	WorldServer.exe!mainCRTStartup() Line 164	C
 	kernel32.dll!7716337a()	Unknown
 	ntdll.dll!77c492e2()	Unknown
 	ntdll.dll!77c492b5()	Unknown

Looking at this section of code.

Code: Select all

shared_ptr<Client> UDPServer::GetClient(uint32_t account_id) {
    shared_ptr<Client> client;

    m_clients.ReadLock();
    for (auto& itr : clients) {
        if (itr.second->GetAccountID() == account_id && itr.second->IsConnected()) {
            client = itr.second;
            break;
        }
    }
    m_clients.ReadUnlock();

    return client;
}
shared_ptr<Client> client; is showing empty

Re: NT Crash Thread

Posted: Tue Jul 21, 2015 12:04 pm
by zippyzee
Is it crashing within that code or when it returns a null client? Whatever is calling it needs to be prepared for that possibility. Most all crashes I see programming-wise are by assuming a pointer has a real object to point to and not checking first before accessing member functions and variables.

Re: NT Crash Thread

Posted: Tue Jul 21, 2015 12:35 pm
by smash
[quote="zippyzee"]Is it crashing within that code or when it returns a null client? Whatever is calling it needs to be prepared for that possibility. Most all crashes I see programming-wise are by assuming a pointer has a real object to point to and not checking first before accessing member functions and variables.[/quote]

I'm mostly just looking at EQ2 emu's code right now but took a peek at this since I've seen it posted a few times. It's probably this line here (UDPServer.cpp line 270)

Code: Select all

auto character = world_client->GetCharacter();
	if (character) {
		auto chunk_client = character->GetCurrentChunk()->GetClient(world_client->GetAccountID()); <---
		if (chunk_client) {
			auto chunk = character->GetCurrentChunk();
			if (chunk) {
				chunk->DisconnectChunkClient(chunk_client,CLIENT_DISCONNECT_NEW_CONNECTION_ATTEMPT);
			}
		}
	}
The pointer to the chunk (assuming that's a zone server) is likely invalid.

Re: NT Crash Thread

Posted: Tue Jul 21, 2015 12:36 pm
by John Adams
This one went away for some time. Please check the last few commits for anything touching disconnect. I think Black tried to fix the Unreal channel warning, not sure if it's near this code.

Re: NT Crash Thread

Posted: Tue Jul 21, 2015 1:36 pm
by zippyzee
[quote="smash"][quote="zippyzee"]Is it crashing within that code or when it returns a null client? Whatever is calling it needs to be prepared for that possibility. Most all crashes I see programming-wise are by assuming a pointer has a real object to point to and not checking first before accessing member functions and variables.[/quote]

I'm mostly just looking at EQ2 emu's code right now but took a peek at this since I've seen it posted a few times. It's probably this line here (UDPServer.cpp line 270)

Code: Select all

auto character = world_client->GetCharacter();
	if (character) {
		auto chunk_client = character->GetCurrentChunk()->GetClient(world_client->GetAccountID()); <---
		if (chunk_client) {
			auto chunk = character->GetCurrentChunk();
			if (chunk) {
				chunk->DisconnectChunkClient(chunk_client,CLIENT_DISCONNECT_NEW_CONNECTION_ATTEMPT);
			}
		}
	}
The pointer to the chunk (assuming that's a zone server) is likely invalid.[/quote]

The chunk needs to be accessed first and checked for validity, just like character and the client. Combining both in the auto chunk_client = ... line is a potential hazard. This code is even more odd because in order to have a chunk_client, you have to have a chunk. The code gets the chunk_client by getting the chunk for the character in that line, and then if it gets the chunk_client, goes back to get the chunk again, and tests to see if it is there only at that point (which it had to be to have gotten the chunk_client to begin with, and if it wasn't there then the previous line would have crashed the server). So it really doesn't make much sense logically.

Re: NT Crash Thread

Posted: Tue Jul 21, 2015 2:24 pm
by Blackstorm
Maybe if we add a check :

Code: Select all

shared_ptr<Client> UDPServer::GetClient(uint32_t account_id) {
    shared_ptr<Client> client;

    m_clients.ReadLock();
    for (auto& itr : clients) {
        auto client_check = nullptr;
        client_check = itr.second;
        if(client_check == nullptr)
            continue;
        if (client_check->GetAccountID() == account_id && client_check->IsConnected()) {
            client = client_check;
            break;
        }
    }
    m_clients.ReadUnlock();

    return client;
}