classification
Title: Python segfaults when configured with --with-pydebug --with-trace-refs
Type: Stage: resolved
Components: Interpreter Core Versions: Python 3.9
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: pablogsal, vstinner
Priority: normal Keywords: patch

Created on 2019-10-07 23:01 by pablogsal, last changed 2019-10-08 07:06 by vstinner. This issue is now closed.

Pull Requests
URL Status Linked Edit
PR 16630 merged pablogsal, 2019-10-07 23:21
Messages (4)
msg354151 - (view) Author: Pablo Galindo Salgado (pablogsal) * (Python committer) Date: 2019-10-07 23:01
configure --with-pydebug --with-trace-refs && make

Modules/gcmodule.c:378: visit_decref: Assertion "!_PyObject_IsFreed(op)" failed
<object at 0x5557629ca260 is freed>
Fatal Python error: _PyObject_AssertFailed
Python runtime state: preinitialized

Current thread 0x00007f6e2863e740 (most recent call first):
<no Python frame>
/bin/sh: line 5: 28078 Aborted                 (core dumped) ./python -E -S -m sysconfig --generate-posix-vars
generate-posix-vars failed
make: * [Makefile:592: pybuilddir.txt] Error 1
msg354152 - (view) Author: Pablo Galindo Salgado (pablogsal) * (Python committer) Date: 2019-10-07 23:01
This is a regression introduced by:

commit 6876257eaabdb30f27ebcbd7d2557278ce2e5705
Author: Victor Stinner <vstinner@python.org>
Date:   Mon Oct 7 18:42:01 2019 +0200

    bpo-36389: _PyObject_CheckConsistency() available in release mode (GH-16612)
    
    bpo-36389, bpo-38376: The _PyObject_CheckConsistency() function is
    now also available in release mode. For example, it can be used to
    debug a crash in the visit_decref() function of the GC.
    
    Modify the following functions to also work in release mode:
    
    * _PyDict_CheckConsistency()
    * _PyObject_CheckConsistency()
    * _PyType_CheckConsistency()
    * _PyUnicode_CheckConsistency()
    
    Other changes:
    
    * _PyMem_IsPtrFreed(ptr) now also returns 1 if ptr is NULL
      (equals to 0).
    * _PyBytesWriter_CheckConsistency() now returns 1 and is only used
      with assert().
    * Reorder _PyObject_Dump() to write safe fields first, and only
      attempt to render repr() at the end.
msg354153 - (view) Author: Pablo Galindo Salgado (pablogsal) * (Python committer) Date: 2019-10-07 23:43
New changeset 36e33c360ed7716a2b5ab2b53210da81f8ce1295 by Pablo Galindo in branch 'master':
bpo-38400 Don't check for NULL linked list pointers in _PyObject_IsFreed (GH-16630)
https://github.com/python/cpython/commit/36e33c360ed7716a2b5ab2b53210da81f8ce1295
msg354171 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2019-10-08 07:06
Notes for myself.

the visit_decref() has been updated to display repr() of the parent object, rather than display the "freed" object.

Before:
---
Modules/gcmodule.c:378: visit_decref: Assertion "!_PyObject_IsFreed(op)" failed
<object at 0x5557629ca260 is freed>
Fatal Python error: _PyObject_AssertFailed
Python runtime state: preinitialized

Current thread 0x00007f6e2863e740 (most recent call first):
<no Python frame>
---

After:
---
Modules/gcmodule.c:378: visit_decref: Assertion "!_PyObject_IsFreed(op)" failed
Enable tracemalloc to get the memory block allocation traceback

object address  : 0x7fe2d1a52b40
object refcount : 1
object type     : 0x740be0
object type name: dict
object repr     : {'__repr__': <slot wrapper '__repr__' of 'weakref' objects>, '__hash__': <slot wrapper '__hash__' of 'weakref' objects>, '__call__': <slot wrapper '__call__' of 'weakref' objects>, '__lt__': <slot wrapper '__lt__' of 'weakref' objects>, '__le__': <slot wrapper '__le__' of 'weakref' objects>, '__eq__': <slot wrapper '__eq__' of 'weakref' objects>, '__ne__': <slot wrapper '__ne__' of 'weakref' objects>, '__gt__': <slot wrapper '__gt__' of 'weakref' objects>, '__ge__': <slot wrapper '__ge__' of 'weakref' objects>, '__init__': <slot wrapper '__init__' of 'weakref' objects>, '__new__': <built-in method __new__ of type object at 0x749500>, '__callback__': <member '__callback__' of 'weakref' objects>, '__doc__': None}

Fatal Python error: _PyObject_AssertFailed
Python runtime state: preinitialized

Current thread 0x00007fe2dea35740 (most recent call first):
<no Python frame>
---

The problem was that the None object was seen as "freed" because _ob_prev=_ob_next=NULL. This object doesn't seem to be part of the list of all objects, sys.getobjects(). I fixed Py_None, but then I got the same assertion error on a different (moduledef) object. I gave up, and Pablo and me fixed _PyObject_IsFreed() instead.
History
Date User Action Args
2019-10-08 07:06:54vstinnersetmessages: + msg354171
2019-10-07 23:43:22pablogsalsetstatus: open -> closed
resolution: fixed
stage: patch review -> resolved
2019-10-07 23:43:17pablogsalsetmessages: + msg354153
2019-10-07 23:21:09pablogsalsetkeywords: + patch
stage: patch review
pull_requests: + pull_request16216
2019-10-07 23:01:53pablogsalsetmessages: + msg354152
2019-10-07 23:01:37pablogsalcreate