I am encountering this error when a user logins into a server and the server sends the response related to username/password match result. The array which has the reply packet is causing the error. I do not know as to how can I get this fixed, its my first time seeing such an error.
procedure TAgUDP.ProcessLoginPacket
( const APacket : TBytes; const ABinding : TIdSocketHandle );
var
Username : String;
Password : String;
Index : WORD;
ID : TGUID;
Reply : TBytes;
Peer : TAgUDPSPeer;
begin
// Extracting Username
SetLength ( Username, APacket [LI_LNUN] );
Index := 5 + HEADER_END + ( APacket [LI_LNIP] * 2 );
Move ( APacket [Index], Username [1], APacket [LI_LNUN] * 2 );
// Checking whether the peer is already connected
if not Assigned ( fClientsList.FindPeer ( Username )) then
begin
// Extracting Password
SetLength ( Password, APacket [LI_LNPW] );
Index := Index + ( APacket [LI_LNUN] * 2 );
Move ( APacket [Index], Password [1], APacket [LI_LNPW] * 2 );
// Creating Peer Object
CreateGUID ( ID );
Peer :=
TAgUDPSPeer.Create ( ABinding.PeerIP, ABinding.PeerPort, ID, Self );
// Checking whether the database has a record of the user
if fOnLogin ( Peer, Username, Password, Reply ) then
begin
// Assigning username and adding to connected clients list
Peer.fName := Username;
fClientsList.Add ( Peer );
// Extracting local ip+port pair
SetLength ( Peer.fLIP, APacket [LI_LNIP] );
Move ( APacket [LI_PORT], Peer.fLPort, 2 );
Move ( APacket [LI_IPST], Peer.fLIP [1], APacket [LI_LNIP] * 2 );
// -----------------------------------------------------------------------
// Building login reply packet
Index := StrSize ( Peer.fIP ) + HEADER_END + 3;
SetLength ( Reply, Index + Length ( Reply ));
Move ( Reply [0], Reply [Index], Length ( Reply ) - Index );
Reply [0] := Byte ( AgOp_LoginReply );
Move ( fID, Reply [HEADER_SID], 16 );
Move ( Peer.fID, Reply [HEADER_RID], 16 );
Reply [LR_LNIP] := Length ( Peer.fIP );
Move ( Peer.fPort, Reply [LR_PORT], 2 );
Move ( Peer.fIP [1], Reply [LR_IPST], Length ( Reply ) - 3 );
SendBuffer ( ABinding.PeerIP, ABinding.PeerPort, Reply );
end
else
begin
// Building login reply packet - for login rejection
Peer.Free;
SetLength ( Reply, 35 );
Reply [0] := Byte ( AgOp_LoginReply );
SendBuffer ( ABinding.PeerIP, ABinding.PeerPort, Reply );;
end;
end;
// Deliberate freeing of the array to make the debugger stop after this, after exception otherwise it stops after end
SetLength ( Reply, 0 );
end;
function TNetworkModule.OnLogin
( const APeer: TAgUDPSPeer; const AUsername, APassword: String;
var ABuffer: TBytes ): Boolean;
var
DS : TSQLDataset;
Profile : TUser;
begin
DS := TSQLDataSet.Create ( nil );
DS.SQLConnection := DBConnection;
DS.CommandText :=
'SELECT user_id,rating,clan '+
'FROM users '+
'WHERE username='''+ AUsername +''' AND password='''+ APassword +'''';
DS.Open;
Result := not DS.Eof;
if Result then
begin
fLog.Log( ['Event'],
['A login request has been accepted. Username: '+ AUsername] );
// Storing user information
Profile := TUser.Create ( APeer, DS.Fields [0].AsInteger,
DS.Fields [1].AsInteger, DS.Fields [2].AsString );
// Adding user to lobby
fHall.AddUser ( Profile );
// Making a packet to have additional information of the user to be transmitted to
// it in the login reply packet
SetLength ( ABuffer, 4 + StrSize ( Profile.Clan ));
Move ( Profile.Rating, ABuffer [0], 4 );
Move ( Profile.Clan, ABuffer [4], Length ( ABuffer ) - 4 );
end
else
fLog.Log( ['Event'],
['A login request has been denied. Username: '+ AUsername] );
DS.Close;
DS.Free;
end;
FastMM has detected an error during a FreeMem operation. The block footer has been corrupted.
The block size is: 68
This block was allocated by thread 0x9C, and the stack trace (return addresses) at the time was:
419E3E [FastMM4.pas][FastMM4][DebugReallocMem$qqrpvi][8935]
40692F [System.pas][System][@ReallocMem$qqrrpvi][4325]
40C165 [System.pas][System][DynArraySetLength$qqrrpvpvipi][31888]
40C296 [System.pas][System][@DynArraySetLength$qqrv][31967]
A4B26B [AgUDPServer.pas][AgUDPServer][TAgUDP.ProcessLoginPacket$qqrx25System.%DynamicArray$tuc%xp30Idsockethandle.TIdSocketHandle][872]
A4BF94 [AgUDPServer.pas][AgUDPServer][TAgUDP.DoUDPRead$qqrp32Idudpserver.TIdUDPListenerThreadx25System.%DynamicArray$tuc%p30Idsockethandle.TIdSocketHandle][1247]
A486A0 [IdUDPServer.pas][IdUDPServer][TIdUDPListenerThread.UDPRead$qqrv][415]
A485E4 [IdUDPServer.pas][IdUDPServer][TIdUDPListenerThread.Run$qqrv][392]
A466D8 [IdThread.pas][IdThread][TIdThread.Execute$qqrv][363]
484E7D [System.Classes.pas][System.Classes][Classes.ThreadProc$qqrp22System.Classes.TThread][14569]
409F9E [System.pas][System][ThreadWrapper$qqspv][21627]
The block was previously used for an object of class: TDBXDynalinkConnection
The block is currently used for an object of class: Unknown
The allocation number is: 182223
The block was previously freed by thread 0x9C, and the stack trace (return addresses) at the time was:
40690E [System.pas][System][@FreeMem$qqrpv][4251]
4082FD [System.pas][System][TObject.FreeInstance$qqrv][14978]
408A8D [System.pas][System][@ClassDestroy$qqrxp14System.TObject][16273]
AF0F57 [Data.DBXCommon.pas][Data.DBXCommon][Dbxcommon.TDBXConnection.$bdtr$qqrv][8476]
4083FB [System.pas][System][TObject.Free$qqrv][15046]
B6E0A3 [Data.SqlExpr.pas][Data.SqlExpr][Sqlexpr.TSQLConnection.DoDisconnect$qqrv][2563]
A77FE5 [Data.DB.pas][Data.DB][Db.TCustomConnection.SetConnected$qqro][3405]
A77F6F [Data.DB.pas][Data.DB][Db.TCustomConnection.Close$qqrv][3386]
B6D010 [Data.SqlExpr.pas][Data.SqlExpr][Sqlexpr.TSQLConnection.$bdtr$qqrv][2217]
4083FB [System.pas][System][TObject.Free$qqrv][15046]
B7181C [Data.SqlExpr.pas][Data.SqlExpr][Sqlexpr.TCustomSQLDataSet.InternalFreeCommand$qqrv][4046]
The current thread ID is 0x9C, and the stack trace (return addresses) leading to this error is:
40690E [System.pas][System][@FreeMem$qqrpv][4251]
40C3EA [System.pas][System][@DynArrayClear$qqrrpvpv][32152]
40C085 [System.pas][System][DynArrayClear$qqrrpvpv][31815]
40C0C1 [System.pas][System][DynArraySetLength$qqrrpvpvipi][31839]
40C296 [System.pas][System][@DynArraySetLength$qqrv][31967]
A4B3FC [AgUDPServer.pas][AgUDPServer][TAgUDP.ProcessLoginPacket$qqrx25System.%DynamicArray$tuc%xp30Idsockethandle.TIdSocketHandle][904]
A4BF94 [AgUDPServer.pas][AgUDPServer][TAgUDP.DoUDPRead$qqrp32Idudpserver.TIdUDPListenerThreadx25System.%DynamicArray$tuc%p30Idsockethandle.TIdSocketHandle][1247]
A486A0 [IdUDPServer.pas][IdUDPServer][TIdUDPListenerThread.UDPRead$qqrv][415]
A485E4 [IdUDPServer.pas][IdUDPServer][TIdUDPListenerThread.Run$qqrv][392]
A466D8 [IdThread.pas][IdThread][TIdThread.Execute$qqrv][363]
484E7D [System.Classes.pas][System.Classes][Classes.ThreadProc$qqrp22System.Classes.TThread][14569]
Block footer corruption is a FastMM4 FullDebugMode error. It means that somewhere, something in your code is writing past the end of allocated memory. Probably the best candidate to look at is any Move
calls.
How reproducible is this? If it happens every time, there's an easy way to track it down:
SetLength
call)@Reply[19]
.) This will give you a memory address, in hexadecimal. Add 1 to this value to get the address of the first byte beyond the boundaries of the array.