Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dictobject infinite loop in module set-up #59108

Closed
DanielFarina mannequin opened this issue May 24, 2012 · 14 comments
Closed

dictobject infinite loop in module set-up #59108

DanielFarina mannequin opened this issue May 24, 2012 · 14 comments
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error

Comments

@DanielFarina
Copy link
Mannequin

DanielFarina mannequin commented May 24, 2012

BPO 14903
Nosy @rhettinger, @terryjreedy, @gpshead, @benjaminp, @alex, @markshannon, @iritkatriel
Files
  • offender.py
  • 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 2020-11-07.19:57:28.118>
    created_at = <Date 2012-05-24.20:19:44.412>
    labels = ['interpreter-core', 'type-bug']
    title = 'dictobject infinite loop in module set-up'
    updated_at = <Date 2020-11-07.19:57:28.118>
    user = 'https://bugs.python.org/DanielFarina'

    bugs.python.org fields:

    activity = <Date 2020-11-07.19:57:28.118>
    actor = 'gregory.p.smith'
    assignee = 'none'
    closed = True
    closed_date = <Date 2020-11-07.19:57:28.118>
    closer = 'gregory.p.smith'
    components = ['Interpreter Core']
    creation = <Date 2012-05-24.20:19:44.412>
    creator = 'Daniel.Farina'
    dependencies = []
    files = ['31578']
    hgrepos = []
    issue_num = 14903
    keywords = []
    message_count = 14.0
    messages = ['161527', '161529', '161683', '161684', '190952', '191254', '196889', '196891', '196892', '196893', '221011', '270868', '380515', '380521']
    nosy_count = 9.0
    nosy_names = ['rhettinger', 'terry.reedy', 'gregory.p.smith', 'benjamin.peterson', 'alex', 'Mark.Shannon', 'Daniel.Farina', 'Max Khon', 'iritkatriel']
    pr_nums = []
    priority = 'normal'
    resolution = 'out of date'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue14903'
    versions = ['Python 2.6', '3rd party', 'Python 2.7']

    @DanielFarina
    Copy link
    Mannequin Author

    DanielFarina mannequin commented May 24, 2012

    I seem to be encountering somewhat rare an infinite loop
    in hash table probing while importing _socket, as triggered by
    init_socket.c in Python 2.6, as seen/patched shipped with Ubuntu 10.04
    LTS. The problem only reproduces on 32 bit machines, on both -O2 and
    -O0 builds (which is how I have managed to retrieve the detailed stack
    traces below). To cut to the chase, the bottom of the stack trace
    invariably looks like this, in particular the "key" (and therefore
    "hash") value is always the same:

    #0  0x08088637 in lookdict_string (mp=0xa042714, key='SO_RCVTIMEO',
       hash=612808203) at ../Objects/dictobject.c:421
    #1  0x080886cd in insertdict (mp=0xa042714, key='SO_RCVTIMEO', hash=612808203,
       value=20) at ../Objects/dictobject.c:450
    #2  0x08088cac in PyDict_SetItem (op=<unknown at remote 0x37>, key=
       'SO_RCVTIMEO', value=20) at ../Objects/dictobject.c:701
    #3  0x0808b8d4 in PyDict_SetItemString (v=
       {'AF_INET6': 10, 'SocketType': <type at remote 0x8275e00>,
    'getaddrinfo': <built-in function getaddrinfo>,
    'TIPC_MEDIUM_IMPORTANCE': 1, 'htonl': <built-in function htonl>,
    'AF_UNSPEC': 0, 'TIPC_DEST_DROPPABLE': 129, 'TIPC_ADDR_ID': 3,
    'PF_PACKET': 17, 'AF_WANPIPE': 25, 'PACKET_OTHERHOST': 3, 'AF_AX25':
    3, 'PACKET_BROADCAST': 1, 'PACKET_FASTROUTE': 6, 'TIPC_NODE_SCOPE': 3,
    'inet_pton': <built-in function inet_pton>, 'AF_ATMPVC': 8,
    'NETLINK_IP6_FW': 13, 'NETLINK_ROUTE': 0, 'TIPC_PUBLISHED': 1,
    'TIPC_WITHDRAWN': 2, 'AF_ECONET': 19, 'AF_LLC': 26, '__name__':
    '_socket', 'AF_NETROM': 6, 'SOCK_RDM': 4, 'AF_IRDA': 23, 'htons':
    <built-in function htons>, 'SOCK_RAW': 3, 'inet_ntoa': <built-in
    function inet_ntoa>, 'AF_NETBEUI': 13, 'AF_NETLINK': 16,
    'TIPC_WAIT_FOREVER': -1, 'AF_UNIX': 1, 'TIPC_SUB_PORTS': 1,
    'HCI_TIME_STAMP': 3, 'gethostbyname_ex': <built-in function
    gethostbyname_ex>, 'SO_RCVBUF': 8, 'AF_APPLETALK': 5,
    'SOCK_SEQPACKET': 5, 'AF_DECnet': 12, 'PACKET_OUTGOING': 4,
    'SO_SNDLOWAT': 19, 'TIPC_SRC_DROPPABLE':...(truncated), key=0x81ac5fb
    "SO_RCVTIMEO", item=20) at ../Objects/dictobject.c:2301
    #4  0x080f6c98 in PyModule_AddObject (m=<module at remote 0xb73cac8c>, name=
       0x81ac5fb "SO_RCVTIMEO", o=20) at ../Python/modsupport.c:615
    #5  0x080f6d0b in PyModule_AddIntConstant (m=<module at remote 0xb73cac8c>,
       name=0x81ac5fb "SO_RCVTIMEO", value=20) at ../Python/modsupport.c:627
    #6  0x081321fd in init_socket () at ../Modules/socketmodule.c:4708

    Here, we never escape from lookdict_string. The key is not in the
    dictionary, but at this stage Python is trying to figure out that is
    the case, and cannot seem to exit because of the lack of a dummy
    entry. Furthermore, every single reproduced case has a dictionary
    with a suspicious looking violation of an invariant that I believe is
    communicated by the source of dictobject.c, with emphasis on the
    values of ma_fill, ma_used, and ma_mask, which never deviate in any
    reproduced case. It seems like no hash table should ever get this
    full, per the comments in the source:

    $3 = {ob_refcnt = 1, ob_type = 0x81c3aa0, ma_fill = 128, ma_used = 128,
    ma_mask = 127, ma_table = 0xa06b4a8, ma_lookup =
    0x8088564 <lookdict_string>, ma_smalltable = {{me_hash = 0, me_key = 0x0,
    me_value = 0x0}, {me_hash = 1023053529, me_key = '__name__', me_value =
    '_socket'}, {me_hash = 1679430097, me_key = 'gethostbyname', me_value =
    <built-in function gethostbyname>}, {me_hash = 0, me_key = 0x0, me_value =
    0x0}, {me_hash = 779452068, me_key = 'gethostbyname_ex', me_value =
    <built-in function gethostbyname_ex>}, {me_hash = -322108099, me_key =
    '__doc__', me_value = None}, {me_hash = -1649837379, me_key =
    'gethostbyaddr', me_value = <built-in function gethostbyaddr>}, {
    me_hash = 1811348911, me_key = '__package__', me_value = None}}}

    The Python program that is running afoul this bug is using gevent, but
    the stack traces suggest that all gevent is doing at the time this
    crashes is importing "socket", and this is done at the very, very
    beginning of program execution.

    Finally, what's especially strange is that I had gone a very long time
    running this exact version of Python, libraries, and application quite
    frequently: it suddenly started cropping up a little while ago (maybe
    a few weeks). It could have been just coincidence, but if there are
    code paths in init_socket.c that may somehow be sensitive to the
    network somehow, this could have been related. I also have a limited
    suspicion that particularly unlucky OOM (these systems are configured
    in a way where malloc and friends will return NULL, i.e. no overcommit
    on Linux) could be related.

    @DanielFarina DanielFarina mannequin added interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error labels May 24, 2012
    @terryjreedy
    Copy link
    Member

    Can you reproduce on current 2.7.3 or 3.2.3 or even 3.3.0 (which has changed dict implementation)? Or can you upload a short program that exhibits the problem, so someone else can try? 2.6 gets security fixes only and I do not believe this qualifies. If not a current problem, this should be closed as out of date, even if disconcerting.

    @DanielFarina
    Copy link
    Mannequin Author

    DanielFarina mannequin commented May 26, 2012

    Unfortunately it's not so easy to upgrade the system's Python, however, it is something we might try. The reproducing test case would appear to be akin to:

    "import _socket"

    And, within the gevent stack trace program, https://github.com/schmir/gevent/blob/master/gevent/monkey.py#L109

    But to be precise, it is stuck at: https://github.com/heroku/WAL-E/blob/master/wal_e/cmd.py#L17. None of this is very helpful, I realize, but this program (in this case, when archiving PostgreSQL write-ahead-log archives) is started up millions of times in a day, putting the defect rate at not far from the nominally figurative phrase "one in a million".

    @terryjreedy
    Copy link
    Member

    I was suggesting alternate installations, not that you touch your system Python (a bad idea I have read). Such should be easy on Ubuntu. Whether you can run this particular program with alt installs is a different matter. If you have questions about doing so, also try python-ideas list or the news.gmane mirror, where there are several *nix users, including Ubuntu.

    @DanielFarina
    Copy link
    Mannequin Author

    DanielFarina mannequin commented Jun 11, 2013

    Hello folks,

    After long delay, I can confirm this issue reproduces in a similar way inside of init_socket in 2.7.

    @DanielFarina
    Copy link
    Mannequin Author

    DanielFarina mannequin commented Jun 16, 2013

    In addition to being re-verified on 2.7, this occurred on a 64 bit system, so I've changed the title accordingly.

    @DanielFarina DanielFarina mannequin changed the title dictobject infinite loop on 2.6.5 on 32-bit x86 dictobject infinite loop Jun 16, 2013
    @DanielFarina DanielFarina mannequin changed the title dictobject infinite loop dictobject infinite loop while importing socket Jun 21, 2013
    @DanielFarina
    Copy link
    Mannequin Author

    DanielFarina mannequin commented Sep 4, 2013

    I've confirmed this in a non-gevent program (actually a very trivial one, I can include the source if anyone asks), in 'initposix'. This is on a quiet system, so OOM is not a very likely explanation. Perhaps signal handling?

    #0 0x000000000054662d in ?? ()
    #1 0x000000000054d12e in ?? ()
    #2 0x00000000005209e9 in PyDict_SetItem ()
    #3 0x00000000004430cd in ?? ()
    #4 0x0000000000456fcc in initposix ()
    #5 0x0000000000456d2b in ?? ()
    #6 0x000000000055fd03 in ?? ()
    #7 0x00000000005600cb in ?? ()
    #8 0x00000000004a0893 in ?? ()
    #9 0x0000000000560964 in ?? ()
    #10 0x0000000000553eab in ?? ()
    #11 0x00000000004bf2a6 in PyObject_Call ()
    #12 0x00000000004bf5a6 in PyEval_CallObjectWithKeywords ()
    #13 0x000000000046870b in PyEval_EvalFrameEx ()
    #14 0x000000000057bd02 in PyEval_EvalCodeEx ()
    #15 0x000000000057cda8 in PyImport_ExecCodeModuleEx ()
    #16 0x000000000055f6d1 in ?? ()
    #17 0x00000000005600cb in ?? ()
    #18 0x00000000004a0893 in ?? ()
    #19 0x0000000000560964 in ?? ()
    #20 0x0000000000553eab in ?? ()
    #21 0x00000000004bf2a6 in PyObject_Call ()
    #22 0x00000000004bf5a6 in PyEval_CallObjectWithKeywords ()
    #23 0x000000000046870b in PyEval_EvalFrameEx ()
    #24 0x000000000057bd02 in PyEval_EvalCodeEx ()
    #25 0x000000000057cda8 in PyImport_ExecCodeModuleEx ()
    #26 0x000000000055f6d1 in ?? ()
    #27 0x00000000005600cb in ?? ()
    #28 0x00000000004a0893 in ?? ()
    #29 0x0000000000560964 in ?? ()
    #30 0x0000000000553eab in ?? ()
    #31 0x00000000004bf2a6 in PyObject_Call ()
    #32 0x00000000004943c5 in PyObject_CallFunction ()
    #33 0x000000000054dfbe in PyImport_Import ()
    #34 0x000000000050df4d in ?? ()
    #35 0x0000000000511ae2 in ?? ()
    #36 0x0000000000512764 in Py_Main ()
    #37 0x00007f88142bc76d in __libc_start_main () from
    /lib/x86_64-linux-gnu/libc.so.6
    #38 0x000000000041ba51 in _start ()

    @alex
    Copy link
    Member

    alex commented Sep 4, 2013

    If you could supply the source that'd be great.

    @DanielFarina
    Copy link
    Mannequin Author

    DanielFarina mannequin commented Sep 4, 2013

    Attached. The program's function is to take a base64 encoded string and arguments as input and then to materialize this program on disk and run it with its arguments.

    Notably, this one contains no socket interaction at all, unlike the other examples, which narrows the cause quite a bit. It is run via 'ssh'. Like the other case, it's during module dictionary set-up.

    @DanielFarina
    Copy link
    Mannequin Author

    DanielFarina mannequin commented Sep 4, 2013

    altered title now that it's been seen in init_posix.

    @DanielFarina DanielFarina mannequin changed the title dictobject infinite loop while importing socket dictobject infinite loop in module set-up Sep 4, 2013
    @gpshead
    Copy link
    Member

    gpshead commented Jun 19, 2014

    Can you provide specific details of exactly which python package from which distro is installed on the machines?

    Are the machines hardware or VMs? if they are VMs, what version of what VM system and what hardware are the VMs running on?

    I'm asking because someone at work is seeing a potentially similar problem from an ubuntu python2.7-minimal package - i don't know which version - they can pipe in here and provide that and any other details that may be relevant.

    @MaxKhon
    Copy link
    Mannequin

    MaxKhon mannequin commented Jul 20, 2016

    I reproduced the problem with Python 2.7.5 as shipped with CentOS 7:

    root@192.168.0.86 /home/padmin # python -V
    Python 2.7.5
    root@192.168.0.86 /home/padmin # rpm -q python
    python-2.7.5-34.el7.x86_64
    root@192.168.0.86 /home/padmin #

    (gdb) bt
    #0 lookdict_string (mp=<optimized out>, key='RPMTAG_OPTFLAGS', hash=411442822543039667)
    at /usr/src/debug/Python-2.7.5/Objects/dictobject.c:461
    #1 0x00007f92d6d9f2c9 in insertdict (mp=0x2502600, key='RPMTAG_OPTFLAGS', hash=411442822543039667,
    value=1122) at /usr/src/debug/Python-2.7.5/Objects/dictobject.c:559
    #2 0x00007f92d6d9f3b0 in dict_set_item_by_hash_or_entry (
    op={'RPMTAG_HEADERREGIONS': 64, 'RPMTAG_EXCLUSIVEOS': 1062, 'fi': <type at remote 0x7f92c87ef6c0>, 'RPMTAG_CHANGELOGNAME': 1081, 'RPMTAG_CONFLICTNEVRS': 5044, 'RPMTAG_FILECAPS': 5010, 'RPMTAG_FILERDEVS': 1033, 'RPMTAG_COLLECTIONS': 5029, 'RPMTAG_BUGURL': 5012, 'setStats': <built-in function setStats>, 'RPMTAG_FILEDIGESTALGO': 5011, 'RPMTAG_DEPENDSDICT': 1145, 'RPMTAG_CLASSDICT': 1142, 'RPMTAG_FILEMODES': 1030, 'RPMTAG_FILEDEPENDSN': 1144, 'RPMTAG_BUILDTIME': 1006, 'ii': <type at remote 0x7f92c87f0280>, 'RPMTAG_INSTALLCOLOR': 1127, 'RPMTAG_CHANGELOGTEXT': 1082, 'RPMTAG_HEADERCOLOR': 5017, 'RPMTAG_CONFLICTNAME': 1054, 'RPMTAG_CONFLICTS': 1054, 'setLogFile': <built-in function setLogFile>, 'versionCompare': <built-in function versionCompare>, 'RPMTAG_CONFLICTVERSION': 1055, 'RPMTAG_NVRA': 1196, 'RPMTAG_NOPATCH': 1052, 'RPMTAG_HEADERI18NTABLE': 100, 'RPMTAG_LONGARCHIVESIZE': 271, 'RPMTAG_FILEREQUIRE': 5002, 'RPMTAG_FILEDEPENDSX': 1143, 'RPMTAG_EVR': 5013, 'RPMTAG_INSTALLTIME': 1008, 'RPMTAG_NAME': 1000, 'RPMTAG_LONG...(truncated), key=<optimized out>, hash=<optimized out>,
    ep=<optimized out>, value=<optimized out>) at /usr/src/debug/Python-2.7.5/Objects/dictobject.c:774
    #3 0x00007f92d6da18a8 in PyDict_SetItemString (
    v={'RPMTAG_HEADERREGIONS': 64, 'RPMTAG_EXCLUSIVEOS': 1062, 'fi': <type at remote 0x7f92c87ef6c0>, 'RPMTAG_CHANGELOGNAME': 1081, 'RPMTAG_CONFLICTNEVRS': 5044, 'RPMTAG_FILECAPS': 5010, 'RPMTAG_FILERDEVS': 1033, 'RPMTAG_COLLECTIONS': 5029, 'RPMTAG_BUGURL': 5012, 'setStats': <built-in function setStats>, 'RPMTAG_FILEDIGESTALGO': 5011, 'RPMTAG_DEPENDSDICT': 1145, 'RPMTAG_CLASSDICT': 1142, 'RPMTAG_FILEMODES': 1030, 'RPMTAG_FILEDEPENDSN': 1144, 'RPMTAG_BUILDTIME': 1006, 'ii': <type at remote 0x7f92c87f0280>, 'RPMTAG_INSTALLCOLOR': 1127, 'RPMTAG_CHANGELOGTEXT': 1082, 'RPMTAG_HEADERCOLOR': 5017, 'RPMTAG_CONFLICTNAME': 1054, 'RPMTAG_CONFLICTS': 1054, 'setLogFile': <built-in function setLogFile>, 'versionCompare': <built-in function versionCompare>, 'RPMTAG_CONFLICTVERSION': 1055, 'RPMTAG_NVRA': 1196, 'RPMTAG_NOPATCH': 1052, 'RPMTAG_HEADERI18NTABLE': 100, 'RPMTAG_LONGARCHIVESIZE': 271, 'RPMTAG_FILEREQUIRE': 5002, 'RPMTAG_FILEDEPENDSX': 1143, 'RPMTAG_EVR': 5013, 'RPMTAG_INSTALLTIME': 1008, 'RPMTAG_NAME': 1000, 'RPMTAG_LONG...(truncated), key=key@entry=0x7f92c83bf537 "RPMTAG_OPTFLAGS",
    item=item@entry=1122) at /usr/src/debug/Python-2.7.5/Objects/dictobject.c:2448
    #4 0x00007f92d6e181f2 in PyModule_AddObject (m=m@entry=<module at remote 0x24d35c8>,
    name=name@entry=0x7f92c83bf537 "RPMTAG_OPTFLAGS", o=o@entry=1122)
    at /usr/src/debug/Python-2.7.5/Python/modsupport.c:616
    #5 0x00007f92d6e182d8 in PyModule_AddIntConstant (m=m@entry=<module at remote 0x24d35c8>,
    name=name@entry=0x7f92c83bf537 "RPMTAG_OPTFLAGS", value=value@entry=1122)
    at /usr/src/debug/Python-2.7.5/Python/modsupport.c:628
    #6 0x00007f92c85e2b20 in addRpmTags (module=<module at remote 0x24d35c8>) at rpmmodule.c:200
    #7 initModule (m=<module at remote 0x24d35c8>) at rpmmodule.c:343
    #8 init_rpm () at rpmmodule.c:281
    #9 0x00007f92d6e13ed9 in _PyImport_LoadDynamicModule (name=name@entry=0x24f69d0 "rpm._rpm",
    pathname=pathname@entry=0x24f79e0 "/usr/lib64/python2.7/site-packages/rpm/_rpmmodule.so",
    fp=<optimized out>) at /usr/src/debug/Python-2.7.5/Python/importdl.c:53
    ...

    The infinite loop happens when "import rpm" is called in low-memory conditions (e.g. when handling ENOMEM or exceptions.MemoryError - RedHat/CentOS abrt-addon-python package which installs sys.excepthook handler).

    @iritkatriel
    Copy link
    Member

    Is this a python 2-only issue?

    @gpshead
    Copy link
    Member

    gpshead commented Nov 7, 2020

    I suspect so. If any modern supported python 3.x version runs into an issue like this I think opening a fresh bugreport is good.

    Closing as not reproducable / obsolete.

    @gpshead gpshead closed this as completed Nov 7, 2020
    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error
    Projects
    None yet
    Development

    No branches or pull requests

    4 participants