[Python-checkins] python/dist/src/Objects weakrefobject.c, 1.13.6.2, 1.13.6.3

fdrake at users.sourceforge.net fdrake at users.sourceforge.net
Wed Feb 4 18:13:46 EST 2004


Update of /cvsroot/python/python/dist/src/Objects
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21840/Objects

Modified Files:
      Tag: release23-maint
	weakrefobject.c 
Log Message:
Allocating a new weakref object can cause existing weakref objects for
the same object to be collected by the cyclic GC support if they are
only referenced by a cycle.  If the weakref being collected was one of
the weakrefs without callbacks, some local variables for the
constructor became invalid and have to be re-computed.

The test caused a segfault under a debug build without the fix applied.


Index: weakrefobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/weakrefobject.c,v
retrieving revision 1.13.6.2
retrieving revision 1.13.6.3
diff -C2 -d -r1.13.6.2 -r1.13.6.3
*** weakrefobject.c	3 Feb 2004 20:15:31 -0000	1.13.6.2
--- weakrefobject.c	4 Feb 2004 23:13:43 -0000	1.13.6.3
***************
*** 631,636 ****
          result = ref;
      if (result != NULL)
!         Py_XINCREF(result);
      else {
          result = new_weakref(ob, callback);
          if (result != NULL) {
--- 631,641 ----
          result = ref;
      if (result != NULL)
!         Py_INCREF(result);
      else {
+         /* Note: new_weakref() can trigger cyclic GC, so the weakref
+            list on ob can be mutated.  This means that the ref and
+            proxy pointers we got back earlier may have been collected,
+            so we need to compute these values again before we use
+            them. */
          result = new_weakref(ob, callback);
          if (result != NULL) {
***************
*** 639,644 ****
              }
              else {
!                 PyWeakReference *prev = (proxy == NULL) ? ref : proxy;
  
                  if (prev == NULL)
                      insert_head(result, list);
--- 644,651 ----
              }
              else {
!                 PyWeakReference *prev;
  
+                 get_basic_refs(*list, &ref, &proxy);
+                 prev = (proxy == NULL) ? ref : proxy;
                  if (prev == NULL)
                      insert_head(result, list);
***************
*** 673,678 ****
          result = proxy;
      if (result != NULL)
!         Py_XINCREF(result);
      else {
          result = new_weakref(ob, callback);
          if (result != NULL) {
--- 680,690 ----
          result = proxy;
      if (result != NULL)
!         Py_INCREF(result);
      else {
+         /* Note: new_weakref() can trigger cyclic GC, so the weakref
+            list on ob can be mutated.  This means that the ref and
+            proxy pointers we got back earlier may have been collected,
+            so we need to compute these values again before we use
+            them. */
          result = new_weakref(ob, callback);
          if (result != NULL) {
***************
*** 683,686 ****
--- 695,699 ----
              else
                  result->ob_type = &_PyWeakref_ProxyType;
+             get_basic_refs(*list, &ref, &proxy);
              if (callback == NULL)
                  prev = ref;




More information about the Python-checkins mailing list