Recent

Author Topic: Having trouble solving an Access violation exception  (Read 6401 times)

kveroneau

  • Full Member
  • ***
  • Posts: 119
Having trouble solving an Access violation exception
« on: August 24, 2016, 09:11:43 pm »
I am running into an Access violation exception when running my application and I am running out of ideas on how to resolve it.  This application when complete will be open sourced, so I have no problems sharing any of the source you see under the GPL license.

Basically, it is a Gopher client, yes, that very outdated Internet protocol.  However, it is a great way to learn and understand a new language.  If you read my introduction, you will notice that I come from Python, but have used Pascal in 2001ish.  I am trying to get back into Pascal, as I am seeing it as a powerful compiled language to have alongside my existing Python knowledge.  So, here is the code which I am having issue with at the moment:

Code: Pascal  [Select][+][-]
  1. {$mode objfpc}{$H+}
  2.  
  3.   TGopherMenu = record
  4.     gtype: char;
  5.     name: String;
  6.     selector: String;
  7.     host: String;
  8.     port: Integer;
  9.   end;
  10.  
  11.   AGopherMenu = Array of TGopherMenu;
  12.  
  13. .... SNIP ....
  14.  
  15. function TGopherClient.GetMenu(const selector: String): AGopherMenu;
  16. var
  17.   data: TMemoryStream;
  18.   entry: TStringList;
  19.   i: Integer;
  20. begin
  21.   SetLength(Result, 1);
  22.   data:=SendSelector(selector); { Returns back a TMemoryStream with data from remote gopher server. }
  23.   entry:=TStringList.Create;
  24.   Repeat
  25.     GetEntry(data, entry); { entry becomes a TStringList using the Delimiter feature on data, which is a single line. }
  26.     WriteLn('Got Entry back: ',entry.Count);
  27.     i:=Length(Result)+1;
  28.     SetLength(Result, i);
  29.     WriteLn('set length=',Length(Result));
  30.     Result[i].gtype:=entry.Strings[0][1];
  31.     WriteLn('Got gtype: ',Result[i].gtype);
  32.     WriteLn('entry.Strings[0]=',Length(entry.Strings[0]));
  33.     Result[i].name:=entry.Strings[0]; { On the 8th iteration this fails with an Access violation, see output below.. }
  34.     WriteLn('Past.');
  35.     Result[i].selector:=entry.Strings[1];
  36.     Result[i].host:=entry.Strings[2];
  37.     Result[i].port:=StrToInt(entry.Strings[3]);
  38.     WriteLn(entry.Strings[0]);
  39.     WriteLn(data.Position,',',data.Size);
  40.   until (data.Position>=data.Size);
  41.   WriteLn('Are we here?');
  42.   entry.Free;
  43. end;
  44.  

If you need additional code, or the entire program, I do plan on uploading this onto my BitBucket page soon, and can point you to that.  All those WriteLns were added in various efforts to troubleshoot this.  For some reason setting Result.name causes this exception.

Output follow:
Code: [Select]
Got Entry back: 4                                                           
set length=2                                                                 
Got gtype: i                                                                 
entry.Strings[0]=27                                                         
Past.                                                                       
iWelcome to my Gopherspace!                                                 
43,1739                                                                     
Got Entry back: 4                                                           
set length=3                                                                 
Got gtype: i                                                                 
entry.Strings[0]=60                                                         
Past.                                                                       
i***********************************************************                 
119,1739                                                                     
Got Entry back: 4                                                           
set length=4                                                                 
Got gtype: i                                                                 
entry.Strings[0]=60                                                         
Past.                                                                       
i**       CELEBRATING GOPHER'S 25 YEAR ANNIVERSARY!       **                 
195,1739                                                                     
Got Entry back: 4                                                           
set length=5                                                                 
Got gtype: i                                                                 
entry.Strings[0]=60                                                         
Past.                                                                       
i**               Plain text is beautiful!                **                 
271,1739                                                                     
Got Entry back: 4                                                           
set length=6                                                                 
Got gtype: i                                                                 
entry.Strings[0]=60                                                         
Past.                                                                       
i***********************************************************                 
347,1739                                                                     
Got Entry back: 4                                                           
set length=7                                                                 
Got gtype: i                                                                 
entry.Strings[0]=60                                                         
Past.                                                                       
i**  What's new? - Updated on Jan. 25, 2016               **                 
423,1739                                                                     
Got Entry back: 4                                                           
set length=8                                                                 
Got gtype: i                                                                 
entry.Strings[0]=60                                                         
Past.                                                                       
i**                                                       **                 
499,1739                                                                     
Got Entry back: 4                                                           
set length=9
Got gtype: i
entry.Strings[0]=60
Past.
TApplication.HandleException Access violation
  Stack trace:
  $00000000004C7C0A
  $00000000005020BA line 45 of main.pas
  $00000000004EB299 line 1023 of include/customform.inc
  $00000000004EA38A line 629 of include/customform.inc
  $00000000004D0941
  $00000000006C6841 line 5341 of include/wincontrol.inc
  $00000000004EC528 line 1443 of include/customform.inc
  $00000000006D450D line 1451 of include/control.inc
  $00000000006C3C0A line 4300 of include/wincontrol.inc
  $00000000006C3B30 line 4350 of include/wincontrol.inc
  $00000000004F0640 line 2682 of include/customform.inc
  $00000000006C2158 line 3556 of include/wincontrol.inc
  $00000000006E0EDA line 5460 of include/control.inc
  $00000000006DD228 line 4300 of include/control.inc
  $00000000004E9EF2 line 486 of include/customform.inc
  $00000000004EEF52 line 2196 of include/customform.inc
  $00000000004FB90D line 1387 of include/application.inc
Segmentation fault (core dumped)

Any ideas on why this would be happening?  Am I using an Array correctly here?  I recenrly heard a plea from the small/tiny gopher community that Firefox is removing a critical feature needed for OverbiteFF to continue functioning, meaning that Gopher will no longer be supported in Firefox even with an add-on, so this native Gopher client will really help that community out if I can get it working.  Many thanks.

Oh, the gopher server this is hitting, in case you want to check out the data is gopher://gopher.veroneau.net/

lainz

  • Hero Member
  • *****
  • Posts: 4470
    • https://lainz.github.io/
Re: Having trouble solving an Access violation exception
« Reply #1 on: August 24, 2016, 09:31:15 pm »
According to your log it 'Past.' the name assignment

Is not here the crash: Result[ i ].selector:=entry.Strings[1]; ?

balazsszekely

  • Guest
Re: Having trouble solving an Access violation exception
« Reply #2 on: August 24, 2016, 09:46:02 pm »
Add {$R+}{$Q+} after your program declaration. The first switch tells the computer to generate code to check the array indices, the second one checks for overflows. This way you will be able to locate the error.

JuhaManninen

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4474
  • I like bugs.
Re: Having trouble solving an Access violation exception
« Reply #3 on: August 24, 2016, 10:02:16 pm »
Yes, as GetMem wrote you should enable all the debug flags and checks while developing.
The error is actually very clear, you will quickly notice it.
I recommend you learn to use classes and objects, and maybe generics containers. They make your code cleaner and less prone to errors.
Mostly Lazarus trunk and FPC 3.2 on Manjaro Linux 64-bit.

kveroneau

  • Full Member
  • ***
  • Posts: 119
Re: Having trouble solving an Access violation exception
« Reply #4 on: August 24, 2016, 10:18:53 pm »
Thanks GetMem.  Adding {$R+}{$Q+} did shed some more light on what might be going on here.  Coming from a non-compiled world, I am used to doing my debugging using stdout/stderr to witness how the code runs and completely forget about the powerful debugging options compiled languages provide.

Anyways, so after adding this, the exact line of the error seems to be here:
Code: Pascal  [Select][+][-]
  1. Result[i].gtype:=entry.Strings[0][1];

Code: [Select]
Got Entry back: 4                                                           
set length=2                                                                 
TApplication.HandleException Range check error                               
  Stack trace:                                                               
  $0000000000502C53 line 121 of gopherclient.pas                             
  $00000000005020BA line 45 of main.pas                                     
  $00000000004EB299 line 1023 of include/customform.inc                     
  $00000000004EA38A line 629 of include/customform.inc                       
  $00000000004D0941                                                         
  $00000000006C6E11 line 5341 of include/wincontrol.inc                     
  $00000000004EC528 line 1443 of include/customform.inc                     
  $00000000006D4ADD line 1451 of include/control.inc                         
  $00000000006C41DA line 4300 of include/wincontrol.inc                     
  $00000000006C4100 line 4350 of include/wincontrol.inc                     
  $00000000004F0640 line 2682 of include/customform.inc                     
  $00000000006C2728 line 3556 of include/wincontrol.inc                     
  $00000000006E14AA line 5460 of include/control.inc                         
  $00000000006DD7F8 line 4300 of include/control.inc                         
  $00000000004E9EF2 line 486 of include/customform.inc
  $00000000004EEF52 line 2196 of include/customform.inc
  $00000000004FB90D line 1387 of include/application.inc

Oddly though, this time around the error occurs much earlier on, namely the first entry.  Am I allocating the space for this array incorrectly?

Code: Pascal  [Select][+][-]
  1.   TGopherMenu = record
  2.     gtype: char;
  3.     name: String;
  4.     selector: String;
  5.     host: String;
  6.     port: Integer;
  7.   end;
  8.  
  9.   AGopherMenu = Array of TGopherMenu;
  10.  
  11. .... SNIP ....
  12.  
  13. function TGopherClient.GetMenu(const selector: String): AGopherMenu;
  14.  
  15. .......
  16.  
  17. SetLength(Result, 1);
  18.  

This has gotten me further though, thank you.  I'll continue troubleshooting, and will check this thread again as well.

Josh

  • Hero Member
  • *****
  • Posts: 1274
Re: Having trouble solving an Access violation exception
« Reply #5 on: August 24, 2016, 10:27:54 pm »
Hi
Would it help if you defined the size of the Strings in the Record Structure to their maximum value?
Josh
The best way to get accurate information on the forum is to post something wrong and wait for corrections.

lainz

  • Hero Member
  • *****
  • Posts: 4470
    • https://lainz.github.io/
Re: Having trouble solving an Access violation exception
« Reply #6 on: August 24, 2016, 10:28:54 pm »
Indexes in pascal start with 0 and if I don't read it badly you're using it wrong just here:

SetLength(Result, 1); // this is ok, highest index will be 0

i:=Length(Result)+1; // 1 + 1 = 2
SetLength(Result, i); // 2

but then you're accesing index 2 that doesn't exists
Result[ i ].gtype:=entry.Strings[0][1];

kveroneau

  • Full Member
  • ***
  • Posts: 119
Re: Having trouble solving an Access violation exception
« Reply #7 on: August 24, 2016, 10:39:32 pm »
Thanks lainz, I ended up coming to the same conclusion after reading:  http://www.freepascal.org/docs-html/ref/refsu15.html#x39-520003.3.1

Updated code which seems to be working now:
Code: Pascal  [Select][+][-]
  1.     i:=Length(Result);
  2.     SetLength(Result, i+1);
  3.     Result[i].gtype:=entry.Strings[0][1];
  4.     ....
  5.  

Originally I didn't think it could be a range issue as I didn't have the checks enabled, so I was looking in all the wrong places.

Thanks again, we can consider this thread solved.

 

TinyPortal © 2005-2018