Lazarus

Free Pascal => General => Topic started by: passt on July 17, 2018, 09:29:45 am

Title: Project raises exception class "External SIGSEGV"
Post by: passt on July 17, 2018, 09:29:45 am
Lazarus 1.8.4 FPC 3.0.4 (x86_64-win32/win64)
Windows 7 Prof x64

I have a project which compiles successfully, but when I run it from IDE an error is shown:
Error: Project raised exception class "External SIGSEGV"
When I run it by its EXE file an access violation is shown.

The error is shown for a line in unit2 where a global variable of type TStringlist is used. The global variable is declared and created in another unit1. Both units refer to each other by "uses unit1/2".

Can anybody help?

Peter
Title: Re: Project raises exception class "External SIGSEGV"
Post by: munair on July 17, 2018, 09:36:09 am
You shouldn't cross reference units. Use unit 2 in unit 1 or unit 1 in unit 2, but not both. Also, it would be helpful if you provide the source. Otherwise there's no way anyone can help.
Title: Re: Project raises exception class "External SIGSEGV"
Post by: passt on July 17, 2018, 09:59:28 am
Well I need the cross reference of the units, at least for my bad and unexperienced programming style  :(
Here is my (shortened) code
Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2. {$mode objfpc}{$H+}
  3. interface  
  4. ...
  5. var
  6.   slFLartikel: TStringlist;
  7. implementation
  8. uses
  9.   Unit2;
  10. {$R *.lfm}
  11. { TForm1 }
  12.  
  13. procedure TForm1.myproc1();
  14. begin
  15.   slFLartikel := TStringlist.Create;
  16.   myproc2;
  17.   Form2.show;
  18.   slFLartikel.free;
  19. end;
  20.  
  21. procedure TForm1.myproc2();
  22. begin
  23.   while ... do slFLartikel.Add(someString);
  24. end;
  25.  
  26. ###
  27.  
  28. unit Unit2;
  29. {$mode objfpc}{$H+}
  30. interface  
  31. ...
  32. implementation
  33. uses
  34.   Unit1;
  35. {$R *.lfm}
  36. { TForm2 }
  37.  
  38. procedure TForm2.myproc3();
  39. begin
  40.   For i := 0 to slFLartikel.Count-1 do showmessage(slFLartikel[i]);
  41. end;
  42.  
Title: Re: Project raises exception class "External SIGSEGV"
Post by: munair on July 17, 2018, 10:59:01 am
You never have to cross reference units. If you need definitions in more than one unit, then create a general one for those definitions. In your case, unit3 could contain the definition
Code: Pascal  [Select][+][-]
  1. var
  2.       slFLartikel: TStringlist;
and both unit1 and unit2 can use unit3.
Title: Re: Project raises exception class "External SIGSEGV"
Post by: passt on July 17, 2018, 11:30:56 am
I changed the code as you proposed exactly. Added unit3 and removed the references for unit1/2 to each other.

Unfortunately the SIGSEGV error still happens. This error is shown even when I start the program.

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2. {$mode objfpc}{$H+}
  3. interface  
  4. ...
  5. var
  6.   slFLartikel: TStringlist;
  7. implementation
  8. uses
  9.   Unit3;
  10. {$R *.lfm}
  11. { TForm1 }
  12.  
  13. procedure TForm1.myproc1();
  14. begin
  15.   slFLartikel := TStringlist.Create;
  16.   myproc2;
  17.   //Form2.show;
  18.   slFLartikel.free;
  19. end;
  20.  
  21. procedure TForm1.myproc2
  22. begin
  23.   while ... do slFLartikel.Add(someString);
  24. end;
  25.  
  26. ###
  27. unit Unit2;
  28. {$mode objfpc}{$H+}
  29. interface  
  30. ...
  31. implementation
  32. uses
  33.   Unit3;
  34. {$R *.lfm}
  35. { TForm2 }
  36.  
  37. procedure TForm2.myproc3();
  38. begin
  39.   For i := 0 to slFLartikel.Count-1 do showmessage(slFLartikel[i]);
  40. end;
  41.  
  42. ###
  43. unit Unit3;
  44. {$mode objfpc}{$H+}
  45. interface
  46. uses
  47.   Classes, SysUtils;
  48. var
  49.   slFLartikel: TStringlist;
  50. implementation
  51.  
  52. end.

Btw is the reference to each other bad coding only or is forbidden definitely?
Title: Re: Project raises exception class "External SIGSEGV"
Post by: taazz on July 17, 2018, 11:38:59 am
the most probable cause is that the slFLartikel variable is not initialized when you try to access it. As far as I can see the variable is initialized only inside the Tform1.myproc1 and it is destroy on exiting the procedure with out setting it to nil. as a side note you did not move the variable to unit3 you only created a new variable with the same name on unit3 which might or might not be used instead of the one in unit1
Title: Re: Project raises exception class "External SIGSEGV"
Post by: passt on July 17, 2018, 11:53:57 am
I don't think this is right - for my case. The shortened code is nearly exact for this issue. But the error happens when I start the program and before any Form is shown. So there isn't any access to the variable slFLartikel.
Title: Re: Project raises exception class "External SIGSEGV"
Post by: taazz on July 17, 2018, 12:03:18 pm
I don't think this is right - for my case. The shortened code is nearly exact for this issue. But the error happens when I start the program and before any Form is shown. So there isn't any access to the variable slFLartikel.
which raises the question where is your application raising the exception? What is the debugger saying?
Title: Re: Project raises exception class "External SIGSEGV"
Post by: munair on July 17, 2018, 12:34:34 pm
The error can occur if your forms are created at startup and one of your form create procedures tries to access (populate) slFLartikel before it is instantiated. For example, in your project file (lpr) you should see something like this:
Code: Pascal  [Select][+][-]
  1. begin
  2.   RequireDerivedFormResource:=True;
  3.   Application.Initialize;
  4.   Application.CreateForm(TForm1, Form1);  // Form1.Create invoked
  5.   Application.CreateForm(TForm2, Form2);  // Form2.Create invoked
  6.   Application.Run;
  7. end.
But without full code this remains guess work.
Title: Re: Project raises exception class "External SIGSEGV"
Post by: passt on July 17, 2018, 01:23:38 pm
Yes this is my project file exactly.
slFLartikel is now declared as a global variable in Unit3. Unit3 isn't shown in the begin..end section of the project file, because it doesn't have a Form. However Unit3 is shown in the uses section of the project file where I changed the order to avoid this error, but it still remains.

Code: Pascal  [Select][+][-]
  1. program MyProgram;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   {$IFDEF UNIX}{$IFDEF UseCThreads}
  7.   cthreads,
  8.   {$ENDIF}{$ENDIF}
  9.   Interfaces, // this includes the LCL widgetset
  10.   Unit3, Forms, Unit1, Unit2
  11.   { you can add units after this };
  12.  
  13. {$R *.res}
  14.  
  15. begin
  16.   RequireDerivedFormResource:=True;
  17.   Application.Initialize;
  18.   Application.CreateForm(TForm1, Form1);
  19.   Application.CreateForm(TForm2, Form2);
  20.   Application.Run;
  21. end.
Title: Re: Project raises exception class "External SIGSEGV"
Post by: passt on July 17, 2018, 01:29:29 pm
which raises the question where is your application raising the exception? What is the debugger saying?
When I change the code so that the problematic line is shown in Unit1 and removed from Unit2, there is no error shown.
But when I set a breakpoint at the problematic line, the debugger shows "Error: Type TSTRINGLIST has no component named COUNT".
Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2. {$mode objfpc}{$H+}
  3. interface  
  4. ...
  5. var
  6.   slFLartikel: TStringlist;
  7. implementation
  8. uses
  9.   Unit3;
  10. {$R *.lfm}
  11. { TForm1 }
  12.  
  13. procedure TForm1.myproc1();
  14. begin
  15.   slFLartikel := TStringlist.Create;
  16.   myproc2;
  17.   //Form2.show;
  18.   For i := 0 to slFLartikel.Count-1 do showmessage(slFLartikel[i]);
  19.   slFLartikel.free;
  20. end;
  21.  
  22. procedure TForm1.myproc2
  23. begin
  24.   while ... do slFLartikel.Add(someString);
  25. end;
  26.  
  27. ###
  28. unit Unit2;
  29. {$mode objfpc}{$H+}
  30. interface  
  31. ...
  32. implementation
  33. uses
  34.   Unit3;
  35. {$R *.lfm}
  36. { TForm2 }
  37.  
  38. procedure TForm2.myproc3();
  39. begin
  40. //  For i := 0 to slFLartikel.Count-1 do showmessage(slFLartikel[i]);
  41. end;
  42.  
  43. ###
  44. unit Unit3;
  45. {$mode objfpc}{$H+}
  46. interface
  47. uses
  48.   Classes, SysUtils;
  49. var
  50.   slFLartikel: TStringlist;
  51. implementation
  52.  
  53. end.
Title: Re: Project raises exception class "External SIGSEGV"
Post by: taazz on July 17, 2018, 02:06:33 pm
which raises the question where is your application raising the exception? What is the debugger saying?
When I change the code so that the problematic line is shown in Unit1 and removed from Unit2, there is no error shown.
But when I set a breakpoint at the problematic line, the debugger shows "Error: Type TSTRINGLIST has no component named COUNT".
Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2. {$mode objfpc}{$H+}
  3. interface  
  4. ...
  5. var
  6.   slFLartikel: TStringlist;
  7. implementation
  8. uses
  9.   Unit3;
  10. {$R *.lfm}
  11. { TForm1 }
  12.  
  13. procedure TForm1.myproc1();
  14. begin
  15.   slFLartikel := TStringlist.Create;
  16.   myproc2;
  17.   //Form2.show;
  18.   For i := 0 to slFLartikel.Count-1 do showmessage(slFLartikel[i]);
  19.   slFLartikel.free;
  20. end;
  21.  
  22. procedure TForm1.myproc2
  23. begin
  24.   while ... do slFLartikel.Add(someString);
  25. end;
  26.  
  27. ###
  28. unit Unit2;
  29. {$mode objfpc}{$H+}
  30. interface  
  31. ...
  32. implementation
  33. uses
  34.   Unit3;
  35. {$R *.lfm}
  36. { TForm2 }
  37.  
  38. procedure TForm2.myproc3();
  39. begin
  40. //  For i := 0 to slFLartikel.Count-1 do showmessage(slFLartikel[i]);
  41. end;
  42.  
  43. ###
  44. unit Unit3;
  45. {$mode objfpc}{$H+}
  46. interface
  47. uses
  48.   Classes, SysUtils;
  49. var
  50.   slFLartikel: TStringlist;
  51. implementation
  52.  
  53. end.
So when you comment out the code in tform2.myproc3 everything seems to work as expected? Can you create the smallest compilable complete application possible, zip it and post it here?  As for the message  Type TSTRINGLIST has no component named COUNT is the inability of GDB to correctly recognize pascal properties, it has nothing to do with your code.


Title: Re: Project raises exception class "External SIGSEGV"
Post by: Thaddy on July 17, 2018, 02:09:39 pm
Small example
Code: Pascal  [Select][+][-]
  1. {$ifdef fpc}{$mode delphi}{$H+}{$endif}
  2. uses classes;
  3. var l:Tstrings;
  4. begin
  5.   L := TStringlist.create;
  6.   try
  7.     writeln(L.count);  
  8.   finally
  9.     L.free;
  10.   end;
  11. end.
Which means the bug is elsewhere, not in your stringlist code, but before that.
And indeed GDB has difficulties with properties. You should read the field instead: FCount.

Title: Re: Project raises exception class "External SIGSEGV"
Post by: munair on July 17, 2018, 02:43:38 pm
Btw is the reference to each other bad coding only or is forbidden definitely?
It is definitely bad coding imo. Some development software allows it and leave the responsibility to the programmer. Other software may be more strict and disallows cyclical referencing.
Title: Re: Project raises exception class "External SIGSEGV"
Post by: passt on July 17, 2018, 03:42:04 pm
@Munair
I try to do it better.
Title: Re: Project raises exception class "External SIGSEGV"
Post by: Thaddy on July 17, 2018, 05:17:25 pm
You shouldn't cross reference units. Use unit 2 in unit 1 or unit 1 in unit 2, but not both. Also, it would be helpful if you provide the source. Otherwise there's no way anyone can help.
Nonsense. The compiler catches that at compile time...
Your advice about introducing a third unit, however is somewhat correct, but not related to an external SIGSEV.
You should have explained that unit references can be resolved by adding one to the interface and the other to the implementation section. (Common knowledge, even basic knowledge).
In the case that it is unresolvable your suggestion is correct, but not for the original problem. So he is still stuck...
If he gives us compilable code, it can be resolved much quicker. (doesn't have to work, but a full project that demonstrates the issue.
Title: Re: Project raises exception class "External SIGSEGV"
Post by: passt on July 17, 2018, 05:25:01 pm
Quote
So when you comment out the code in tform2.myproc3 everything seems to work as expected? Can you create the smallest compilable complete application possible, zip it and post it here?  As for the message  Type TSTRINGLIST has no component named COUNT is the inability of GDB to correctly recognize pascal properties, it has nothing to do with your code.

When I reduce the program to an application for the console, everything works fine and no error is shown. Although it doesn't make any sense to work with three units in this case. Please see the attached project "Neuer Ordner test.zip".

When I use forms and buttons with the same shortened and reduced code, the error still happens. Please see the attached project "Neuer Ordner abas_CSV.7z".
Title: Re: Project raises exception class "External SIGSEGV"
Post by: howardpc on July 17, 2018, 06:20:59 pm
Your main project file needs to create Form2 as well as Form1:

Code: Pascal  [Select][+][-]
  1. begin
  2.   RequireDerivedFormResource:=True;
  3.   Application.Initialize;
  4.   Application.CreateForm(TForm1, Form1);
  5.   Application.CreateForm(TForm2, Form2);
  6.   Application.Run;
  7. end.
and you should delete the TForm2.OnCreate handler, and replace it with a TForm2.OnShow handler:
Code: Pascal  [Select][+][-]
  1. procedure TForm2.FormShow(Sender: TObject);
  2. var
  3.   i: Integer;
  4. begin
  5.   for i := 0 to slFLartikel.Count-1 do showmessage(slFLartikel[i]);
  6. end;
Title: Re: Project raises exception class "External SIGSEGV"
Post by: munair on July 17, 2018, 08:00:55 pm
You shouldn't cross reference units. Use unit 2 in unit 1 or unit 1 in unit 2, but not both. Also, it would be helpful if you provide the source. Otherwise there's no way anyone can help.
Nonsense. The compiler catches that at compile time...
Your advice about introducing a third unit, however is somewhat correct, but not related to an external SIGSEV.
You should have explained that unit references can be resolved by adding one to the interface and the other to the implementation section. (Common knowledge, even basic knowledge).
In the case that it is unresolvable your suggestion is correct, but not for the original problem. So he is still stuck...
If he gives us compilable code, it can be resolved much quicker. (doesn't have to work, but a full project that demonstrates the issue.
Nonsense, yet somewhat correct. Right! So what's it gonna be? Cross referencing units is bad coding and has no place in structured programming. Period. And nowhere in my comments did I suggest that it would resolve the problem. Just a step in the right direction. I stated multiple times that without compilable code, no help could be given. But thanks for the lecture. you're very good at it.  8-)
Title: Re: Project raises exception class "External SIGSEGV"
Post by: passt on July 18, 2018, 12:17:56 pm
Your main project file needs to create Form2 as well as Form1:
Ah, this was a mistake which I removed for testing purpose only. In the original code still it's in the project file.

and you should delete the TForm2.OnCreate handler, and replace it with a TForm2.OnShow handler:
This did the trick.
Can you explain why the OnCreate event doesn't work for this?

Thanks a lot  :D
Title: Re: Project raises exception class "External SIGSEGV"
Post by: munair on July 18, 2018, 04:55:58 pm
Can you explain why the OnCreate event doesn't work for this?
OnCreate is invoked when the form is created. If it's in the project file then this will be at program startup. If you try to access an object in that handler that has not (yet) been created you will receive the SIGSEGV. If you access the object in the OnShow handler and create the object before showing the form no error occurs because the object exists.
TinyPortal © 2005-2018