Access violation at address 00000000. Read of address 00000000

guys, i have a program server that uses tidcmdtcpserver, then i'm storaging clients information inside this record:

  PClient   = ^TClient;
  TClient   = record
    HostName    : String[20];  { Hostname }
    PeerIP      : String[15];  { Cleint IP address }
    Ver         : String[4];
    PathInstall : ShortString;
    TakeShot    : boolean;     { explained later }
    Connected,                 { Time of connect }
    LastAction  : TDateTime;   { Time of last transaction }
    AContext    : Pointer;     { Pointer to thread }
    Connection  : TIdTCPConnection;
    IOHandle    : TIdIOHandler;
  end;

  //put this on the var section
  //var
  //Clients : TThreadList;

then ever time the clients connects, i'm doing this like this:

procedure TFPrinc.IdCmdTCPServer1Connect(AContext: TIdContext);
var
  Maq, Ver, PathInstall : shortstring;
  NewClient: PClient;
begin
   { THESE TWO LINES ARE CRITICAL TO MAKING THE IdcmdTCPSERVER WORK WITH SSL! }
   if (AContext.Connection.IOHandler is TIdSSLIOHandlerSocketBase) then
   begin
     TIdSSLIOHandlerSocketBase(AContext.Connection.IOHandler).PassThrough:= False;
   end;
   Maq := AContext.Connection.IOHandler.ReadLn;
   Ver := AContext.Connection.IOHandler.ReadLn;
   PathInstall := AContext.Connection.IOHandler.ReadLn;

            GetMem(NewClient, SizeOf(TClient));
            NewClient.PeerIP      := AContext.Connection.Socket.Binding.PeerIP;
            NewClient.HostName    := Maq;
            NewClient.Ver         := Ver;
            NewClient.PathInstall := PathInstall;
            NewClient.TakeShot    := False;
            NewClient.Connected   := Now;
            NewClient.LastAction  := NewClient.Connected;
            NewClient.AContext    :=  Acontext;
            NewClient.Connection  := Acontext.Connection;
            NewClient.IOHandle    := Acontext.Connection.IOHandler;
            AContext.Data := TObject(NewClient);
            Clients.LockList.Add(NewClient);
            Clients.UnlockList;



then when i execute this code several times to send some message to the client the error shows up, the client receive the information normally before this, but after the error happening, the client do not receive anyinformation, and the error show up ever time that i click to execute the code:

procedure TFPrinc.ToolButton23Click(Sender: TObject);
var
  i:integer;
begin
 with Clients.LockList do
  try
    for i := 0 to Count-1 do
    begin
      AClient := Items[i];
      Aclient.IOHandle.WriteLn('MSG');
    end;
  finally
    Clients.UnlockList;
  end;
LVL 1
rafaelrglAsked:
Who is Participating?
 
diniludCommented:
Access violation means you are try to aceess some invalid memory.

Means that some invalid pointer is there in Clients List.
0
 
MerijnBSr. Software EngineerCommented:
to be more specific, it is of address 00000000 meaning that you are using a nil pointer as an object, this should be quite easy to find.
Where in your code are clients removed from the list?

a start could be in this procedure:

procedure TFPrinc.ToolButton23Click(Sender: TObject);
var
  i:integer;
begin
 with Clients.LockList do
  try
    for i := 0 to Count-1 do
    begin
      AClient := Items[i];
      if (AClient = nil) or (AClient.IOHandle0 = nil) then
       sleep(0);
      Aclient.IOHandle.WriteLn('MSG');
    end;
  finally
    Clients.UnlockList;
  end;


now put a breakpoint on the line with sleep(0), if it comes you are in the situation where you are about to get the access violation, maybe you are able to get some more info at this poinst.
0
Cloud Class® Course: Microsoft Azure 2017

Azure has a changed a lot since it was originally introduce by adding new services and features. Do you know everything you need to about Azure? This course will teach you about the Azure App Service, monitoring and application insights, DevOps, and Team Services.

 
diniludCommented:
Did you freeing the Client while disconnect the TCPServer?

{========================================}

procedure TMainFormServer.TCPServerDisconnect(AThread: TIdPeerThread);
var
  Client: PClient;
begin
  Client := PClient(AThread.Data);
  //Protocol.Lines.Add (TimeToStr(Time)+' Disconnect from "' + Client.HostName+'"');
  try
    Clients.LockList.Remove(Client);
  finally
    Clients.UnlockList;
  end;
  FreeMem(Client);
  AThread.Data := nil;

  //RefreshListDisplay;
end; (* TCPServer Disconnect *)
0
 
rafaelrglAuthor Commented:
here when the client disconnects from the server, i think is normal, take a look:

procedure TFPrinc.IdCmdTCPServer1Disconnect(AContext: TIdContext);
var
   Client : PClient;
begin
  Client := PClient(AContext.Data);
  try
    Clients.LockList.Remove(Client);
  finally
    Clients.UnlockList;
  end;
  FreeMem(Client);
  AContext.Data := nil;
end;


also, i test the procedure that MerijnB gave above, after trying several times this errors shows up:

9/8/2007 20:32:00 : Error : Access violation at address 00000000. Read of address 00000000
9/8/2007 20:32:01 : Error : Access violation at address 00000000. Read of address 00000000
9/8/2007 20:32:02 : Error : Access violation at address 72646461. Read of address 72646461
9/8/2007 20:32:02 : Error : Access violation at address 00000000. Read of address 00000000
9/8/2007 20:32:03 : Error : Access violation at address 0041C99C in module 'NUCLEO_SERVER.EXE'. Read of address 070041C9
9/8/2007 20:32:03 : Error : Access violation at address 0041C99C in module 'NUCLEO_SERVER.EXE'. Read of address 070041C9
0
 
rafaelrglAuthor Commented:
also i tryed like this, and then at some point the clients disconnected from the server, then i try hit the button again, then the same error shows up:

procedure TFPrinc.ToolButton23Click(Sender: TObject);
var
  i:integer;
begin
 with Clients.LockList do
  try
    for i := 0 to Count-1 do
    begin
      AClient := Items[i];
      if (AClient = nil) or (AClient.IOHandle = nil) then
      begin
        If Aclient = nil then
        begin
           showmessage('Aclient=nil')
        end;
        if Aclient.IOHandle = nil then
        begin
           showmessage('Aclient.iohandle=nil')
        end;
      end else begin
        Aclient.IOHandle.WriteLn('MSG');
      end;
    end;
  finally
    Clients.UnlockList;
  end;
0
 
diniludCommented:
Can you show your code?
0
 
diniludCommented:
Please check.    i didn't check this


procedure TForm1.Button1Click(Sender: TObject);
var
  i:integer;
begin
 with Clients.LockList do
  try
    for i := 0 to Count-1 do
    begin
      AClient := Items[i];
      if (AClient = nil) or (AClient.IOHandle = nil) then
      begin
        If Aclient = nil then
        begin
           try
             With IdCmdTCPServer1.Contexts.LockList do
             begin
               if IndexOf(AClient.AContext)>-1 then
               begin
                 Aclient.IOHandle.WriteLn('MSG');
               end
               else showmessage('Invalid Client')
              end;
           finally
             IdCmdTCPServer1.Contexts.UnlockList;
           end;
        end;
      end;
    end;
  finally
    Clients.UnlockList;
end;
0
 
diniludCommented:
procedure TForm1.Button1Click(Sender: TObject);
var
  i:integer;
begin
  try
    with IdCmdTCPServer1.Contexts.LockList do
    for i := 0 to Count-1 do
      TIdContext(Items[i]).Connection.IOHandler.WriteLn('MSG');
  finally
    IdCmdTCPServer1.Contexts.UnlockList;
  end;
end;
0
 
rafaelrglAuthor Commented:
Ok guys, to make more easy for us, i did a example that you can try on your comp, I can't give you my program code, i spend 2 hours build this sample to us make a solution on this, and maybe adding other question to send and receive files using commandhandle. so, you can download the code from here, for now lets make a solution building comunication back to client:

http://www.nucleodaweb.com/tidcmdtcp.rar

take a look, one thing, you will have to copy the dlls to the system folder, as far as i know, the ssl need it.

pls help me on this.
0
 
rafaelrglAuthor Commented:
waiting comment...
0
 
rafaelrglAuthor Commented:
what happening, you guys stop comments. i'm waiting.
0
 
diniludCommented:
i am trying.
0
 
rafaelrglAuthor Commented:
after this question i will make more 3 question with differents items, like send file to the client using commandhandle and other stuffs, ok. i will try here too, any thing new, pls tell me.
0
 
rafaelrglAuthor Commented:
I tryed to compile the code dinilud, it show a error:

Incompatible types: 'Integer' and 'Int64'


here is the line where the error is talking about:

        AContext.Connection.OnWorkBegin := (AContext.Data as TClientSpecificData).TCPClientInsideThreadWorkBegin;
        AContext.Connection.OnWork := (AContext.Data as TClientSpecificData).TCPClientInsideThreadWork;
        AContext.Connection.OnWorkEnd := (AContext.Data as TClientSpecificData).TCPClientInsideThreadWorkEnd;
0
 
rafaelrglAuthor Commented:
dinilud, take a look on my other question.... I opened other question to send message back to client, check it on my open questions.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.