Memory leaks in VC6 2 line Python 2.1b1 apps?

Craig Holman craig at patterncraft.com
Fri Mar 9 11:28:33 EST 2001


Greetings,

I'm afraid that both versions 2.0 and 2.1b1 leak memory for a single
Py_Initialize, Py_Finalize sequence in a
Visual C++ MFC application.

I created a simple VC 6 MFC application using the wizard as follows:

Dialog shared MFC-DLL application
Run-time library debug multithreaded DLL
Added a Test button to the dialog
The handler for the Test button calls Py_Initialize and then Py_Finalize.

I used this application to test for leaks in both Python 2.0 and Python
2.1b1.

Python 2.0 had 84 memory leaks that resulted in a leakage of a total of
15,936 bytes for a single pair of
Py_Initialize, Py_Finalize calls. The addition of a second Py_Intialize,
Py_Finalize pair resulted in an additional
leak of at least 2,300 bytes.  The memory leak dump listing in the Visual
Studio debug window was truncated after those additional 2,300 bytes,
so I'm not sure how large the additional leak was for the second call, nor
can I tell you how much is leaked for additional pairs.

Python 2.1b1 had 21 memory leaks that resulted in a leakage of a total of
6,899 bytes for a single pair of
Py_Initialize, Py_Finalize calls.  Additional Py_Intitialize, Py_Finalize
pairs did not result in any
additional leakage (10,000 pairs were tested).

Based upon these experiments, I'd suggest using 2.1b1.

Python development is apparently aware of some of these leaks.
I found the following comment in pythonrun.c, lines 254-258 near the end of
the Py_Finalize procedure:

 /* XXX Still allocated:
    - various static ad-hoc pointers to interned strings
    - int and float free list blocks
    - whatever various modules and libraries allocate
 */

I am going to continue testing Python 2.1b1 for leaks when its driven from a
VC++ 6 MFC application.

I'm hoping that some of these leaks can be addressed before the 2.1 release
is issued.

The remainder of this note is an annotated listing of memory leaks that were
produced when running the
application with Python 2.1b1.  It is incomplete, but Owen's note prompted
me to post it early.
The addresses in the "normal block at" lines may not match up with the
addresses in the runtime stack
captures that I provide - I captured this information over several runs of
the program.

Craig
____________________________________________________________________________
_
Python 2.1b1 memory leaks as reported by a debug Visual C++ 6 MFC
application

Dumping objects ->

{1037} normal block at 0x0079CE80, 39 bytes long.
 Data: <  y             > 20 EE 79 00 88 85 1F 1E 03 00 00 00 B8 17 20 1E

 Cause :  interned string not being released

    Breakpoint:

  classobject.c, line 544 :  delstr = PyString_InternFromString("__del__");

 Runtime stack:

  instance_dealloc(PyInstanceObject * 0x00947e04) line 544
  _Py_Dealloc(_object * 0x00947e04) line 1367 + 7 bytes
  fini_exceptions() line 1139 + 70 bytes
  Py_Finalize() line 242


{1020} normal block at 0x0094B960, 6144 bytes long.
 Data: <   w Hy         > FF BD 07 77 B8 48 79 00 00 00 00 00 00 00 00 00

 Cause :

  /* Delete some special variables first.  These are common
     places where user values hide and people complain when their
     destructors fail.  Since the modules containing them are
     deleted *last* of all, they would come too late in the normal
     destruction order.  Sigh. */  (source: PyImport_Cleanup()  (I believe))

 Breakpoint:

     dictobject.c, line 404 :  newtable = PyMem_NEW(dictentry, newsize);

 Runtime stack:

  malloc(unsigned int 6144) line 130
  dictresize(dictobject * 0x00794bc4, int 342) line 404 + 13 bytes
  PyDict_SetItem(_object * 0x00794bc4, _object * 0x0079d4a0, _object *
0x0079d4a0) line 491 + 18 bytes
  PyString_InternInPlace(_object * * 0x0012f6cc) line 3171 + 20 bytes
  PyDict_SetItemString(_object * 0x00798ca4, char * 0x1e1f24e0, _object *
0x1e1f84f0 __Py_NoneStruct) line 1271 + 9 bytes
  PyImport_Cleanup() line 253 + 20 bytes
  Py_Finalize() line 213

{436} normal block at 0x0079EE20, 40 bytes long.
 Data: <  y   y         > B0 EA 79 00 80 CE 79 00 03 00 00 00 B8 17 20 1E

 Cause :  interned string not being released

    Breakpoint:

        classobject.c, line 474 :  initstr =
PyString_InternFromString("__init__");

 Runtime stack:

  PyInstance_New(_object * 0x00946a3c, _object * 0x0079cfa4, _object *
0x00000000) line 474
  call_object(_object * 0x00946a3c, _object * 0x0079cfa4, _object *
0x00000000) line 2705 + 17 bytes
  PyEval_CallObjectWithKeywords(_object * 0x00946a3c, _object * 0x0079cfa4,
_object * 0x00000000) line 2673 + 17 bytes
  init_exceptions() line 1123 + 24 bytes
  Py_Initialize() line 148

{427} normal block at 0x0079EAB0, 43 bytes long.
 Data: <H y   y         > 48 EA 79 00 20 EE 79 00 03 00 00 00 B8 17 20 1E

 Cause :  interned string not being released

    Breakpoint:

        classobject.c, line 97 :  delattrstr =
PyString_InternFromString("__delattr__");

 Runtime stack:

  PyClass_New(_object * 0x0079cfa4, _object * 0x0079dc3c, _object *
0x0079e7f8) line 97
  make_Exception(char * 0x1e1e9cfc) line 345 + 15 bytes
  init_exceptions() line 1073 + 9 bytes
  Py_Initialize() line 148

{426} normal block at 0x0079EA48, 43 bytes long.
 Data: <  y   y         > E0 E9 79 00 B0 EA 79 00 03 00 00 00 B8 17 20 1E

 Cause :  interned string not being released

    Breakpoint:

        classobject.c, line 96 :  setattrstr =
PyString_InternFromString("__setattr__");

 Runtime stack:

  PyClass_New(_object * 0x0079cfa4, _object * 0x0079dc3c, _object *
0x0079e7f8) line 96
  make_Exception(char * 0x1e1e9cfc) line 345 + 15 bytes
  init_exceptions() line 1073 + 9 bytes
  Py_Initialize() line 148

{425} normal block at 0x0079E9E0, 43 bytes long.
 Data: <  y H y         > B0 DD 79 00 48 EA 79 00 03 00 00 00 B8 17 20 1E

 Cause :  interned string not being released

    Breakpoint:

        classobject.c, line 95 :  getattrstr =
PyString_InternFromString("__getattr__");

 Runtime stack:

  PyClass_New(_object * 0x0079cfa4, _object * 0x0079dc3c, _object *
0x0079e7f8) line 95
  make_Exception(char * 0x1e1e9cfc) line 345 + 15 bytes
  init_exceptions() line 1073 + 9 bytes
  Py_Initialize() line 148

{416} normal block at 0x0079DDB0, 42 bytes long.
 Data: <  y   y         > A0 DE 79 00 E0 E9 79 00 03 00 00 00 B8 17 20 1E

 Cause :  interned string not being released

    Breakpoint:

        classobject.c, line 29 :  modstr=
PyString_InternFromString("__module__");

 Runtime stack:

  PyClass_New(_object * 0x00000000, _object * 0x0079dc3c, _object *
0x0079e7f8) line 29
  make_Exception(char * 0x1e1e9cfc) line 345 + 15 bytes
  init_exceptions() line 1073 + 9 bytes
  Py_Initialize() line 148

{406} normal block at 0x0079DEA0, 40 bytes long.
 Data: <  y   y         > D0 DC 79 00 B0 DD 79 00 03 00 00 00 B8 17 20 1E

 Cause :  interned string not being released

    Breakpoint:

        import.c, line 1584 :  pathstr =
PyString_InternFromString("__path__");

 Runtime stack:

  get_parent(_object * 0x0079dc3c, char * 0x0012f494, int * 0x0012f490) line
1584
  import_module_ex(char * 0x0079daac, _object * 0x0079dc3c, _object *
0x0079dc3c, _object * 0x0079db6c) line 1518 + 23 bytes
  PyImport_ImportModuleEx(char * 0x0079daac, _object * 0x0079dc3c, _object *
0x0079dc3c, _object * 0x0079db6c) line 1563 + 21 bytes
  builtin___import__(_object * 0x00000000, _object * 0x0079dd2c) line 31 +
21 bytes
  call_cfunction(_object * 0x00794e68, _object * 0x0079dd2c, _object *
0x00000000) line 2740 + 11 bytes
  call_object(_object * 0x00794e68, _object * 0x0079dd2c, _object *
0x00000000) line 2703 + 17 bytes
  PyEval_CallObjectWithKeywords(_object * 0x00794e68, _object * 0x0079dd2c,
_object * 0x00000000) line 2673 + 17 bytes
  PyObject_CallObject(_object * 0x00794e68, _object * 0x0079dd2c) line 1529
+ 15 bytes
  PyObject_CallFunction(_object * 0x00794e68, char * 0x1e1f2dfc) line 1570 +
13 bytes
  PyImport_Import(_object * 0x0079da90) line 1954 + 33 bytes
  PyImport_ImportModule(char * 0x1e1e9d08) line 1494 + 9 bytes
  init_exceptions() line 1060 + 10 bytes
  Py_Initialize() line 148

{399} normal block at 0x00795558, 12 bytes long.
 Data: <        \   > FF FF FF FF 00 00 00 00 5C 00 00 00

 Cause :  allocated lock is not released

 Breakpoint:

        thread_nt.h, line 240 :  aLock = AllocNonRecursiveMutex() ;

 Runtime stack:

  PyThread_allocate_lock() line 240
  lock_import() line 154 + 5 bytes
  PyImport_ImportModuleEx(char * 0x1e1f2de8, _object * 0x00000000, _object *
0x00000000, _object * 0x00000000) line 1563
  PyImport_Import(_object * 0x0079da90) line 1936 + 16 bytes
  PyImport_ImportModule(char * 0x1e1e9d08) line 1494 + 9 bytes
  init_exceptions() line 1060 + 10 bytes
  Py_Initialize() line 148

{398} normal block at 0x0079DCD0, 39 bytes long.
 Data: <t y   y         > 74 DC 79 00 A0 DE 79 00 01 00 00 00 B8 17 20 1E

 Runtime stack:



{397} normal block at 0x007953E8, 4 bytes long.
 Data: <  y > D0 DC 79 00

 Runtime stack:



{396} normal block at 0x0079DC68, 36 bytes long.
 Data: <    P y       y > F0 BC 1E 1E 50 CF 79 00 CD CD CD CD 00 DC 79 00

 Runtime stack:



{395} normal block at 0x0079DC00, 44 bytes long.
 Data: <\ y t y         > 5C CF 79 00 74 DC 79 00 03 00 00 00 B8 17 20 1E

 Cause :  interned string not being released

    Breakpoint:

        import.c, line 1915 :  builtins_str =
PyString_InternFromString("__builtins__");

 Runtime stack:

  PyImport_Import(_object * 0x0079da90) line 1915
  PyImport_ImportModule(char * 0x1e1e9d08) line 1494 + 9 bytes
  init_exceptions() line 1060 + 10 bytes
  Py_Initialize() line 148

{365} normal block at 0x0079CF50, 36 bytes long.
 Data: <h y  Ly      Oy > 68 DC 79 00 D8 4C 79 00 CD CD CD CD E0 4F 79 00



{280} normal block at 0x00797590, 66 bytes long.
 Data: <.\DLLs;.\lib;.\l> 2E 5C 44 4C 4C 73 3B 2E 5C 6C 69 62 3B 2E 5C 6C



{85} normal block at 0x00794FE0, 42 bytes long.
 Data: <@Ny \ y         > 40 4E 79 00 5C CF 79 00 03 00 00 00 B8 17 20 1E

 Cause :  interned string not being released

    Breakpoint:

        import.c, line 1912 :  import_str =
PyString_InternFromString("__import__");

 Runtime stack:

  PyImport_Import(_object * 0x0079da90) line 1912
  PyImport_ImportModule(char * 0x1e1e9d08) line 1494 + 9 bytes
  init_exceptions() line 1060 + 10 bytes
  Py_Initialize() line 148

{81} normal block at 0x00794E40, 39 bytes long.
 Data: < Ly  Oy         > E4 4C 79 00 E0 4F 79 00 03 00 00 00 B8 17 20 1E

 Cause :  interned string not being released

    Breakpoint:

        classobject.c, line 24 :  docstr=
PyString_InternFromString("__doc__");

 Runtime stack:

  PyClass_New(_object * 0x00000000, _object * 0x0079dc3c, _object *
0x0079e7f8) line 24
  make_Exception(char * 0x1e1e9cfc) line 345 + 15 bytes
  init_exceptions() line 1073 + 9 bytes
  Py_Initialize() line 148

{78} normal block at 0x00794CD8, 52 bytes long.
 Data: <P y         pLy > 50 CF 79 00 F0 BC 1E 1E CD CD CD CD 70 4C 79 00



{77} normal block at 0x00794C70, 40 bytes long.
 Data: < Hy  Ly         > B8 48 79 00 E4 4C 79 00 04 00 00 00 B8 17 20 1E

 Cause :  interned string not being released

 Breakpoint:

        import.c, line 1579 :  namestr =
PyString_InternFromString("__name__");

 Runtime stack:

  get_parent(_object * 0x0079dc3c, char * 0x0012f494, int * 0x0012f490) line
1579
  import_module_ex(char * 0x0079daac, _object * 0x0079dc3c, _object *
0x0079dc3c, _object * 0x0079db6c) line 1518 + 23 bytes
  PyImport_ImportModuleEx(char * 0x0079daac, _object * 0x0079dc3c, _object *
0x0079dc3c, _object * 0x0079db6c) line 1563 + 21 bytes
  builtin___import__(_object * 0x00000000, _object * 0x0079dd2c) line 31 +
21 bytes
  call_cfunction(_object * 0x00794e68, _object * 0x0079dd2c, _object *
0x00000000) line 2740 + 11 bytes
  call_object(_object * 0x00794e68, _object * 0x0079dd2c, _object *
0x00000000) line 2703 + 17 bytes
  PyEval_CallObjectWithKeywords(_object * 0x00794e68, _object * 0x0079dd2c,
_object * 0x00000000) line 2673 + 17 bytes
  PyObject_CallObject(_object * 0x00794e68, _object * 0x0079dd2c) line 1529
+ 15 bytes
  PyObject_CallFunction(_object * 0x00794e68, char * 0x1e1f2dfc) line 1570 +
13 bytes
  PyImport_Import(_object * 0x0079da90) line 1954 + 33 bytes
  PyImport_ImportModule(char * 0x1e1e9d08) line 1494 + 9 bytes
  init_exceptions() line 1060 + 10 bytes
  Py_Initialize() line 148

{67} normal block at 0x007948B8, 43 bytes long.
 Data: <    pLy         > 88 85 1F 1E 70 4C 79 00 B4 00 00 00 B8 17 20 1E

 Cause :  string is not being released

    Breakpoint:

        dictobject.c, line 130 :  dummy = PyString_FromString("<dummy
key>");

 PyDict_New() line 130
 Py_Initialize() line 116 + 5 bytes

{65} normal block at 0x007947F8, 12 bytes long.
 Data: <        X   > FF FF FF FF 00 00 00 00 58 00 00 00

 Cause :  allocated lock is not released

 Breakpoint:

        thread_nt.h, line 240 :  aLock = AllocNonRecursiveMutex() ;

 PyThread_allocate_lock() line 240
 PyInterpreterState_New() line 36 + 14 bytes
 Py_Initialize() line 107 + 5 bytes

Object dump complete.

"Tom" <NoSpam at NoSpam.com> wrote in message
news:hGPp6.53719$UZ4.13963947 at news4.rdc1.on.home.com...
> "Owen F. Ransen" <ransen_spam_me_not at nemo.it> wrote in message
> news:3aa88f52.5419185 at news.newsguy.com...
> > Python 2.1b1
> >
> > I tried to create a simple VC MFC app using the
> > wizard as follows:
> >
> > 1) Multidoc shared MFC-DLL application.
> > 2) Run time library debug multithreaded DLL
> > 3) Added #include <python.h> to the main file
> > 4) Added
> >         Py_Initialize()
> >         Py_Finalize()
> >    at the end of the InitInstance()
> > 5) When I run I get memory leaks visible at
> >    exit.
> >
> > Any clues anyone?
>
> For comparison sake.
> I use VC6 and Python 2.0.  I create an EXE that calls the same same
> functions that you mention, and Python itself doesn't leak (I get various
> wierd leaks from other sources, but not Python so far as I can tell).
>
> Tom.
>
> >
> > (I can't yet report this via Source Forge because my account
> >  problems have not be sorted out yet.)
> >
> >
> > --
> > Owen F. Ransen
> > http://www.ransen.com/
> > Home of Gliftic & Repligator Image Generators
>
>





More information about the Python-list mailing list