@@ -17,9 +17,9 @@ typedef struct {
1717 PyObject * kwargs ;
1818} atexit_callback ;
1919
20- atexit_callback * * atexit_callbacks ;
21- int ncallbacks = 0 ;
22- int callback_len = 32 ;
20+ static atexit_callback * * atexit_callbacks ;
21+ static int ncallbacks = 0 ;
22+ static int callback_len = 32 ;
2323
2424/* Installed into pythonrun.c's atexit mechanism */
2525
@@ -33,7 +33,7 @@ atexit_callfuncs(void)
3333 if (ncallbacks == 0 )
3434 return ;
3535
36- for (i = ncallbacks - 1 ; i >= 0 ; i -- )
36+ for (i = ncallbacks - 1 ; i >= 0 ; i -- )
3737 {
3838 cb = atexit_callbacks [i ];
3939 if (cb == NULL )
@@ -42,10 +42,12 @@ atexit_callfuncs(void)
4242 r = PyObject_Call (cb -> func , cb -> args , cb -> kwargs );
4343 Py_XDECREF (r );
4444 if (r == NULL ) {
45+ /* Maintain the last exception, but don't leak if there are
46+ multiple exceptions. */
4547 if (exc_type ) {
4648 Py_DECREF (exc_type );
47- Py_DECREF (exc_value );
48- Py_DECREF (exc_tb );
49+ Py_XDECREF (exc_value );
50+ Py_XDECREF (exc_tb );
4951 }
5052 PyErr_Fetch (& exc_type , & exc_value , & exc_tb );
5153 if (!PyErr_ExceptionMatches (PyExc_SystemExit )) {
@@ -92,6 +94,8 @@ atexit_register(PyObject *self, PyObject *args, PyObject *kwargs)
9294
9395 if (ncallbacks >= callback_len ) {
9496 callback_len += 16 ;
97+ /* XXX(nnorwitz): this leaks if realloc() fails. It also
98+ doesn't verify realloc() returns a valid (non-NULL) pointer. */
9599 atexit_callbacks = PyMem_Realloc (atexit_callbacks ,
96100 sizeof (atexit_callback * ) * callback_len );
97101
@@ -145,7 +149,7 @@ atexit_clear(PyObject *self)
145149 atexit_callback * cb ;
146150 int i ;
147151
148- for (i = 0 ; i < ncallbacks ; i ++ )
152+ for (i = 0 ; i < ncallbacks ; i ++ )
149153 {
150154 cb = atexit_callbacks [i ];
151155 if (cb == NULL )
@@ -163,7 +167,7 @@ atexit_unregister(PyObject *self, PyObject *func)
163167 atexit_callback * cb ;
164168 int i , eq ;
165169
166- for (i = 0 ; i < ncallbacks ; i ++ )
170+ for (i = 0 ; i < ncallbacks ; i ++ )
167171 {
168172 cb = atexit_callbacks [i ];
169173 if (cb == NULL )
@@ -213,5 +217,8 @@ initatexit(void)
213217 if (m == NULL )
214218 return ;
215219
220+ /* XXX(nnorwitz): probably best to register a callback that will free
221+ atexit_callbacks, otherwise valgrind will report memory leaks.
222+ Need to call atexit_clear() first. */
216223 _Py_PyAtExit (atexit_callfuncs );
217224}
0 commit comments