Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2000-07

RTL bug ?? TObject.FieldAddres

14 messages · 3 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Sebastian Günther
to Marc Weustink: + From: + Behalf + Of Sebastian G�nther + > + > While pinpointing the current crashes…
Marc Weustink wrote
Besides this, maybe an idea to prevent unnecesary lookups and check if name '' in TObject.FieldAddress

Would be possible, of course, but this case (name='') is extremely unlikely.

+ This seems to be a problem with virtual constructors again. Marcs + example gives the following values here: Maybe it is, while debugging I had troubles inspecting member vars.

Checking objects is simple: When you dump an object in GDB, you should get zero as result when you add the both values of the _vptr record. If this is not the case, then either the object is corrupt or the object pointer passed is wrong.

- Sebastian

Reply by email

Marc Weustink

Hi,
While pinpointing the current crashes in lazarus I found it related to the TObject.FieldAddres function.

Try the following code, the number of aaaa is important, one less, everything is ok, one more you get an illegal instruction. The number of chars needed for this also depends on what or how many units are used.

Marc

-------------------------------------------

program vartest;
{$mode objfpc}
uses
   Classes;
type
   TMyComponent = class(TComponent)
     aaaaaaaaaa: TComponent;
     b: TComponent;
   private
   public
     constructor Create(AOwner: TComponent); override;
   end;
constructor TMyComponent.Create(AOwner: TComponent);
begin
   inherited Create(AOwner);
   aaaaaaaaaa := TComponent.Create(Self);
end;
var
   MyComponent: TMyComponent;
begin
   MyComponent := TMyComponent.Create(nil);
end.

-------------------------------------------

marc:~/fpc/lazarus/test$ ppc386 vartest.pp
Target OS: Linux for i386
Compiling vartest.pp
vartest.pp(25,3) Note: Local variable MYCOMPONENT is assigned but never used Assembling (pipe) vartest.s
Linking vartest
28 Lines compiled, 0.2 sec
marc:~/fpc/lazarus/test$ vartest
An unhandled exception occurred at 0x0805D4AE :
Access violation
0x0805D4AE
0x0805DD7A
0x08079540
0x08075066
0x0000D7B2

marc:~/fpc/lazarus/test$

Reply by email

Sebastian Günther
to Marc Weustink
Marc Weustink wrote
Hi, While pinpointing the current crashes in lazarus I found it related to the TObject.FieldAddres function.

How did you came to this conclusion? TObject.FieldAddress is not used in your example program.

Perhaps Florian knows the answer, as he fixes another similar bug recently:
This seems to be a problem with virtual constructors again. Marcs example gives the following values here:
<:356>

  Constructor TComponent.Create(AOwner: TComponent);
  begin
    FComponentStyle:=[csInheritable];	// line 356
    If Assigned(AOwner) then AOwner.InsertComponent(Self);
  end;

At this point, I get invalid values already for the first object: self = {_vptr. = {$807ec51, $0}}
(gdbpas) info symbol 0x807ec51
VMT_VARTEST$_TMYCOMPONENT in section .data

Florian, I think you will recognise this problem...?

- Sebastian

Reply by email

Marc Weustink
to Marc Weustink: + From: + Behalf + Of Sebastian G�nther + > + > While pinpointing the current crashes…
Sebastian G|nther wrote 7 lines
Marc Weustink wrote: > Besides this, maybe an idea to prevent unnecesary lookups and check if name > '' in TObject.FieldAddress Would be possible, of course, but this case (name='') is extremely unlikely.

???
I've to dive some deeper in it. As far as I understand (and I may completely wrong) TObject.FieldAddress is called to set a reference to a member var of a parent component. THe member var is looked up through the name of the component. In most cases (now) name is '' so you dont have to look them up.

Show quoted text 9 lines
> + This seems to be a problem with virtual constructors again. Marcs > + example gives the following values here: > > Maybe it is, while debugging I had troubles inspecting member vars. Checking objects is simple: When you dump an object in GDB, you should get zero as result when you add the both values of the _vptr record. If this is not the case, then either the object is corrupt or the object pointer passed is wrong.

Has this a deeper meaning ?? (don't know the exact meaning of _vptr)

Marc

Reply by email

Marc Weustink
to Sebastian Günther: How did you came to this conclusion? TObject.FieldAddress is not used in your example…

+ From:
+ Behalf
+ Of Sebastian G�nther

+ Marc Weustink wrote:
+ >
+ > Hi,
+ > While pinpointing the current crashes in lazarus I found it
+ > related to the TObject.FieldAddres function.
+
+ How did you came to this conclusion? TObject.FieldAddress is
+ not used in your example program.

Ehh... this example is a simplified reconstruction of the Lazarus main.pp. TComponent.Create calls InsertComponent which calls SetReference which calls TObject.FieldAddress.

And somewhere between TComponent.Create and TObject.FieldAddress it got messed up.
While I saw it retrieve an Adress for an
empty name.
Besides this, maybe an idea to prevent unnecesary lookups and check if name '' in TObject.FieldAddress

+ Perhaps Florian knows the answer, as he fixes another similar bug
+ recently:
+ This seems to be a problem with virtual constructors again. Marcs
+ example gives the following values here:

Maybe it is, while debugging I had troubles inspecting member vars.

Marc

Reply by email

Sebastian Günther
to Marc Weustink
Marc Weustink wrote 6 lines
I've to dive some deeper in it. As far as I understand (and I may completely wrong) TObject.FieldAddress is called to set a reference to a member var of a parent component. THe member var is looked up through the name of the component. In most cases (now) name is '' so you dont have to look them up.

OK, I will commit a patch tomorrow.

Show quoted text 6 lines
>Checking objects is simple: When you dump an object in GDB, you should >get zero as result when you add the both values of the _vptr record. If >this is not the case, then either the object is corrupt or the object >pointer passed is wrong. Has this a deeper meaning ?? (don't know the exact meaning of _vptr)

Yes: _vptr is the VMT (virtual method table) pointer: Object variables are just pointer to a piece of memory; the first 4 bytes of this memory is the VMT pointer. The VMT itself is a list of pointers to the virtual methods of a specific class, but there are some additional fields. However, GDB displays two of these special fields, the first one is the size of a class instance in bytes, and the second one its the complement of this value, which is used only as a checksum. To check if a VMT is valid, just add these two values, and check if the result is zero (when you do a 32 bit addition of course; e.g. $80000000+$80000000 is zero in 32-bit arithmetic)

- Sebastian

Reply by email

Sebastian Günther
to Marc Weustink: + From: + Behalf + Of Sebastian G�nther + > + > While pinpointing the current crashes…
> Has this a deeper meaning ?? (don't know the exact meaning of _vptr)

I have to correct myself: Actually, the both values shown in GDB for _vptr are _not_ the size and its complement field. To get this fields, use the command "x/4 0x12345678" where 0x12345678 is the first of the two _vptr values.

BTW, the problem disappeared, but I don't know why?

- Sebastian

Reply by email

Sebastian Günther
to Marc Weustink: + From: + Behalf + Of Sebastian G�nther + > + > While pinpointing the current crashes…
Marc Weustink wrote
If it is the latter case.... it still exists, since your patch checks for empty names it isn't triggered by now. Maybe commentout check, try to fix and enable check again ?

Ok, sorry, you are right. There has been a bug in TObject.FieldAddress: I copied the code from the streaming support in FCL, but the FCL is compiled in a different mode than the RTL. This caused a "inc" command to fail.

This bug is fixed, and everything should work fine now.

- Sebastian

Reply by email

Marc Weustink
to Marc Weustink: + From: + Behalf + Of Sebastian G�nther + > + > While pinpointing the current crashes…
Sebastian G|nther wrote
I have to correct myself: Actually, the both values shown in GDB for _vptr are _not_ the size and its complement field. To get this fields, use the command "x/4 0x12345678" where 0x12345678 is the first of the two _vptr values.

OK

BTW, the problem disappeared, but I don't know why?

Eehh, what problem, the check you described or the problem I reported.

If it is the latter case.... it still exists, since your patch checks for empty names it isn't triggered by now. Maybe commentout check, try to fix and enable check again ?

Marc

Reply by email

Pavlovic Ivan
to Marc Weustink: + From: + Behalf + Of Sebastian G�nther + > + > While pinpointing the current crashes…
> If it is the latter case.... it still exists, since your patch checks

for

> empty names it isn't triggered by now. Maybe commentout check, try to

fix

Show quoted text 8 lines
> and enable check again ? Ok, sorry, you are right. There has been a bug in TObject.FieldAddress: I copied the code from the streaming support in FCL, but the FCL is compiled in a different mode than the RTL. This caused a "inc" command to fail. This bug is fixed, and everything should work fine now.

I've just downloaded the latest CVS but it still crashes... I'm sending the output when compiled with OPT=-dTRACE...

Pavlovic Ivan
---------------------------------
E-mail:
----------

Homepage:
----------
www.tisoft.cjb.net

-------------- next part --------------
A non-text attachment was scrubbed...
Name: bin00005.bin
Type: application/octet-stream
Size: 2455 bytes
Desc: "ERROR.LOG"
Url : http://localhost/pipermail/lazarus/attachments/20000708/5539523a/bin00005.bin

Reply by email

Sebastian Günther
to Marc Weustink: + From: + Behalf + Of Sebastian G�nther + > + > While pinpointing the current crashes…
Sebastian G�nther wrote 10 lines
Marc Weustink wrote: > > I've to dive some deeper in it. As far as I understand (and I may > completely wrong) TObject.FieldAddress is called to set a reference to a > member var of a parent component. THe member var is looked up through the > name of the component. In most cases (now) name is '' so you dont have to > look them up. OK, I will commit a patch tomorrow.

Done.

- Sebastian

Reply by email