?
Solved

Access violation at address 00000000. Read of address 00000000

Posted on 2007-08-08
18
Medium Priority
?
2,240 Views
Last Modified: 2013-11-05
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;
0
Comment
Question by:rafaelrgl
  • 9
  • 8
18 Comments
 
LVL 10

Expert Comment

by:dinilud
ID: 19659829
Access violation means you are try to aceess some invalid memory.

Means that some invalid pointer is there in Clients List.
0
 
LVL 19

Expert Comment

by:MerijnB
ID: 19660012
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
 
LVL 10

Expert Comment

by:dinilud
ID: 19660789
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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 1

Author Comment

by:rafaelrgl
ID: 19667002
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
 
LVL 1

Author Comment

by:rafaelrgl
ID: 19667031
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
 
LVL 10

Expert Comment

by:dinilud
ID: 19667962
Can you show your code?
0
 
LVL 10

Expert Comment

by:dinilud
ID: 19668394
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
 
LVL 10

Expert Comment

by:dinilud
ID: 19668406
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
 
LVL 1

Author Comment

by:rafaelrgl
ID: 19674440
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
 
LVL 1

Author Comment

by:rafaelrgl
ID: 19677138
waiting comment...
0
 
LVL 1

Author Comment

by:rafaelrgl
ID: 19687444
what happening, you guys stop comments. i'm waiting.
0
 
LVL 10

Expert Comment

by:dinilud
ID: 19689738
i am trying.
0
 
LVL 1

Author Comment

by:rafaelrgl
ID: 19695635
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
 
LVL 10

Accepted Solution

by:
dinilud earned 2000 total points
ID: 19708925
0
 
LVL 1

Author Comment

by:rafaelrgl
ID: 19730965
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
 
LVL 1

Author Comment

by:rafaelrgl
ID: 19733858
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

Featured Post

[Webinar] Cloud and Mobile-First Strategy

Maybe you’ve fully adopted the cloud since the beginning. Or maybe you started with on-prem resources but are pursuing a “cloud and mobile first” strategy. Getting to that end state has its challenges. Discover how to build out a 100% cloud and mobile IT strategy in this webinar.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
In a question here at Experts Exchange (https://www.experts-exchange.com/questions/29062564/Adobe-acrobat-reader-DC.html), a member asked how to create a signature in Adobe Acrobat Reader DC (the free Reader product, not the paid, full Acrobat produ…
As many of you are aware about Scanpst.exe utility which is owned by Microsoft itself to repair inaccessible or damaged PST files, but the question is do you really think Scanpst.exe is capable to repair all sorts of PST related corruption issues?
Suggested Courses

862 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question