mikak 2 Posted September 24, 2019 Hi, I'm testing classes that use RTTI and I get some strange leaks. My isolated test case is [ TestFixture ] tSomeTEst = class (TObject) private a: integer; b: string; c: double; published [ test] procedure sometest; end; /// ... and the test itself .. procedure tSomeTEst.sometest; var ctx: TRttiContext; ti: TRttiType; f: TRttiField; begin ctx := TRttiContext.Create; ti := ctx.GetType( typeinfo(Tsometest) ); for f in ti.GetFields do codesite.send(f.Name); ctx.free; end; When I run my test I get testkassaapi.tSomeTEst.sometest Message: 432 bytes were leaked in the test method Total allocation count: 26532 (1906454 B) Leak detected 06320CB0 size 76 B for class: TStringList Leak detected 06519080 size 18 B B0 04 02 00 01 00 00 00 02 00 00 00 0D 00 0A 00 00 00 | ?????????????????? Leak detected 065192F0 size 40 B 01 00 00 00 04 00 00 00 6C 95 51 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ????????l?Q?????????????? ??????? 00 00 00 00 00 00 00 00 | ???????? Leak detected 06519560 size 16 B for UnicodeString {RefCount: 1} = a Leak detected 064A57E0 size 28 B for class: TRttiInstanceFieldEx Leak detected 064A5A50 size 28 B for class: TRttiInstanceFieldEx Leak detected 064A5CC0 size 28 B for class: TRttiInstanceFieldEx Leak detected 064A5F30 size 32 B for UnicodeString {RefCount: 1} = 3676=3676 Leak detected 064A61A0 size 40 B 01 00 00 00 04 00 00 00 3C 5F 4A 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ????????<_J?????????????? ??????? 00 00 00 00 00 00 00 00 | ???????? Leak detected 06320F50 size 86 B for UnicodeString {RefCount: 2} = 2EC5265F-E40C-42B0-B71D-D8C0F8E30803 Leak detected 064A6680 size 40 B 01 00 00 00 04 00 00 0 If I just use standard ReportmemoryleakOnShutdown, it reports no leaks. what's going on here? I use Delphi 10.3.1. and latest leak-check from https://bitbucket.org/shadow_cs/delphi-leakcheck/src/master/ Share this post Link to post
Stefan Glienke 2002 Posted September 24, 2019 (edited) That is because internally all RTTI through an TRttiContext is handled by a singleton instance and DUnitX itself is already using some TRttiContext. So the internal singleton already exists and your usage causes it to just create more objects that are then owned by that singleton instance which outlives the unit test because DUnitX keeps it alive. This general issue of cached objects created during unit tests that keep existing after the test ran and thus are considered leaks is known and LeakCheck has mechanisms for that. Add the following line into the dpr (needs LeakCheck and LeakCheck.Utils in the uses) TLeakCheck.InstanceIgnoredProc := IgnoreRttiObjects; For more details please see the Ignoring section in the LeakCheck readme In practice there are many more places in RTL and possibly custom code that use lazy creation/caching mechanism and are subject to such a leak detection approach (see InitializeLeakCheck in Spring.TestRunner.pas for some example of such madness if you are curious) Edited September 24, 2019 by Stefan Glienke 1 1 Share this post Link to post
mikak 2 Posted September 25, 2019 Thanks for reply. I'm quite ashamed of how badly I concentrated to read readme ... there it was, Right before my eyes. But opening Spring.TestRunners.pas was quite eye opener! Thanks. Got rid of some unidac singleton and some LazyLoadAttributes.MakeClosure* leaks. thanks again... Share this post Link to post