Opened 10 years ago

Closed 10 years ago

#3529 closed defect (fixed)

Crash on memory release in CSharp wrapper

Reported by: joker99 Owned by: tamas
Priority: normal Milestone: 1.7.2
Component: CSharpBindings Version: 1.7.1
Severity: major Keywords:
Cc:

Description

When using SpatialReference?.ExportToWkt? method from c# wrapper, there is either crash or stack overflow exception or AccessViolation? exception.

Use this code to reproduce:

   class Program
   {
       static void Main(string[] args)
       {
           Ogr.RegisterAll();
           using (var sourceDS = Ogr.Open(<path_to_feature_layer_with_srs>, 0))
           {
               var sourceLayer = sourceDS.GetLayerByIndex(0);
               using (var sourceSRS = sourceLayer.GetSpatialRef())
               {
                   if (sourceSRS != null)
                   {
                       string wkt = null;
                       Console.WriteLine("Getting projeciton wkt");
                       sourceSRS.ExportToWkt(out wkt);
                       Console.WriteLine("Projection wkt:" + wkt);
                   }
               }
           }
       }
   }

The bug happens because the memory returned from GDAL is freed using free function and not CPLFree in swig generated CSharp_SpatialReference_ExportToWkt function.

Change History (5)

comment:1 Changed 10 years ago by Even Rouault

Component: SWIG (all bindings)CSharpBindings
Owner: changed from hobu to tamas

Tamas,

I have confirmed the issue when running apps/WKT2WKB.cs with GDAL compiled with uncommented #define DEBUG_VSIMALLOC in port/cpl_vsisimple.cpp, which is a good way of checking consistant pairing of CPL/VSI memory allocation routines.

Index: ../include/csharp/typemaps_csharp.i
===================================================================
--- ../include/csharp/typemaps_csharp.i	(révision 19399)
+++ ../include/csharp/typemaps_csharp.i	(copie de travail)
@@ -259,7 +259,7 @@
   char* temp_string;
   temp_string = SWIG_csharp_string_callback(*$1);
   if (*$1)
-		free(*$1);
+    CPLFree(*$1);
   *$1 = temp_string;
 }

seems to do the trick, but I let you check & apply.

By the way, I'm wondering if there are not memory leaks in the csharp bindings with functions using 'out string'. I've tried the following and memory usage grows continuously :

while(true)
{
  string wkt;
  Osr.GetWellKnownGeogCSAsWKT("WGS84", out wkt);
}

or

while(true)
{
  string geom_wkt;
  geom.ExportToWkt(out geom_wkt);
}

But perhaps I'm doing something wrong or forgetting an explicit deallocation. I'm less that a newbee in csharp ;-)

comment:2 Changed 10 years ago by joker99

I tried

            using (var sourceDS = Ogr.Open(<shape_file>, 0))
            {
                var sourceLayer = sourceDS.GetLayerByIndex(0);
                using (var f = sourceLayer.GetFeature(0))
                {
                    using (var geom = f.GetGeometryRef())
                    {
                        int i = 0;
                        while (true)
                        {
                            string x;
                            geom.ExportToWkt(out x);
                            i++;
                            if (i % 10000 == 0)
                                Console.WriteLine(i);
                        }
                    }
                }
           }

and it had stable memory usage on my machine for about 1 million iterations.

comment:3 Changed 10 years ago by Even Rouault

ok, so this may be just a problem with my version of mono on Linux

comment:4 Changed 10 years ago by tamas

Milestone: 1.7.2

Committed the patch in r19466 and r19467

comment:5 Changed 10 years ago by Even Rouault

Resolution: fixed
Status: newclosed
Note: See TracTickets for help on using tickets.