#1 2019-06-12 12:25:48

isa
Member
Registered: 2018-01-09
Posts: 22

Memory leak in mORMotWrappers

There is a memory leak caused When WrapperMethod is called, upon visiting the wrapper page to generate mORMotClient code.

The memory leak is specifically caused by the method function TWrapperContext.ContextFromMethods(int: TInterfaceFactory): variant;
Where "Result" can already be initialized by a previous call of this very method, resulting into calling init again on the same TDocVariantData, which results into AnsiString memory leaks.

I don't know with 100% certainty, if this is caused by our specific mustache files or other configurations, but I'm quite certain this is not caused by my code.

Now you could say, (As I initially thought), how come result is assigned before you even enter the method? Well it seems like the previous TDocVariantData result instance created by that function, seems to remain there, I suppose as "garbage".
Similar bihaviour can be seen in SynCommons.pas, in the function:
function _ObjFast(const NameValuePairs: array of const): variant;

There you can see that the first thing that is done is, is checking if result needs to be cleared prior to getting initialized again. So exact same concept I think, however in case of the method "ContextFromMethods" (Which is called in loops in quite some places), there is no such precaution available.
In ContextFromMethods, in order to initialize the resulting TDocVariantData, the method "TDocVariant.NewFast" is used, which on its turn calls InitFast, which doesn't do such a check such as in _ObjFast.

Calling VarClear(Result) before NewFast is called inside the method "ContextFromMethods", seems to solve the issue. But I don't know If it's dangerous to call it, meaning that I don't know with certainty, that initialized result data is somehow referenced somewhere else, and can be used.

So, it would be nice if someone else can look at this, confirm this, and possible also think for a (better) solution.

Kind Regards.

Offline

#2 2019-06-12 13:15:12

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,660
Website

Re: Memory leak in mORMotWrappers

TDocVariant.NewFast(out aValue: variant) is expected to make a VarClear() before call, required by the "out" kind of parameter.
It is visible when you use Alt-F2 in the Delphi IDE.

Which compiler do you use?

Offline

#3 2019-06-12 13:49:33

isa
Member
Registered: 2018-01-09
Posts: 22

Re: Memory leak in mORMotWrappers

Thank you for the fast reply,

I use Delphi XE 10.2

I don't know the Alt-F2 key, but trying Alt-F5 or Ctrl-F7 during debugging, I do see that the value is unassigned and becomes Null after the first call of ContextFromMethods.
After that, when entering ContextFromMethods the next time, I see result being assigned from the very beginning, and NewFast makes it Null again.

But I forgot to give you some extra details regarding the memory leak. The memory leak doesn't happen until you call AddItem inside the for loop.
So once again.
1st time calling ContextFromMethods, which is called by the loop of "CreateFromModel", no problems, memory leaks whatsoever.
2nd time calling ContextFromMethods, nothing goes wrong even after calling NewFast, but from there on in that for loop, every single AddItem causes a memory leak. I made sure if it wasn't the "ContextFromMethod" inside the AddItem call sent as parameter, which it wasn't because even when you call this following line in that for loop, it creates a memory leak:
TDocVariantData(result).AddItem('a');

And when I add VarClear(result); before calling TDocVariant.NewFast(result); The memory leak is gone.

Also of course all this code I mentioned is from mORMotWrappers.pas

Hope this helps.
If necessary I can provide you more info that you need.

Last edited by isa (2019-06-12 13:54:37)

Offline

#4 2019-06-18 08:42:42

isa
Member
Registered: 2018-01-09
Posts: 22

Re: Memory leak in mORMotWrappers

Hi, since I'm not getting reply, I just wanted to ask to make sure.
In order to solve this problem I added the following line:
varClear(result);

I added this in TWrapperContext.ContextFromMethods
Right before calling TDocVariant.NewFast(result);

Just wanted to ask if this is safe to do? The wrapper system still works as intended, but I suppose this will not break anything else right?
Just want to make sure.

Offline

Board footer

Powered by FluxBB