Page 1 of 1

Memory error in SendNetworkData

Posted: Wed Dec 18, 2024 9:34 pm
by danny88
Hello,

I wrote an enhanced SendNetworkData function that checks if all data was sent. it receives a packet that should have a header containig the packet length in 8 bytes followed by packet type in 1 byte then the payload.

it's been months i'm trying to figure out a problem : once in a while, i get [ERROR] Invalid memory access. (read error at address 3473458).
I can't figure out what conditions raise this error.

is there a way to handle this error or a sort of on "error resume next"

Here is the function :

Code: Select all

Procedure SendNetworkData2(ConnectionID.l, *b) 
  Protected DataSent.q = 0, TotaltDataSent.q = 0
  Protected length.q = PeekQ(*b)
  Protected type = PeekA(*b + 8)
  Repeat
    DataSent = SendNetworkData(ConnectionID, *b + TotaltDataSent, length - TotaltDataSent)
    If DataSent > 0
      TotaltDataSent + DataSent
    EndIf
    Delay(1)      
  Until TotaltDataSent = Length   
  FreeMemory(*b)
  ProcedureReturn TotaltDataSent
EndProcedure

Re: Memory error in SendNetworkData

Posted: Wed Dec 18, 2024 10:14 pm
by infratec
You have to find the error and not work arround it :wink:

Try this;

Code: Select all

#MaxPacketSize = 1400 ; depending on UDP or TCP

Procedure.i SendNetworkData2(ConnectionID.i, *b) 
  
  Protected.a type
  Protected.i DataSent
  Protected.q TotaltDataSent, length, ToSend
  
  
  length = PeekQ(*b)
  type = PeekA(*b + 8)
  
  Repeat
    ToSend = length - TotaltDataSent
    If ToSend > #MaxPacketSize
      ToSend = #MaxPacketSize
    EndIf
    DataSent = SendNetworkData(ConnectionID, *b + TotaltDataSent, ToSend)
    If DataSent > 0
      TotaltDataSent + DataSent
    EndIf
    Delay(1)
  Until TotaltDataSent = Length
  
  FreeMemory(*b)
  
  ProcedureReturn TotaltDataSent
  
EndProcedure

Re: Memory error in SendNetworkData

Posted: Wed Dec 18, 2024 10:21 pm
by infratec
Since it looks like you want to transfer the complete buffer:

Code: Select all

#MaxPacketSize = 1400 ; depending on UDP or TCP

Procedure.i SendNetworkData2(ConnectionID.i, *b) 
  
  Protected.i DataSent, TotaltDataSent, length, ToSend, Error
  
  
  length = MemorySize(*b)
  
  Repeat
    ToSend = length - TotaltDataSent
    If ToSend > #MaxPacketSize
      ToSend = #MaxPacketSize
    EndIf
    DataSent = SendNetworkData(ConnectionID, *b + TotaltDataSent, ToSend)
    If DataSent > 0
      TotaltDataSent + DataSent
      Error = 0
    Else
      Error - 1
    EndIf
    Delay(1)
  Until TotaltDataSent = Length Or Error = -3
  
  If Error = 0
    FreeMemory(*b)
  Else
    TotaltDataSent = Error
  EndIf
  
  ProcedureReturn TotaltDataSent
  
EndProcedure

Re: Memory error in SendNetworkData

Posted: Thu Dec 19, 2024 8:22 am
by danny88
.

Re: Memory error in SendNetworkData

Posted: Thu Dec 19, 2024 8:28 am
by danny88
Still the same error :/

Actually, the server uses that function to ping a list of connected clients that may disconnect at any time.
I tried checking if ConnectionID is not 0 before sending the packet but still the same

Re: Memory error in SendNetworkData

Posted: Thu Dec 19, 2024 9:04 am
by dige
In my experience, the function that is currently crashing is not necessarily the actual problem, but there was already a memory overflow somewhere before. It may help, if you activate Purifier and set it to PurifierGranularity(1, 1, 1, 1).

Re: Memory error in SendNetworkData

Posted: Thu Dec 19, 2024 6:57 pm
by danny88
I'm pretty sure it's related to that specific function

Re: Memory error in SendNetworkData

Posted: Thu Dec 19, 2024 7:27 pm
by STARGĂ…TE
danny88 wrote: Thu Dec 19, 2024 6:57 pm I'm pretty sure it's related to that specific function
:lol: Nice joke^^.

Here is a very quick example that this kind of thinking is incorrect.

Code: Select all

Define *Buffer1 = AllocateMemory(400)
Define *Buffer2 = AllocateMemory(500)

; Here, you want to check the size of *Buffer1 and *Buffer2.
Debug MemorySize(*Buffer1)
Debug MemorySize(*Buffer2)

; Here, a string is written into *Buffer1, but it overwrites its end.
PokeS(*Buffer1+390, "This is a very long string that corrupts the next memory buffer.") ; No error here (without enabled purifier)

; Here, you want to check the size of *Buffer1 and *Buffer2 (where nothing should happen) again.
Debug MemorySize(*Buffer1)
Debug MemorySize(*Buffer2)  ; Invalid memory ID in line 13, but the "misstake" was at line 9
Have you checked, if the address error which you quoted is related to the buffer or in its near?

Re: Memory error in SendNetworkData

Posted: Tue Dec 24, 2024 12:43 am
by danny88
Actually I think that the error occurs when ClientID doesn't exist anymore.

So is there a way to check if a ConnectionID really exist before sending data ?

Re: Memory error in SendNetworkData

Posted: Tue Dec 24, 2024 2:25 am
by idle
You could try using the error check code from atomic webserver

Code: Select all

Procedure Atomic_Server_NetworkErrorContinue(ID) 
  Protected ret,option.l,oplen.l=4 
  
  #WSA_IO_INCOMPLETE = 996
  #WSA_IO_PENDING = 997
  #WSAEINTR = 10004
  #WSAEMFILE = 10024
  #WSAEWOULDBLOCK = 10035
  #WSAEINPROGRESS = 10036
  #WSAEALREADY = 10037
  
  #_WANT_POLLIN  = -2
  #_WANT_POLLOUT = -3
    
  CompilerIf #PB_Compiler_OS = #PB_OS_Windows 
    option = WSAGetLastError_()
  CompilerElse 
    CompilerIf #PB_Compiler_Backend = #PB_Backend_C
      !#include "errno.h"
      !extern int errno;
      !v_option=errno;
    CompilerElse
      option = errno 
    CompilerEndIf 
  CompilerEndIf
    
  Select option 
    Case 0 
      ret = 1
    Case  #WSAEWOULDBLOCK  
      ret = 1 
      Debug "would block"
    Case  #WSAEINPROGRESS   
      Debug "#WSAEINPROGRESS"
      ret = 1  
    Case  #WSAEALREADY  
      Debug "#WSAEALREADY"
      ret = 1  
    Case  #WSA_IO_INCOMPLETE
      Debug "#WSA_IO_INCOMPLETE"
      ret =1   
    Case  #WSA_IO_PENDING
      Debug "#WSA_IO_PENDING"
      ret = 1  
    Case  #WSAEMFILE 
      ret =1 
      Debug "#WSAEMFILE"
    Case #_WANT_POLLIN
      ret =1 
       Debug "#TLS_WANT_POLLIN"
    Case #_WANT_POLLOUT 
      ret = 1 
      Debug "#TLS_WANT_POLLOUT"
    Default 
      Debug option   
  EndSelect   
  
  ProcedureReturn ret 
  
EndProcedure  
If it returns 1 its OK call it when pb returns -1

Re: Memory error in SendNetworkData

Posted: Tue Dec 24, 2024 8:43 am
by danny88
look at this example :

Code: Select all

ClientID = 750154536	;Invalid Connection ID

sent = SendNetworkString(ClientID, "Hello"); Returns Invalid memory accesss
Atomic_Server_NetworkErrorContinue(ClientID) still returns 1