FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Try to print repr() when an C-level assert fails (in the garbage collector, beyond?) · Issue #53509 · python/cpython · GitHub

Repository navigation

Try to print repr() when an C-level assert fails (in the garbage collector, beyond?) #53509

Description

BPO 9263
Nosy @loewis, @ncoghlan, @pitrou, @vstinner, @davidmalcolm, @serhiy-storchaka
PRs
  • bpo-9263: _PyObject_Dump() detects freed memory #10061
  • bpo-9263: Dump Python object on GC assertion failure #10062
  • bpo-9263: CheckConsistency() use _PyObject_ASSERT() #10108
  • bpo-9263: _Py_NegativeRefcount() use _PyObject_AssertFailed() #10109
  • bpo-9263: Use _PyObject_ASSERT() in object.c #10110
  • bpo-9263: Use _PyObject_ASSERT() in typeobject.c #10111
  • bpo-9263: Use _PyObject_ASSERT() in gcmodule.c #10112
  • bpo-9263: Fix _PyObject_Dump() for freed object #10661
  • [3.7] bpo-9263: _PyObject_Dump() detects freed memory (GH-10061) #10662
  • [3.6] bpo-9263: _PyObject_Dump() detects freed memory (GH-10061) (GH-10662) #10663
  • Files
  • py3k-repr-on-gcmodule-assertions.patch
  • py3k-objdump-on-gcmodule-assertions-2010-11-22-001.patch
  • py3k-objdump-on-gcmodule-assertions-2011-01-10-001.patch
  • py3k-objdump-on-gcmodule-assertions-2011-01-10-002.patch
  • 00170-gc-assertions.patch
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = <Date 2018-10-26.17:13:51.209>
    created_at = <Date 2010-07-14.23:50:49.130>
    labels = ['interpreter-core', 'type-feature']
    title = 'Try to print repr() when an C-level assert fails (in the garbage collector, beyond?)'
    updated_at = <Date 2018-11-22.16:40:57.760>
    user = 'https://github.com/davidmalcolm'

    bugs.python.org fields:

    activity = <Date 2018-11-22.16:40:57.760>
    actor = 'vstinner'
    assignee = 'none'
    closed = True
    closed_date = <Date 2018-10-26.17:13:51.209>
    closer = 'vstinner'
    components = ['Interpreter Core']
    creation = <Date 2010-07-14.23:50:49.130>
    creator = 'dmalcolm'
    dependencies = []
    files = ['18007', '19777', '20343', '20344', '30532']
    hgrepos = []
    issue_num = 9263
    keywords = ['patch']
    message_count = 20.0
    messages = ['110341', '122170', '125959', '125960', '131016', '131036', '190929', '328323', '328327', '328452', '328507', '328560', '328566', '328568', '328569', '328575', '328576', '330266', '330267', '330270']
    nosy_count = 7.0
    nosy_names = ['loewis', 'ncoghlan', 'pitrou', 'vstinner', 'dmalcolm', 'serhiy.storchaka', 'bkabrda']
    pr_nums = ['10061', '10062', '10108', '10109', '10110', '10111', '10112', '10661', '10662', '10663']
    priority = 'normal'
    resolution = 'fixed'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = 'enhancement'
    url = 'https://bugs.python.org/issue9263'
    versions = ['Python 3.3']

    Linked PRs

    Activity

    1. davidmalcolm commented on Jul 14, 2010

      MemberAuthor

      Modules/gcmodule.c contains various assertions which can fail due to reference counting errors elsewhere in either python, or an extension module. These can be difficult to track down.

      In the hope of maximizing the information from crash reports, the attached patch (against py3k) introduces a new assertion macro to Objects/object.h and Objects.c, which provides a richer debug message. In particular, it identifies which object has the issue, and can more clearly spell out the problem.

      The patch replaces all uses of assert() in Modules/gcmodule.c for which a specific object has an issue (e.g. bogus reference count).

      The implementation may play somewhat fast-and-loose with rules about object invariants: you might have an only partially valid object, but the process is about to abort, so it seems acceptable to try to glean extra information on stderr. (This may turn an abort into a segfault, of course)

      Caveats:

      • exact name of the API probably could be better
      • I don't yet have a specific use for the "callback" idea; I was thinking of trying to display all objects that reference that object. Might need a void* closure to be useful. Might be a useless complication.
      • Only tested on gcc-4.4.3 so far; the __STRING(expr) and __PRETTY_FUNCTION__ look non-portable.
      • no test case; I thought about using ctypes to extract PyObject_IncRef from the implementation, but this is likely to lead to brittle test cases. Alternatively, is xxmodule to be used for this kind of thing?

      Thoughts?

    2. davidmalcolm commented on Nov 22, 2010

      MemberAuthor

      Attaching a simplified version of the patch; I got rid of the callbacks.

      Still doesn't have test cases.

      I suspect that the use of __STRING and __PRETTY_FUNCTION__ may be compatibility issues. I believe that __FILE__ and __LINE__ and standard C though.

    3. davidmalcolm commented on Jan 10, 2011

      MemberAuthor

      Attaching updated version of the patch.

      I've added a selftest which (in a sacrificial subprocess) abuses ctypes to break an ob_refcnt, and then triggers a garbage collection.

      I also changed the printing to stderr to directly use fprintf and fflush to ensure that data leaves the process before abort kills it (not sure if this is a cross-platform or unicode no-no, though).

    4. davidmalcolm commented on Jan 10, 2011

      MemberAuthor

      As above, but I added an extra call to fflush in case the call to _PyObject_Dump leads to a segfault.

    5. pitrou commented on Mar 15, 2011

      Member

      How about turning these asserts into Py_FatalError()s and then enabling Victor's faulthandler extension?

    6. ncoghlan commented on Mar 15, 2011

      Contributor

      I'd suggest calling Py_FatalError rather than calling abort() directly in _PyObject_AssertFailed, but otherwise this looks like a nice improvement over standard C asserts for state invariants that may be broken by buggy C extensions.

      For the tests, take a look at test.script_helper - it provides some convenience wrappers for spawning subprocesses for tests that would cause problems if run in the current process.

    7. bkabrda commented on Jun 10, 2013

      bkabrdamannequin
      Mannequin

      I'm currently patching Python 3.3.2 with this, so I thought it might be nice to attach an up-to-date patch. The only notable difference is that I added self.preclean() at the beginning of test_refcount_errors - without it, running test suite produced a huge number of these lines:

      Exception AttributeError: "'GCCallbackTests' object has no attribute 'visit'" in <bound method GCCallbackTests.cb1 of <main.GCCallbackTests testMethod=test_refcount_errors>> ignored

    8. vstinner commented on Oct 23, 2018

      Member

      New changeset 82af0b6 by Victor Stinner in branch 'master':
      bpo-9263: _PyObject_Dump() detects freed memory (GH-10061)
      82af0b6

    9. vstinner commented on Oct 23, 2018

      Member

      00170-gc-assertions.patch is used in the Fedora package of Python.

      I converted the patch to a pull request: PR 10062.

      My PR only uses the new assertion macro once. I plan to write more changes to use the new assertion macros in more places, once the first PR is merged.

    10. vstinner commented on Oct 25, 2018

      Member

      New changeset 626bff8 by Victor Stinner in branch 'master':
      bpo-9263: Dump Python object on GC assertion failure (GH-10062)
      626bff8

    11. vstinner commented on Oct 26, 2018

      Member

      New changeset 3ec9af7 by Victor Stinner in branch 'master':
      bpo-9263: _Py_NegativeRefcount() use _PyObject_AssertFailed() (GH-10109)
      3ec9af7

    12. vstinner commented on Oct 26, 2018

      Member

      New changeset 2470204 by Victor Stinner in branch 'master':
      bpo-9263: Use _PyObject_ASSERT() in object.c (GH-10110)
      2470204

    13. vstinner commented on Oct 26, 2018

      Member

      New changeset a4b2bc7 by Victor Stinner in branch 'master':
      bpo-9263: Use _PyObject_ASSERT() in gcmodule.c (GH-10112)
      a4b2bc7

    14. vstinner commented on Oct 26, 2018

      Member

      New changeset 0862505 by Victor Stinner in branch 'master':
      bpo-9263: Use _PyObject_ASSERT() in typeobject.c (GH-10111)
      0862505

    15. vstinner commented on Oct 26, 2018

      Member

      New changeset 50fe3f8 by Victor Stinner in branch 'master':
      bpo-9263: _PyXXX_CheckConsistency() use _PyObject_ASSERT() (GH-10108)
      50fe3f8

    16. vstinner commented on Oct 26, 2018

      Member

      I pushed the change and even more, so I consider that the issue can now be closed... 8 years later! Thank you very much Dave Malcolm for this nice idea, and for its implementation. Thanks Bohuslav "Slavek" Kabrda for the rebase in 2013, and thanks to my colleagues who rebased the patch frequently since 2013 in the Fedora package!

      Maybe some people (like me?) want to use _PyObject_ASSERT() in more places, but I consider that we don't need to leave this issue open just for that.

      I took the 00170-gc-assertions.patch rebased on Python 3.7.1 by my colleagues for the Fedora package, and I rebased it on master. I modified more functions in object.c and typeobject.c to use _PyObject_ASSERT(). I tried to not replace all assert(), but only when it's revelant.

      I added code to detect if the object memory has been freed to avoid derefering 0xdbdbdbdbdbdbdbdb pointers which is very likely to cause a segmantation fault. It should reduce the risk of crash when dumping the faulty object.

      Dave Malcolm:

      • Only tested on gcc-4.4.3 so far; the __STRING(expr) and __PRETTY_FUNCTION__ look non-portable.

      I used Py_STRINGIFY() and __func__ in the final patch. __func__ is part of the C99 standard which is now required since Python 3.6: see PEP-7.

      Dave Malcolm:

      • no test case; I thought about using ctypes to extract PyObject_IncRef from the implementation, but this is likely to lead to brittle test cases. Alternatively, is xxmodule to be used for this kind of thing?

      I reworked the unit test to not use ctypes, but write the crashing code in C instead.

      Antoine Pitrou:

      How about turning these asserts into Py_FatalError()s and then enabling Victor's faulthandler extension?

      Done.

    17. davidmalcolm commented on Oct 26, 2018

      MemberAuthor

      Thanks!

    18. vstinner commented on Nov 22, 2018

      Member

      New changeset 2cf5d32 by Victor Stinner in branch 'master':
      bpo-9263: Fix _PyObject_Dump() for freed object (bpo-10661)
      2cf5d32

    19. vstinner commented on Nov 22, 2018

      Member

      New changeset 95036ea by Victor Stinner in branch '3.7':
      [3.7] bpo-9263: _PyObject_Dump() detects freed memory (GH-10061) (GH-10662)
      95036ea

    20. vstinner commented on Nov 22, 2018

      Member

      New changeset c9b3fc6 by Victor Stinner in branch '3.6':
      bpo-9263: _PyObject_Dump() detects freed memory (GH-10061) (GH-10662) (GH-10663)
      c9b3fc6

    21. transferred this issue fromon Apr 10, 2022
    22. added 3 commits that reference this issue on Oct 9, 2025
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Metadata

    Metadata

    Assignees

    No one assigned

      Labels

      interpreter-core(Objects, Python, Grammar, and Parser dirs)type-featureA feature request or enhancement

      Projects

      No projects

        Milestone

        No milestone

        Relationships

        None yet

        Development

        No branches or pull requests

        Issue actions


        Back | FazBrowse Home | New Git URL