[DUG] IsClass access violation

Ross Levis ross at stationplaylist.com
Fri Nov 15 13:28:24 NZDT 2013


No packages being used.  Still looking.

 

From: delphi-bounces at listserver.123.net.nz
[mailto:delphi-bounces at listserver.123.net.nz] On Behalf Of Jolyon Smith
Sent: Friday, 15 November 2013 8:37 a.m.
To: NZ Borland Developers Group - Delphi List
Subject: Re: [DUG] IsClass access violation

 


ime it is highly unlikely that bad memory or malware would result in a
consistent and reliable (albeit sporadic) error at the same place in your
code every time.

A corrupt DLL might be involved and if you are using runtime packages this
might include those (since the error occurs in IsClass, replacing the
appropriate rtl.bpl could be a first option - but only if you are using
runtime packages).  Also if you are using runtime packages, make sure that
the machine has all the right versions of your application packages.  A
mismatch in typeinfo in different versions of a reference runtime package
can lead to strange issues.

If you aren't using runtime packages (or even if you are) then as well as
checking for correctly paired Free/NIL'ing of references I strongly
recommend you also check for any hard type-casts to the TCustomDetails()
type, and sanity check them as well.





 <mailto:dugdavid at dbsolutions.co.nz> David Brennan

Thu, 14 Nov 2013 22:34

The most annoying type of bug - one which only occurs on one computer. There
is always the possibility that it is a problem with that particular machine,
bad memory or some a corrupt DLL/malware, etc. Most of the time when we have
run into something like this it turns out to be our code still, but the
thought that it might not be and you're going on a wild goose chase is
frustrating!

 

 

 

From: delphi-bounces at listserver.123.net.nz
[mailto:delphi-bounces at listserver.123.net.nz] On Behalf Of Ross Levis
Sent: Thursday, 14 November 2013 9:59 p.m.
To: 'NZ Borland Developers Group - Delphi List'
Subject: Re: [DUG] IsClass access violation

 

This code is working in about 1100 installations for over 12 months, and
executed around 1000 times a day at each installation, and the class
referencing is working correctly to determine if it is a TCategoryDetails
object or not.  Whether it should or shouldn't be done is another matter.  I
don't see any logical reason not to.

 

Only 1 user is having an occasional problem at the same line of code, twice
in the last 2 weeks.  I can't find a situation where the object has been
freed and my object storage not updated, but I suspect it must have been
somehow.  I'll have a closer look.

 

Cheers,

Ross.

 

From: delphi-bounces at listserver.123.net.nz
[mailto:delphi-bounces at listserver.123.net.nz] On Behalf Of Jolyon Smith
Sent: Thursday, 14 November 2013 4:39 p.m.
To: NZ Borland Developers Group - Delphi List
Subject: Re: [DUG] IsClass access violation

 


It is perfectly possible for self to be NIL (the "Free" method relies on
this fact).  If SetModified is not virtual then you can happily call it with
a NIL reference - it will only blow up when the code attempts to access any
member data. 

i.e. if self were NIL then the AV would occur on the FModified := Modify
line.

Since you are not getting an AV on that line then the one thing you can be
sure of is that self is not NIL.  :)


The read address in that access violation is very odd.  If the object were
previously valid but destroyed then I would expect a more "random" looking
address.  It also seems a curiously high address.

Another possibility is that the SetModified() method has been called using a
hard-typecast on some other value, not even necessarily a valid object
reference.  If so, then the procedure will be running in some sort of
no-mans land where setting the memory that it thinks is "fModified" is
acceptable but will do unpredictable damage with the wheels only coming off
when calling up the class hierarchy to check the class type.

e.g. in a form event:  TCustomDetails(self).SetModified(FALSE) will compile
and run but the line that sets fModified := Modify will actually overwrite
some private member data of the TForm (assuming that TCustomDetails is not a
form class) and if it doesn't blow up in your face right away something
almost certainly will go "bang" at some point later.

If that is what's going on, the fact that it is blowing up when attempting
to call the IsClass method suggests that whatever has been type cast isn't
even an object reference at all.

It's a puzzle, that's for sure.

Are there any other potential factors ?  Runtime packages ?  Threads ?


fwiw - an ancestor class referencing a sub-class is unusual and often
reflects a shortcoming in the OO model, but I wouldn't go so far as Todd as
saying that it should NEVER be done.  Without reviewing your class hierarchy
it's impossible to say for sure.  There may be good reasons for it and it is
unlikely to be directly related to your problem in any case (he said,
offering up a hostage to fortune!).  :) 



 <mailto:ross at stationplaylist.com> Ross Levis

Thu, 14 Nov 2013 15:51

I've got a strange error occurring for just one user where this procedure is
failing...

 

procedure TCustomDetails.SetModified(Modify: Boolean);

begin

  FModified := Modify;

  if Modify then

  begin

    if Self is TCategoryDetails then MainForm.CategoryChanged := True

    else MainForm.SpotChanged := True;

  end;

end;

 

TCategoryDetails and another class is inherited from TCustomDetails.

 

Access violation at address 004047DC in module 'SPLCreator.exe'. Read of
address FFFFFFDF.

main thread ($87c):

004047dc SPLCreator.exe System                TObject.InheritsFrom

00404742 SPLCreator.exe System                @IsClass

005dc6a6 SPLCreator.exe SPMain      3831   +4 TCustomDetails.SetModified

 

Would this happen if Self was nil or invalid?  I don't see how that could
happen but just wondering how this can happen.

 

Cheers,

Ross.

_______________________________________________
NZ Borland Developers Group - Delphi mailing list
Post: delphi at listserver.123.net.nz
Admin: http://delphi.org.nz/mailman/listinfo/delphi
Unsubscribe: send an email to delphi-request at listserver.123.net.nz with
Subject: unsubscribe

 

_______________________________________________
NZ Borland Developers Group - Delphi mailing list
Post: delphi at listserver.123.net.nz
Admin: http://delphi.org.nz/mailman/listinfo/delphi
Unsubscribe: send an email to delphi-request at listserver.123.net.nz with
Subject: unsubscribe



 <mailto:ross at stationplaylist.com> Ross Levis

Thu, 14 Nov 2013 21:59

This code is working in about 1100 installations for over 12 months, and
executed around 1000 times a day at each installation, and the class
referencing is working correctly to determine if it is a TCategoryDetails
object or not.  Whether it should or shouldn't be done is another matter.  I
don't see any logical reason not to.

 

Only 1 user is having an occasional problem at the same line of code, twice
in the last 2 weeks.  I can't find a situation where the object has been
freed and my object storage not updated, but I suspect it must have been
somehow.  I'll have a closer look.

 

Cheers,

Ross.

 

From: delphi-bounces at listserver.123.net.nz
[mailto:delphi-bounces at listserver.123.net.nz] On Behalf Of Jolyon Smith
Sent: Thursday, 14 November 2013 4:39 p.m.
To: NZ Borland Developers Group - Delphi List
Subject: Re: [DUG] IsClass access violation

 


It is perfectly possible for self to be NIL (the "Free" method relies on
this fact).  If SetModified is not virtual then you can happily call it with
a NIL reference - it will only blow up when the code attempts to access any
member data. 

i.e. if self were NIL then the AV would occur on the FModified := Modify
line.

Since you are not getting an AV on that line then the one thing you can be
sure of is that self is not NIL.  :)


The read address in that access violation is very odd.  If the object were
previously valid but destroyed then I would expect a more "random" looking
address.  It also seems a curiously high address.

Another possibility is that the SetModified() method has been called using a
hard-typecast on some other value, not even necessarily a valid object
reference.  If so, then the procedure will be running in some sort of
no-mans land where setting the memory that it thinks is "fModified" is
acceptable but will do unpredictable damage with the wheels only coming off
when calling up the class hierarchy to check the class type.

e.g. in a form event:  TCustomDetails(self).SetModified(FALSE) will compile
and run but the line that sets fModified := Modify will actually overwrite
some private member data of the TForm (assuming that TCustomDetails is not a
form class) and if it doesn't blow up in your face right away something
almost certainly will go "bang" at some point later.

If that is what's going on, the fact that it is blowing up when attempting
to call the IsClass method suggests that whatever has been type cast isn't
even an object reference at all.

It's a puzzle, that's for sure.

Are there any other potential factors ?  Runtime packages ?  Threads ?


fwiw - an ancestor class referencing a sub-class is unusual and often
reflects a shortcoming in the OO model, but I wouldn't go so far as Todd as
saying that it should NEVER be done.  Without reviewing your class hierarchy
it's impossible to say for sure.  There may be good reasons for it and it is
unlikely to be directly related to your problem in any case (he said,
offering up a hostage to fortune!).  :) 



 <mailto:ross at stationplaylist.com> Ross Levis

Thu, 14 Nov 2013 15:51

I've got a strange error occurring for just one user where this procedure is
failing...

 

procedure TCustomDetails.SetModified(Modify: Boolean);

begin

  FModified := Modify;

  if Modify then

  begin

    if Self is TCategoryDetails then MainForm.CategoryChanged := True

    else MainForm.SpotChanged := True;

  end;

end;

 

TCategoryDetails and another class is inherited from TCustomDetails.

 

Access violation at address 004047DC in module 'SPLCreator.exe'. Read of
address FFFFFFDF.

main thread ($87c):

004047dc SPLCreator.exe System                TObject.InheritsFrom

00404742 SPLCreator.exe System                @IsClass

005dc6a6 SPLCreator.exe SPMain      3831   +4 TCustomDetails.SetModified

 

Would this happen if Self was nil or invalid?  I don't see how that could
happen but just wondering how this can happen.

 

Cheers,

Ross.

_______________________________________________
NZ Borland Developers Group - Delphi mailing list
Post: delphi at listserver.123.net.nz
Admin: http://delphi.org.nz/mailman/listinfo/delphi
Unsubscribe: send an email to delphi-request at listserver.123.net.nz with
Subject: unsubscribe

 

_______________________________________________
NZ Borland Developers Group - Delphi mailing list
Post: delphi at listserver.123.net.nz
Admin: http://delphi.org.nz/mailman/listinfo/delphi
Unsubscribe: send an email to delphi-request at listserver.123.net.nz with
Subject: unsubscribe



 <mailto:jsmith at deltics.co.nz> Jolyon Smith

Thu, 14 Nov 2013 16:38


It is perfectly possible for self to be NIL (the "Free" method relies on
this fact).  If SetModified is not virtual then you can happily call it with
a NIL reference - it will only blow up when the code attempts to access any
member data. 

i.e. if self were NIL then the AV would occur on the FModified := Modify
line.

Since you are not getting an AV on that line then the one thing you can be
sure of is that self is not NIL.  :)


The read address in that access violation is very odd.  If the object were
previously valid but destroyed then I would expect a more "random" looking
address.  It also seems a curiously high address.

Another possibility is that the SetModified() method has been called using a
hard-typecast on some other value, not even necessarily a valid object
reference.  If so, then the procedure will be running in some sort of
no-mans land where setting the memory that it thinks is "fModified" is
acceptable but will do unpredictable damage with the wheels only coming off
when calling up the class hierarchy to check the class type.

e.g. in a form event:  TCustomDetails(self).SetModified(FALSE) will compile
and run but the line that sets fModified := Modify will actually overwrite
some private member data of the TForm (assuming that TCustomDetails is not a
form class) and if it doesn't blow up in your face right away something
almost certainly will go "bang" at some point later.

If that is what's going on, the fact that it is blowing up when attempting
to call the IsClass method suggests that whatever has been type cast isn't
even an object reference at all.

It's a puzzle, that's for sure.

Are there any other potential factors ?  Runtime packages ?  Threads ?


fwiw - an ancestor class referencing a sub-class is unusual and often
reflects a shortcoming in the OO model, but I wouldn't go so far as Todd as
saying that it should NEVER be done.  Without reviewing your class hierarchy
it's impossible to say for sure.  There may be good reasons for it and it is
unlikely to be directly related to your problem in any case (he said,
offering up a hostage to fortune!).  :) 



 <mailto:todd.martin.nz at gmail.com> Todd Martin

Thu, 14 Nov 2013 16:00

Firstly, since TCategoryDetails is a descendant of TCustomDetails, it should
NEVER be referenced in a method of TCustomDetails.
Secondly, I would say the TCustomDetails object has already been destroyed.

Todd.




_______________________________________________
NZ Borland Developers Group - Delphi mailing list
Post: delphi at listserver.123.net.nz
Admin: http://delphi.org.nz/mailman/listinfo/delphi
Unsubscribe: send an email to delphi-request at listserver.123.net.nz with
Subject: unsubscribe



 <mailto:ross at stationplaylist.com> Ross Levis

Thu, 14 Nov 2013 15:51

I've got a strange error occurring for just one user where this procedure is
failing...

 

procedure TCustomDetails.SetModified(Modify: Boolean);

begin

  FModified := Modify;

  if Modify then

  begin

    if Self is TCategoryDetails then MainForm.CategoryChanged := True

    else MainForm.SpotChanged := True;

  end;

end;

 

TCategoryDetails and another class is inherited from TCustomDetails.

 

Access violation at address 004047DC in module 'SPLCreator.exe'. Read of
address FFFFFFDF.

main thread ($87c):

004047dc SPLCreator.exe System                TObject.InheritsFrom

00404742 SPLCreator.exe System                @IsClass

005dc6a6 SPLCreator.exe SPMain      3831   +4 TCustomDetails.SetModified

 

Would this happen if Self was nil or invalid?  I don't see how that could
happen but just wondering how this can happen.

 

Cheers,

Ross.

_______________________________________________
NZ Borland Developers Group - Delphi mailing list
Post: delphi at listserver.123.net.nz
Admin: http://delphi.org.nz/mailman/listinfo/delphi
Unsubscribe: send an email to delphi-request at listserver.123.net.nz with
Subject: unsubscribe

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://listserver.123.net.nz/pipermail/delphi/attachments/20131115/56670925/attachment-0001.html 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: image/jpeg
Size: 770 bytes
Desc: not available
Url : http://listserver.123.net.nz/pipermail/delphi/attachments/20131115/56670925/attachment-0004.jpe 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: image/jpeg
Size: 886 bytes
Desc: not available
Url : http://listserver.123.net.nz/pipermail/delphi/attachments/20131115/56670925/attachment-0005.jpe 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: image/jpeg
Size: 1302 bytes
Desc: not available
Url : http://listserver.123.net.nz/pipermail/delphi/attachments/20131115/56670925/attachment-0006.jpe 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: image/jpeg
Size: 1236 bytes
Desc: not available
Url : http://listserver.123.net.nz/pipermail/delphi/attachments/20131115/56670925/attachment-0007.jpe 


More information about the Delphi mailing list