From 81a4dcdf89dc5e95c2b5ecd96857581b14252362 Mon Sep 17 00:00:00 2001 From: Yann Andrey Date: Wed, 23 May 2018 09:59:47 -0400 Subject: [PATCH] Fixing a memory leak This part of the code makes a copy of the original reference without calling the destructor at any time for it (original reference). Instead of using a default constructor / copy constructor and then one destructor for each, such C++ copy elision optimization, it's better to simply remove copy. Simple example of the problem: public global::Lldb.SBSymbolContext GetSymbolContext(uint resolve_scope) { var __ret = new global::Lldb.SBSymbolContext.__Internal(); __Internal.GetSymbolContext((__Instance + __PointerAdjustment), new IntPtr(&__ret), resolve_scope); // here __ret is initialized like a constructor return global::Lldb.SBSymbolContext.__CreateInstance(__ret); } internal static global::Lldb.SBSymbolContext __CreateInstance(global::Lldb.SBSymbolContext.__Internal native, bool skipVTables = false) { return new global::Lldb.SBSymbolContext(native, skipVTables); } private SBSymbolContext(global::Lldb.SBSymbolContext.__Internal native, bool skipVTables = false) : this(__CopyValue(native), skipVTables) { __ownsNativeInstance = true; NativeToManagedMap[__Instance] = this; } private static void* __CopyValue(global::Lldb.SBSymbolContext.__Internal native) { var ret = Marshal.AllocHGlobal(sizeof(global::Lldb.SBSymbolContext.__Internal)); global::Lldb.SBSymbolContext.__Internal.cctor(ret, new global::System.IntPtr(&native)); return ret.ToPointer(); } After the fix: private static void* __CopyValue(global::Lldb.SBSymbolContext.__Internal native) { var ret = Marshal.AllocHGlobal(sizeof(global::Lldb.SBSymbolContext.__Internal)); *(global::Lldb.SBSymbolContext.__Internal*) ret = native; return ret.ToPointer(); } --- .../Generators/CSharp/CSharpSources.cs | 21 +++---------------- 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/src/Generator/Generators/CSharp/CSharpSources.cs b/src/Generator/Generators/CSharp/CSharpSources.cs index 739ed0a715..4b907cfa18 100644 --- a/src/Generator/Generators/CSharp/CSharpSources.cs +++ b/src/Generator/Generators/CSharp/CSharpSources.cs @@ -2179,24 +2179,9 @@ public void GenerateNativeConstructorByValue(Class @class, string returnType) PushBlock(BlockKind.Method); WriteLine($"private static void* __CopyValue({@internal} native)"); WriteStartBraceIndent(); - var copyCtorMethod = @class.Methods.FirstOrDefault(method => - method.IsCopyConstructor); - if (@class.HasNonTrivialCopyConstructor && copyCtorMethod != null && - copyCtorMethod.IsGenerated) - { - // Allocate memory for a new native object and call the ctor. - WriteLine($"var ret = Marshal.AllocHGlobal(sizeof({@internal}));"); - var printed = TypePrinter.PrintNative(@class); - WriteLine($"{printed}.{GetFunctionNativeIdentifier(copyCtorMethod)}(ret, new global::System.IntPtr(&native));", - printed, GetFunctionNativeIdentifier(copyCtorMethod)); - WriteLine("return ret.ToPointer();"); - } - else - { - WriteLine($"var ret = Marshal.AllocHGlobal(sizeof({@internal}));"); - WriteLine($"*({@internal}*) ret = native;"); - WriteLine("return ret.ToPointer();"); - } + WriteLine($"var ret = Marshal.AllocHGlobal(sizeof({@internal}));"); + WriteLine($"*({@internal}*) ret = native;"); + WriteLine("return ret.ToPointer();"); WriteCloseBraceIndent(); PopBlock(NewLineKind.BeforeNextBlock); }