[Lazarus] Improper initialization of manged types
Anthony Walter
sysrpl at gmail.com
Tue Jul 9 19:55:03 CEST 2013
Problem: Free Pascal is not properly initializing and finalizing an
interface type resulting in code being invoked for a garbage pointer. The
error is highlighted at the end.
Previously I filed a bug report on this issue and received feedback that
the bug could not be reproduced, but it's hitting me me big time when
building on 32-bit Linux (I been working on 64-bit Linux withe same same
compiler source without these problems). I'd like to post some code and get
feedback on how to fix this problem, if it is either something I am doing
or a problem with the compiler.
I have an interface type, what I would call a managed type since the
compiler ought to generate code to initialize and finalize its value, which
is used to share 1 or more contiguous floats:
IDependencyProperty = interface
['{E021AD95-9985-48AB-B29F-8D25A7BBE10E}']
function GetCount: Integer;
function GetValue(Index: Integer): Float;
procedure SetValue(Value: Float; Index: Integer);
property Count: Integer read GetCount;
end;
The interface is exposed by records TVec(n)Prop where n represents the
count or available floats. These properties are used to share float vectors
with animations/storyboards or other objects. Here is an the listing of
TVec1Prop:
TVec1Prop = record
private
function GetValue: TVec1;
procedure SetValue(Value: TVec1);
function GetVec(Index: Integer): TVec1Prop;
procedure SetVec(Index: Integer; const Value: TVec1Prop);
public
class operator Implicit(const Value: TVec1): TVec1Prop;
class operator Implicit(const Value: TVec1Prop): TVec1;
class operator Negative(const A: TVec1Prop): TVec1;
class operator Positive(const A: TVec1Prop): TVec1;
class operator Equal(const A, B: TVec1Prop) : Boolean;
class operator NotEqual(const A, B: TVec1Prop): Boolean;
class operator GreaterThan(const A, B: TVec1Prop): Boolean;
class operator GreaterThanOrEqual(const A, B: TVec1Prop): Boolean;
class operator LessThan(const A, B: TVec1Prop): Boolean;
class operator LessThanOrEqual(const A, B: TVec1Prop): Boolean;
class operator Add(const A, B: TVec1Prop): TVec1;
class operator Subtract(const A, B: TVec1Prop): TVec1;
class operator Multiply(const A, B: TVec1Prop): TVec1;
class operator Divide(const A, B: TVec1Prop): TVec1;
procedure Link(OnChange: TDependencyChangeNotify = nil); overload;
procedure Link(Prop: IDependencyProperty; Index: LongInt); overload;
procedure Unlink;
function Linked: Boolean;
function Equals(const A: TVec1Prop): Boolean;
function Same(const A: TVec1Prop): Boolean;
property X: TVec1Prop index 0 read GetVec write SetVec;
property Value: TVec1 read GetValue write SetValue;
property Vec[Index: Integer]: TVec1Prop read GetVec write SetVec;
private
FProp: IDependencyProperty;
case Boolean of
True: (FIndex: LongInt);
False: (FValue: TVec1);
end;
Part of the implementation looks like this with an example of the ERROR in
comments:
{ TVec1Prop }
class operator TVec1Prop.Implicit(const Value: TVec1Prop): TVec1;
begin
Result := Value.Value;
end;
class operator TVec1Prop.Implicit(const Value: TVec1): TVec1Prop;
begin
// ERROR: WriteLn(UIntPtr(Result.FProp)); writes out a random memory
location
// ERROR: Result.FProp should be nil already but it is not
Result.FProp := nil; // ERROR: Code is generated which attempts to call
release on random garbage
Result.FIndex := 0;
Result.FValue := Value;
end;
function TVec1Prop.GetValue: TVec1;
begin
if FProp = nil then
Result := FValue
else
Result := FProp.GetValue(FIndex);
end;
procedure TVec1Prop.SetValue(Value: TVec1);
begin
if FProp = nil then
FValue := Value
else
FProp.SetValue(Value, FIndex);
end;
The problem is happening in a lot of places which use my TVec(n)Prop types,
resulting in many AV errors, but again only when I am recompiling my demo
programs on 32-bit Linux (with the same compiler source). For example I
have a list of TVec1Prop, when I clear the list I am getting AV errors due
to some items not being finalized correctly.
What should I do?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20130709/04506e79/attachment-0002.html>
More information about the Lazarus
mailing list