Recent

Author Topic: This Code get Error on Lazarus and Work on Delphi  (Read 5589 times)

XyberX

  • New Member
  • *
  • Posts: 43
This Code get Error on Lazarus and Work on Delphi
« on: March 24, 2017, 08:29:08 pm »
  Code down side have one error on Lazarus 1.6 who due close the app.
  But on Delphi Work normal.

Uses TypInfo;

Procedure TForm1.ListProps;
Var
 ListaPropriedades : TPropList;
 Contador          : Integer;
begin
 // Preenche uma lista com as propriedades do objeto
 GetPropList(TypeInfo(TForm), [tkMethod, tkProcedure], @ListaPropriedades);
 // Executa um loop nas propriedades do objeto
 Memo1.Clear;
 Try
  For Contador := 0 to Length(ListaPropriedades) -1 do
   Memo1.Lines.Add(ListaPropriedades[Contador]^.Name);
 Except
 End;
end;

Thaddy

  • Hero Member
  • *****
  • Posts: 14210
  • Probably until I exterminate Putin.
Re: This Code get Error on Lazarus and Work on Delphi
« Reply #1 on: March 24, 2017, 09:22:25 pm »
You should test for nil, also in Delphi, that also throws an access violation,,,(in 10.1)
Code: Pascal  [Select][+][-]
  1. procedure TForm1.ListProps;
  2. Var
  3.  ListaPropriedades : TPropList;
  4.  Contador          : Integer;
  5. begin
  6.  ListaPropriedades :=Default(TpropList);  //make sure all nil;
  7.  // Preenche uma lista com as propriedades do objeto
  8.  GetPropList(TypeInfo(TForm), [tkMethod, tkProcedure], @ListaPropriedades);
  9.  // Executa um loop nas propriedades do objeto
  10.  Memo1.Clear;
  11.  Try
  12.   For Contador := Low(ListaPropriedades) to High(ListaPropriedades) do
  13.    if ListaPropriedades[Contador]<> nil then  //test for nil
  14.       Memo1.Lines.Add(ListaPropriedades[Contador]^.Name);
  15.  Except
  16.    On E:Exception do
  17.     Showmessage(e.message);
  18.  End;
  19. end;

Your code simply crashes also in Delphi:

« Last Edit: March 24, 2017, 10:08:48 pm by Thaddy »
Specialize a type, not a var.

XyberX

  • New Member
  • *
  • Posts: 43
Re: This Code get Error on Lazarus and Work on Delphi
« Reply #2 on: March 24, 2017, 09:30:26 pm »
 Thanks.
 Delphi no need this because, he bring only methods <> NIL

XyberX

  • New Member
  • *
  • Posts: 43
Re: This Code get Error on Lazarus and Work on Delphi
« Reply #3 on: March 24, 2017, 09:32:42 pm »
 I test, problem still... :( :( :( :(

Thaddy

  • Hero Member
  • *****
  • Posts: 14210
  • Probably until I exterminate Putin.
Re: This Code get Error on Lazarus and Work on Delphi
« Reply #4 on: March 24, 2017, 09:55:49 pm »
I tested the same code in Laz 1.7 + FPC trunk and Delphi Berlin. Behavior is the same.
Your code crashes also in Delphi, same error...  My code doesn't, See the screenshot above from the delphi debugger.
« Last Edit: March 24, 2017, 10:06:54 pm by Thaddy »
Specialize a type, not a var.

Thaddy

  • Hero Member
  • *****
  • Posts: 14210
  • Probably until I exterminate Putin.
Re: This Code get Error on Lazarus and Work on Delphi
« Reply #5 on: March 24, 2017, 10:10:03 pm »
Thanks.
 Delphi no need this because, he bring only methods <> NIL

That is not true. Same behavior. Note that Delphi will eat the exception during debugging when using except {empty} end; but that will not always work at runtime and outside of the IDE. You should handle the exception. Then you can see that Delphi has the exact same one.
If you run your Lazarus project without debugging it will also eat the exception... btw,,, But your code is bad.
« Last Edit: March 24, 2017, 10:21:18 pm by Thaddy »
Specialize a type, not a var.

XyberX

  • New Member
  • *
  • Posts: 43
Re: This Code get Error on Lazarus and Work on Delphi
« Reply #6 on: March 24, 2017, 11:55:33 pm »
 What you say? If you need i put one vídeo. My code  is right and i use Berlin.
 If you need one prove i due  for you if you need im nos noob and Bring This problem for test because lazarus stable have the problem, you believe ir not  i put one vídeo if necessary

Deepaak

  • Sr. Member
  • ****
  • Posts: 454
Re: This Code get Error on Lazarus and Work on Delphi
« Reply #7 on: March 25, 2017, 04:26:16 am »
What you say? If you need i put one vídeo. My code  is right and i use Berlin.
 If you need one prove i due  for you if you need im nos noob and Bring This problem for test because lazarus stable have the problem, you believe ir not  i put one vídeo if necessary

Please proceed with video? As  your code generate error in delphi. Maybe you are missing something, ASFAIK Lazarus don't have problem.
Holiday season is online now. :-)

Thaddy

  • Hero Member
  • *****
  • Posts: 14210
  • Probably until I exterminate Putin.
Re: This Code get Error on Lazarus and Work on Delphi
« Reply #8 on: March 25, 2017, 06:19:53 am »
As anybody can test that the code crashes under the delphi debugger and in debug mode I would like to see that video.
Summary:
The code eats the access violations in release mode Both in Delphi and in Lazarus.
The code will show the access violations under debugger both in Delphi and in Lazarus.
The code uses a fixed array of pointers (16380 in Delphi, 65536 in Lazarus) that is not initialized.
The code uses Length() on a fixed array, which is the same as as one of the above numbers.
Contrary to a dynamic array Length() will not return the actual number of elements used.
Not in Lazarus and not in Delphi.
What happens is that the array likely has a lot of nil pointers left and the code tries to read records field on a nil polinter... BOOM!

What he should do and what I did for him
1.  Initialize the array so you can be sure they are all nil's in the first place.
1a.The pointers are on the stack and the stack is dirty. Do use Defaut()
2.  Check if you are reading a valid entry by checking for nil
3.  Don't eat the exceptions, but handle them. Or write in such a way you don't need them.
4.  Use proper settings for debug and release.

Now make the movie and show us how you solved it.

Maybe the best way to demonstrate this is to show you do not even need the exception if you write proper code. Works in Delphi and in Freepascal:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.ListProps;
  2. Var
  3.  ListaPropriedades : TPropList;
  4.  Contador          : Integer;
  5. begin
  6.   ListaPropriedades := Default(TPropList);  // initialize
  7.   GetPropList(TypeInfo(TForm), [tkMethod, tkProcedure], @ListaPropriedades);
  8.   Memo1.Clear;
  9.   For Contador := Low(ListaPropriedades) to High(ListaPropriedades) do
  10.     if ListaPropriedades[Contador] <> nil then
  11.       memo1.Lines.Add(String(ListaPropriedades[contador]^.name))  // cast removes warning
  12.     else
  13.       Break; // We're done when we meet nil
  14. end;
       
« Last Edit: March 25, 2017, 07:40:06 am by Thaddy »
Specialize a type, not a var.

ASerge

  • Hero Member
  • *****
  • Posts: 2223
Re: This Code get Error on Lazarus and Work on Delphi
« Reply #9 on: March 25, 2017, 07:39:08 am »
  Code down side have one error on Lazarus 1.6 who due close the app.
  But on Delphi Work normal.
I think in Delphi it is also a mistake, because you list an uninitialized data array.
Better:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.ListProps;
  2. var
  3.   PropList: TPropList;
  4.   Info: PTypeInfo;
  5.   MethPropCnt: Integer;
  6.   i: Integer;
  7. begin
  8.   Info := TypeInfo(TForm);
  9.   MethPropCnt := GetPropList(Info, [tkMethod, tkProcedure], @PropList);
  10.   for i := 0 to MethPropCnt - 1 do
  11.     Memo1.Lines.Append(PropList[i]^.Name);
  12. end;
But it will allocate a very large array on the stack, so even better
Code: Pascal  [Select][+][-]
  1. procedure TForm1.ListProps;
  2. var
  3.   PropList: PPropList; // Change to Pointer
  4.   Info: PTypeInfo;
  5.   AllPropCnt: Integer;
  6.   MethPropCnt: Integer;
  7.   i: Integer;
  8. begin
  9.   Info := TypeInfo(TForm);
  10.   AllPropCnt := GetTypeData(Info)^.PropCount;
  11.   if AllPropCnt > 0 then
  12.   begin
  13.     GetMem(PropList, SizeOf(PPropInfo) * AllPropCnt);
  14.     try
  15.       MethPropCnt := GetPropList(Info, [tkMethod, tkProcedure], PropList); // No @
  16.       for i := 0 to MethPropCnt - 1 do
  17.         Memo1.Lines.Append(PropList^[i]^.Name); // Add ^
  18.     finally
  19.       FreeMem(PropList);
  20.     end;
  21.   end;
  22. end;

Thaddy

  • Hero Member
  • *****
  • Posts: 14210
  • Probably until I exterminate Putin.
Re: This Code get Error on Lazarus and Work on Delphi
« Reply #10 on: March 25, 2017, 07:41:53 am »
@ASerge
That's why I introduced a default. But the use of propcount is a good one. (gets rid of my break)
Note his code simply raises an exception in both Delphi AND Lazarus.
« Last Edit: March 25, 2017, 07:53:17 am by Thaddy »
Specialize a type, not a var.

ASerge

  • Hero Member
  • *****
  • Posts: 2223
Re: This Code get Error on Lazarus and Work on Delphi
« Reply #11 on: March 25, 2017, 08:04:25 am »
@ASerge
That's why I introduced a default.
There is no need to Default, because the method GetPropList returns the number of initialized elements. Perhaps only for debugging purposes.

XyberX

  • New Member
  • *
  • Posts: 43
Re: This Code get Error on Lazarus and Work on Delphi
« Reply #12 on: March 25, 2017, 06:25:00 pm »
 Thanks, you code work on Lazarus 1.6.4 REV 54278.

 This is for my REST Dataware for Lazarus, I need know what Methods have on class for publish this.
 Thanks again.

 

TinyPortal © 2005-2018