swig / swig

SWIG is a software development tool that connects programs written in C and C++ with a variety of high-level programming languages.
http://www.swig.org
Other
5.93k stars 1.26k forks source link

Potential memory leak in iterator generation #3076

Closed behrisch closed 4 months ago

behrisch commented 4 months ago

This is another one from static code analysis like #2865 but with Python this time.

The SWIG code looks like this (removed a few lines for clarity):

  template<typename OutIter>
  inline SwigPyIterator*
  make_output_iterator(const OutIter& current, PyObject *seq = 0)
  {
    return new SwigPyIteratorOpen_T<OutIter>(current, seq);
  }

...

SWIGINTERN PyObject *_wrap_StringVector_begin(PyObject *self, PyObject *args) {
  PyObject *resultobj = 0;
  std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ;
  void *argp1 = 0 ;
  int res1 = 0 ;
  PyObject *swig_obj[1] ;
  std::vector< std::string >::iterator result;

  swig_obj[0] = args;
  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_std__vectorT_std__string_t, 0 |  0 );
  if (!SWIG_IsOK(res1)) {
    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "StringVector_begin" "', argument " "1"" of type '" "std::vector< std::string > *""'");
  }
  arg1 = reinterpret_cast< std::vector< std::string > * >(argp1);
  result = (arg1)->begin();
  resultobj = SWIG_NewPointerObj(swig::make_output_iterator(static_cast< const std::vector< std::string >::iterator & >(result)),
    swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
  return resultobj;
}

I admit I don't understand everything about the encapsulated iterator but at least it looks like a pointer is being returned and to me it is not clear who is taking the responsibility of cleaning it up. I could also not find the DECREF the python C API uses to get rid of objects. So is this a legitimate memory leak?

The input to reproduce this is probably very simple:

%include "std_string.i"
%include "std_vector.i"
%template(StringVector) std::vector<std::string>;

The full report can be found here:

https://sonarcloud.io/project/issues?impactSoftwareQualities=RELIABILITY&issueStatuses=OPEN%2CCONFIRMED&id=org.eclipse.sumo&open=AZLBiQCj6jzsRIZ_s-l4

I am using swig 4.2.0 on ubuntu 24.04.

ojwb commented 4 months ago

SWIG_POINTER_OWN means the object created by make_output_iterator() should be cleaned up by Python's garbage collection.

Static analysis tools can to be a bit trigger happy about suggesting there are memory leaks - can you demonstrate there's actually a leak here (e.g. by wrapping an object of a class which counts calls to its constructor and destructor)?

behrisch commented 4 months ago

Thanks for your help, I decided to ignore those warnings