-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Tests run when called by name but seg fault when part of a collection #3672
Comments
GitMate.io thinks possibly related issues are #3251 (Warnings not captured during test collection), #2188 (Test runner hangs during collection with doctest-modules and mock.call in module), #1521 (High memory usage if tests called by test case name), #337 (there is no warning when tests have the same name), and #1337 (Segmentation fault in tests). |
Hi @mvahowe, Unfortunately it is very hard to suggest something at this point because we can't really see all the code. It might be a bug in pytest, but I would actually guess it is some bad interaction with your code. The only hint I can give is to try to isolate the problem in a minimal reproducible problem; that will help you find the problem in your code or isolate the bug in pytest so we can fix it. |
Thanks for this. A colleague of mine got this, from OS X. (Another colleague failed to reproduce the seg fault with Windows):
From this it looks to us like the issue is something along the lines of double deallocation within the lxml module, which uses the libxml2 library under the hood. libxml2 internals are famously murky. I'll try to come up with a simpler test case but I'm not optimistic. What I would say is that whatever is happening depends, in a reproducible way, on how the test is called. It doesn't happen if the test is called directly in isolation, it doesn't happen if the file containing the failing test is called with other files, it does occur if all the tests in the file are run, of if the test is called in isolation via a mark decorator. This suggests to me that there's something different about how cleanup occurs. Given that there are lots of persistent gevent threads in our code, could it be something to do with how threads are shut down in different cases? |
Also, I don't think sharing all our sprawling codebase here is sensible, but if someone has time to look into the problem we could give them access to our repo. We're getting identical behaviour with Linux and OS X so I'm confident the problem can be reproduced. |
Seems like a good venue for investigation. Keep in mind that pytest itself doesn't know about gevent or attempts to close threads in anyway, so if there's threads being shutdown they are not being shutdown by pytest.
I agree, probably people won't be able to allocate the necessary time to understand the entire code base. |
I had segfault too and I think it was due to updating of python 3.6.6 to 3.7.0, because application worked just fine with python 3.6.6. |
Same here. Python version has no influence though. Running individual files is OK. Running them together segfaults. |
Closing this for now as it seems this is not related to pytest per-se. Will be happy to reopen if more information comes to light. 👍 |
Getting same issue. I was recently running a job in Python and ctrl+c killed it. I don't know if maybe some memory allocation issue arose because of that abrupt termination? Just throwing hypotheses out there. |
FWIW this seems to me to be a pytest issue because it happens in the pytest context but not in other contexts. If there are certain types of code that seg fault with pytest but not elsewhere, that's either a bug that should be fixed or a constraint that should be documented. |
This code, when running under python works just fine: from lxml import html
def test_():
pass
if __name__ == "__main__":
test_() Run this with pytest, and it segfaults. I can't say this is pytest issue per se, but It does feels like it. stracing the segafault:
Anyone has any insights into that ? |
FWIW, my crashing code above made heavy use of lxml. |
Thanks. I guess for future readers, while pytest might indeed be the issue, it's better to start off with a clean venv, and see if there is any specific dependency that is the issue. |
Shouldn't faulthandler provide more inside? (i.e. a Python traceback). |
@AvnerCohen its possible that your segfault is only hit when certain preconditions are met, as far as i i can tell, snapshot-test does setup/clean out sys.modules details, its thinkable that a unexpected gc happens due to loosing/reimporting a module, thus its possible that it needs a blacklist for toplevels not to touch |
I'll try to provide all the info I can here, let me know if anything is missing. Given this basic test file: from lxml import html
def test_():
pass
if __name__ == "__main__":
test_() If I run this with pytest, here is the output: =========================================================================================== test session starts ============================================================================================
platform linux -- Python 3.7.4, pytest-5.2.2, py-1.8.0, pluggy-0.13.0
rootdir: /opt/app
collected 1 item
moshe.py . [100%]
============================================================================================ 1 passed in 0.02s ============================================================================================= Once I also install snapshottest ( $ pytest moshe.py
=========================================================================================== test session starts ============================================================================================
platform linux -- Python 3.7.4, pytest-5.2.2, py-1.8.0, pluggy-0.13.0
rootdir: /opt/app
plugins: snapshottest-0.5.1
collecting ... Fatal Python error: Segmentation fault
Current thread 0x00007f933f78f740 (most recent call first):
File "<frozen importlib._bootstrap>", line 219 in _call_with_frames_removed
File "<frozen importlib._bootstrap_external>", line 1043 in create_module
File "<frozen importlib._bootstrap>", line 583 in module_from_spec
File "<frozen importlib._bootstrap>", line 670 in _load_unlocked
File "<frozen importlib._bootstrap>", line 967 in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 983 in _find_and_load
File "<frozen importlib._bootstrap>", line 219 in _call_with_frames_removed
File "<frozen importlib._bootstrap>", line 1035 in _handle_fromlist
File "/opt/app/moshe/lib/python3.7/site-packages/lxml/html/__init__.py", line 53 in <module>
File "<frozen importlib._bootstrap>", line 219 in _call_with_frames_removed
File "<frozen importlib._bootstrap_external>", line 728 in exec_module
File "<frozen importlib._bootstrap>", line 677 in _load_unlocked
File "<frozen importlib._bootstrap>", line 967 in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 983 in _find_and_load
File "<frozen importlib._bootstrap>", line 219 in _call_with_frames_removed
File "<frozen importlib._bootstrap>", line 1035 in _handle_fromlist
File "/opt/app/moshe.py", line 1 in <module>
File "/opt/app/moshe/lib/python3.7/site-packages/_pytest/assertion/rewrite.py", line 142 in exec_module
File "<frozen importlib._bootstrap>", line 677 in _load_unlocked
File "<frozen importlib._bootstrap>", line 967 in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 983 in _find_and_load
File "/opt/app/moshe/lib/python3.7/site-packages/py/_path/local.py", line 701 in pyimport
File "/opt/app/moshe/lib/python3.7/site-packages/_pytest/python.py", line 501 in _importtestmodule
File "/opt/app/moshe/lib/python3.7/site-packages/_pytest/python.py", line 433 in _getobj
File "/opt/app/moshe/lib/python3.7/site-packages/_pytest/python.py", line 256 in obj
File "/opt/app/moshe/lib/python3.7/site-packages/_pytest/python.py", line 449 in _inject_setup_module_fixture
File "/opt/app/moshe/lib/python3.7/site-packages/_pytest/python.py", line 436 in collect
File "/opt/app/moshe/lib/python3.7/site-packages/_pytest/runner.py", line 256 in <lambda>
File "/opt/app/moshe/lib/python3.7/site-packages/_pytest/runner.py", line 229 in from_call
File "/opt/app/moshe/lib/python3.7/site-packages/_pytest/runner.py", line 256 in pytest_make_collect_report
File "/opt/app/moshe/lib/python3.7/site-packages/pluggy/callers.py", line 187 in _multicall
File "/opt/app/moshe/lib/python3.7/site-packages/pluggy/manager.py", line 86 in <lambda>
File "/opt/app/moshe/lib/python3.7/site-packages/pluggy/manager.py", line 92 in _hookexec
File "/opt/app/moshe/lib/python3.7/site-packages/pluggy/hooks.py", line 286 in __call__
File "/opt/app/moshe/lib/python3.7/site-packages/_pytest/runner.py", line 375 in collect_one_node
File "/opt/app/moshe/lib/python3.7/site-packages/_pytest/main.py", line 703 in genitems
File "/opt/app/moshe/lib/python3.7/site-packages/_pytest/main.py", line 478 in _perform_collect
File "/opt/app/moshe/lib/python3.7/site-packages/_pytest/main.py", line 439 in perform_collect
File "/opt/app/moshe/lib/python3.7/site-packages/_pytest/main.py", line 246 in pytest_collection
File "/opt/app/moshe/lib/python3.7/site-packages/pluggy/callers.py", line 187 in _multicall
File "/opt/app/moshe/lib/python3.7/site-packages/pluggy/manager.py", line 86 in <lambda>
File "/opt/app/moshe/lib/python3.7/site-packages/pluggy/manager.py", line 92 in _hookexec
File "/opt/app/moshe/lib/python3.7/site-packages/pluggy/hooks.py", line 286 in __call__
File "/opt/app/moshe/lib/python3.7/site-packages/_pytest/main.py", line 236 in _main
File "/opt/app/moshe/lib/python3.7/site-packages/_pytest/main.py", line 193 in wrap_session
File "/opt/app/moshe/lib/python3.7/site-packages/_pytest/main.py", line 230 in pytest_cmdline_main
File "/opt/app/moshe/lib/python3.7/site-packages/pluggy/callers.py", line 187 in _multicall
File "/opt/app/moshe/lib/python3.7/site-packages/pluggy/manager.py", line 86 in <lambda>
File "/opt/app/moshe/lib/python3.7/site-packages/pluggy/manager.py", line 92 in _hookexec
File "/opt/app/moshe/lib/python3.7/site-packages/pluggy/hooks.py", line 286 in __call__
File "/opt/app/moshe/lib/python3.7/site-packages/_pytest/config/__init__.py", line 90 in main
File "/opt/app/moshe/bin/pytest", line 8 in <module>
Segmentation fault Happy to provide anything else if this can be of help. |
Please try if it also crashes with |
It does.
|
Then try what py does there manually: https://github.com/pytest-dev/py/blob/34f716fe1fb4df9a5257b5f640ebb8a71e10aa88/py/_path/local.py#L689-L701 (to get pytest / your tests out of the equation / try to reproduce it without). |
@blueyed Sorry, not sure I follow your exact suggested test here. The recreation of this is very simple.
|
Not listed for Python 3.7. (have only later seen that you have it with py37)
Is the |
Thanks for the help @blueyed I did notice this did not occur on an alpine-python, but is present on this centos based docker. |
Hi,
I'm running the python3-pytest package of Ubuntu 18.04, v3.3.2-2, with cov-2.5.1 from a package and faulthandler-1.5.0 from pip. (I'm not using a virtual environment.) The application I am testing makes extensive use of gevent. This has worked well until now but today, when refactoring my tests to move the startup/teardown code to a module, I'm getting seg faults.
I've tried to isolate the issue, and it seems to be something around pytest teardown after the last test in a collection, ie
ie
The test above looks like this:
and two of the fixtures look like this:
This looks to me like a bug in pytest, since the test behaviour varies according to how it is invoked. But I'm quite willing to believe that there's also something evil in my code - I just have no clue how to find it.
All suggestions welcome.
The text was updated successfully, but these errors were encountered: