[Patches] [ python-Patches-448194 ] Debuging negative reference counts

noreply@sourceforge.net noreply@sourceforge.net
Sun, 05 Aug 2001 10:52:26 -0700


Patches item #448194, was opened at 2001-08-05 10:52
You can respond by visiting: 
http://sourceforge.net/tracker/?func=detail&atid=305470&aid=448194&group_id=5470

Category: None
Group: None
Status: Open
Resolution: None
Priority: 5
Submitted By: Frederic Giacometti (giacometti)
Assigned to: Nobody/Anonymous (nobody)
Summary: Debuging negative reference counts

Initial Comment:



I'm giving the patch below as a 'time-saver' for extension writters suffering crashes 
(memory-related in most cases).

The patch is activated only under compilation with the Py_DEBUG flag (hint: production code is 
unchanged, this is only of concerns to Py_DEBUG-aware developpers).

The new behavior is as follows (under Py_DEBUG):

After decrementing:
 if 0 < do_nothing; elseif 0 == refcount release_memory; else print_warning;
 #instead of: if 0 < do_nothing else release-memory;

In effect, in the present python code, releasing a memory segment already released (negative ref 
count will at best crash the application, or further corrupts it).

With the patch, in the situations (the very large majority of cases) where the memory has not 
already been overwritten with a positive value, the negative ref count is recognized, and an 
appropriate action is taken (currently: print the Py_DECREF location to stderr, instead of 
releasing [erroneously] the memory segment).

Note that the only penalty to this is some small code bloat under Py_DEBUG compilation.

The feature has been tested on two project, and demonstrated to directly pinpoint almost directly 
to the culprit in situations where a Py_INCREF has been missing somewhere (as an alternate to teh 
traditional application crash further down the application :(((


Frederic Giacometti


diff -c -r1.1.1.1 object.h
*** Include/object.h	2001/05/27 15:36:16	1.1.1.1
--- Include/object.h	2001/07/05 22:10:54
***************
*** 429,439 ****
  #endif /* !Py_TRACE_REFS */
  
  #define Py_INCREF(op) (_Py_RefTotal++, (op)->ob_refcnt++)
! #define Py_DECREF(op) \
! 	if (--_Py_RefTotal, (--((op)->ob_refcnt) != 0)) \
! 		; \
! 	else \
! 		_Py_Dealloc((PyObject *)(op))
  #else /* !Py_REF_DEBUG */
  
  #ifdef COUNT_ALLOCS
--- 429,440 ----
  #endif /* !Py_TRACE_REFS */
  
  #define Py_INCREF(op) (_Py_RefTotal++, (op)->ob_refcnt++)
!   /* under Py_REF_DEBUG: also log negative ref counts after Py_DECREF() !! */
! #define Py_DECREF(op)							\
!        if (--_Py_RefTotal, 0 < (--((op)->ob_refcnt))) ;			\
!        else if (0 == (op)->ob_refcnt) _Py_Dealloc( (PyObject*)(op));	\
!        else (void)fprintf( stderr, "%s:%i negative ref count %i\n",	\
! 		           __FILE__, __LINE__, (op)->ob_refcnt)
  #else /* !Py_REF_DEBUG */
  
  #ifdef COUNT_ALLOCS


----------------------------------------------------------------------

You can respond by visiting: 
http://sourceforge.net/tracker/?func=detail&atid=305470&aid=448194&group_id=5470