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

[BUG] v2.1.2 segfaults on Python 3.7 on Debian #41

Closed
progval opened this issue Dec 21, 2021 · 14 comments
Closed

[BUG] v2.1.2 segfaults on Python 3.7 on Debian #41

progval opened this issue Dec 21, 2021 · 14 comments
Labels
Status: Fixed Now it works! Type: Bug Something isn't working

Comments

@progval
Copy link

progval commented Dec 21, 2021

Hi,

OS version: Debian 10, in Docker; installed using this Dockerfile: https://forge.softwareheritage.org/source/swh-jenkins-dockerfiles/browse/master/sphinx/Dockerfile

Python3 version (python3 -V -V):

Python 3.7.3 (default, Jan 22 2021, 20:04:44)
--
[GCC 8.3.0]

Steps to reproduce:

  1. run python3 -c "from frozendict import frozendict; frozendict({'_uuid': '9c20cbe8-6275-11ec-a64f-0242ac110001', 'processingMode': 'json-ld-1.1', 'mappings': {}})"

Actual result (with the python stack trace if present):

Segmentation fault (core dumped)

In details:

(.venv) jenkins@30f908325208:~/swh-environment/swh-search$ python3 -c "from frozendict import frozendict; frozendict({'_uuid': '9c20cbe8-6275-11ec-a64f-0242ac110001', 'processingMode': 'json-ld-1.1', 'mappings': {}})"
--
Segmentation fault (core dumped)
(.venv) jenkins@30f908325208:~/swh-environment/swh-search$ gdb python core
[...]
 
warning: core file may not match specified executable file.
[New LWP 5590]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `python3 -c from frozendict import frozendict; frozendict({'_uuid': '9c20cbe8-62'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x00007f9db196bd46 in frozendict_new_barebone (type=0x7f9db197b0e0 <PyFrozenDict_Type>) at /project/frozendict/src/3_7/frozendictobject.c:2214
2214	/project/frozendict/src/3_7/frozendictobject.c: No such file or directory.
(gdb) where
#0  0x00007f9db196bd46 in frozendict_new_barebone (type=0x7f9db197b0e0 <PyFrozenDict_Type>) at /project/frozendict/src/3_7/frozendictobject.c:2214
#1  _frozendict_new (use_empty_frozendict=1, kwds=0x0, args=<optimized out>, type=0x7f9db197b0e0 <PyFrozenDict_Type>) at /project/frozendict/src/3_7/frozendictobject.c:2255
#2  frozendict_new (type=0x7f9db197b0e0 <PyFrozenDict_Type>, args=<optimized out>, kwds=0x0) at /project/frozendict/src/3_7/frozendictobject.c:2290
#3  0x00000000005d9bd7 in _PyObject_FastCallKeywords ()
#4  0x000000000055274b in _PyEval_EvalFrameDefault ()
#5  0x000000000054bcc2 in _PyEval_EvalCodeWithName ()
#6  0x00000000005317ef in PyRun_StringFlags ()
#7  0x000000000063177d in PyRun_SimpleStringFlags ()
#8  0x0000000000654558 in ?? ()
#9  0x000000000065468e in _Py_UnixMain ()
#10 0x00007f9db1d7409b in __libc_start_main (main=0x4bc560 <main>, argc=3, argv=0x7ffd87efc938, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7ffd87efc928) at ../csu/libc-start.c:308
#11 0x00000000005e0e8a in _start ()
(gdb) quit
(.venv) jenkins@30f908325208:~/swh-environment/swh-search$ python3 -V -V
Python 3.7.3 (default, Jan 22 2021, 20:04:44)
[GCC 8.3.0]
(.venv) jenkins@30f908325208:~/swh-environment/swh-search$ pip3 show frozendict
WARNING: The directory '/home/jenkins/.cache/pip' or its parent directory is not owned or is not writable by the current user. The cache has been disabled. Check the permissions and owner of that directory. If executing pip with sudo, you should use sudo's -H flag.
Name: frozendict
Version: 2.1.2
Summary: A simple immutable dictionary
Home-page: https://github.com/Marco-Sulla/python-frozendict
Author: Marco Sulla
Author-email: marcosullaroma@gmail.com
License: LGPL v3
Location: /home/jenkins/swh-environment/.venv/lib/python3.7/site-packages
Requires:
Required-by: PyLD, swh.indexer

Here is the core dump: core.gz

This issue does not seem to occur outside Docker or on frozendict 2.1.1.

Thanks

@richvdh
Copy link

richvdh commented Dec 21, 2021

We noticed this as well.

We can also reproduce it outside the docker image, but it requires a recent version of pip so that you get the manylinux wheel. Starting from a basic debian10 install:

rav@debian10:~$ sudo apt install python3-venv
...
rav@debian10:~$ python3 -m venv env
rav@debian10:~$ env/bin/pip install -q --upgrade pip
rav@debian10:~$ env/bin/pip install frozendict
Collecting frozendict
  Downloading frozendict-2.1.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (173 kB)
     |████████████████████████████████| 173 kB 3.4 MB/s            
Installing collected packages: frozendict
Successfully installed frozendict-2.1.2
rav@debian10:~$ env/bin/python3 -c 'import frozendict; frozendict.frozendict()'
Segmentation fault

richvdh added a commit to matrix-org/synapse that referenced this issue Dec 21, 2021
... to work around breakage on buster
(Marco-Sulla/python-frozendict#41)
richvdh added a commit to matrix-org/synapse that referenced this issue Dec 21, 2021
@Marco-Sulla
Copy link
Owner

This is quite strange. Packages are automatically created and tested on every push. Furthermore I tested on my Lubuntu with python 3.7 and it works. I'll try to setup a VM with Debian 10 and see what happens.

@richvdh
Copy link

richvdh commented Dec 21, 2021

Yeah, I couldn't reproduce this on an Ubuntu with Python 3.7. Debian have been known to do odd things with their python binaries in the past.

@Marco-Sulla
Copy link
Owner

...Ubuntu is not a debian distro?

@richvdh
Copy link

richvdh commented Dec 21, 2021

That's pretty much what I'm saying, yes. I think this is specific to the Python 3.7 build in Debian 10.

@Marco-Sulla
Copy link
Owner

Marco-Sulla commented Dec 21, 2021

Ok, there are two macros that causes the segfaults:

  1. _PyObject_GC_TRACK and _PyObject_GC_UNTRACK. This is not a problem, since I can substitute them with the more canonical PyObject_GC_(Un)Track functions
  2. Py_TRASHCAN_SAFE_BEGIN - Py_TRASHCAN_SAFE_END. This is a problem. If I remove them from the deallocator, all seems to work happily. But for what I know these functions are needed to safely deallocate objects, because without them the deallocation can chain indefinitely.

Unluckily, I found very few about Py_TRASHCAN_SAFE_BEGIN - Py_TRASHCAN_SAFE_END, but, for what I see, they are used in C extensions:
https://cpp.hotexamples.com/examples/-/-/Py_TRASHCAN_SAFE_BEGIN/cpp-py_trashcan_safe_begin-function-examples.html

@Marco-Sulla
Copy link
Owner

Fixed by 0e46ac5

I released v2.1.3

Unluckily, the binaries generated by cibuildwheel does not work, so I removed them from the current and next releases. I have to investigate.
If someone wants the more performant C extension, it must download the sdist package (the .tar.gz) and install it with pip

@Marco-Sulla Marco-Sulla added the Status: Fixed Now it works! label Dec 22, 2021
@Marco-Sulla Marco-Sulla changed the title [BUG] v2.1.2 segfaults on Python 3.7 in Docker [BUG] v2.1.2 segfaults on Python 3.7 on Debian Dec 22, 2021
@anthrotype
Copy link

I'm not familiar with CPython API, but just wanted to point out that mypyc uses the same macro Py_TRASHCAN_SAFE_BEGIN in https://github.com/python/mypy/blob/master/mypyc/lib-rt/CPy.h#L508 and they managed to build manylinux wheels (see https://pypi.org/project/mypy/#files). Not sure if they use cibuildwheel or not, or if that's relevant.

@anthrotype
Copy link

well, of course, building the manylinux wheel successfully (as you also did) doesn't guarantee that mypyc won't segfault on debian python 3.7 (I haven't tested that). Anyway, sorry for the noise.

@Marco-Sulla
Copy link
Owner

Marco-Sulla commented Dec 22, 2021

@anthrotype Maybe the problem is I use a lot of not public and / or not stable APIs.

I started the C version of frozendict simply adding it in dictobject.c and compiling CPython with the new builtin object. My goal was to resurrect PEP 416. Since it seems that no one in the CPython team is interested, even if it's faster than dict in some jobs, I created the C extension. I leaved it with internal and not stable APIs on purpose, since my wish is that in a future it will added to Python.

@anthrotype
Copy link

good luck resurrecting the pep. Even if added to python 3.x itself, keeping the external package has advantages as it'd allow to use like a backport on python < 3.x

@Marco-Sulla
Copy link
Owner

In the current version, 2.2.0, I completely refactored the C code. Now the ABI compatibility should be reached. I tested it with a Debian VM.

Can someone confirm or deny this?

@Marco-Sulla Marco-Sulla reopened this Jan 15, 2022
@colenot
Copy link

colenot commented Jan 31, 2022

Had the bug 100% of the time with frozendict 2.1.2
Fixed as soon as I upgraded to 2.2.1

@Marco-Sulla
Copy link
Owner

Thank you for the report. Since now frozendict is completely covered by the testcase and I also tested it on a Debian VM, I can close this report :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Fixed Now it works! Type: Bug Something isn't working
Projects
None yet
Development

No branches or pull requests

5 participants