New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fixed critical rtti cache bug #227
Conversation
TRttiInfo.ComputeCache method assumes Cache parameter will be zeroed out by caller but this is not true because of usage of out prefix which discards initial value. The method does not correctly initialize Cache structure therefor it contains whatever garbage is currently on the stack. The only time out parameter would "work" is if Cache would contain another managed type field which would force the compiler to initialize the structure on method entry. Fix is simple, use var prefix so that Cache is passed as reference. To be honest because of importance of this method in RTTI generation I would not leave it up to the caller to correctly initialize the Cache record.
Which compiler are you using? This method is only used internally, and only once from TRttiCustom.FromRtti() so it sounded safe to assume the cache record is filled with zeroes. I will merge your pull request (which does not hurt for sure), but please discuss here or in the forum which compiler do you use, and ensure that there is really a difference between "var" and "out" by looking at the asm using Alt-F2 in the IDE. |
Compiler is FPC 3.2.3 (fixes-3_2) and Lazarus 2.2.5 (fixes_2_2). Consider the following simple example
On my computer using that compiler the out param function fills record with garbage except for the field specifically set. I would expect it do this because I've specifically told the compiler that I don't care about what the initial value of record is. The documentation also confirms this
|
Assembly is also different for TestVar
where as TestOut
As you can see clearly not working from same pointer offset. |
With my FPC 3.2.3 the writeln() output is the very same with TestVar and TestOut, and the asm is exactly the same.
also when calling the functions:
I don't know where the asm you are showing comes from, but its does not make any sense anyway. |
I also tried to reproduce your initial Something seems wrong with your FPC tool chain... |
Well that's awkward ... |
It makes sense then. :) You may have asked directly on the forum, for better discussion. |
bug present in stable, trunk.
TRttiInfo.ComputeCache method assumes Cache parameter will be zeroed out by caller but this is not true because of usage of out prefix which discards initial value. The method does not correctly initialize Cache structure therefor it contains whatever garbage is currently on the stack. The only time out parameter would "work" is if Cache would contain another managed type field which would force the compiler to initialize the structure on method entry.
Fix by using var prefix so that Cache is passed as reference. To be honest because of importance of this method in RTTI generation I would not leave it up to the caller to correctly initialize the Cache record. I would still use out parameter but the first line should be
Default(Cache);
so that it zeroes out the structure.See following example
Because of Unique constraint on property "Name", Sqlite returns error if already exists in table.
This kicks off the following events