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

client tests spuriously segfault and or fail #1880

Open
legoktm opened this issue Feb 29, 2024 · 2 comments
Open

client tests spuriously segfault and or fail #1880

legoktm opened this issue Feb 29, 2024 · 2 comments

Comments

@legoktm
Copy link
Member

legoktm commented Feb 29, 2024

Description

A tracking issue to discuss and investigate that our client tests regularly flakily segfault and fail. The failures usually error similar to RuntimeError: wrapped C/C++ object of type QPushButton has been deleted.

E.g.:

FAILED tests/gui/conversation/export/test_print_transcript_dialog.py::test_PrintTranscriptDialog_init - RuntimeError: wrapped C/C++ object of type QPushButton has been deleted
FAILED tests/gui/conversation/export/test_print_dialog.py::test_PrintDialog_init_sanitizes_filename - RuntimeError: wrapped C/C++ object of type QPushButton has been deleted
legoktm added a commit that referenced this issue Feb 29, 2024
These tests are pretty quick that they don't really benefit from xdist.
Plus not all of our tests are threadsafe (e.g. the ones that call
locale.setlocale()), so if there's no real need for parallelization,
let's skip it.

Refs #1880.
@legoktm
Copy link
Member Author

legoktm commented Feb 29, 2024

I've been seeing a few QThread: Destroyed while thread is still running segfaults while fixing the functional tests to use the proxy v2, and came across https://blog.xmatthias.com/post/pytest-debug-segfault/ which suggested enabling Python's faulthandler and disabling pytest's. So now I have this stacktrace:

QThread: Destroyed while thread is still running
Fatal Python error: Aborted

Thread 0x000071bb773ff6c0 (most recent call first):
  File "/usr/lib64/python3.10/subprocess.py", line 1141 in communicate
  File "/usr/lib64/python3.10/subprocess.py", line 505 in run
  File "/usr/lib64/python3.10/subprocess.py", line 421 in check_output
  File "/home/user/github/freedomofpress/securedrop-client/client/securedrop_client/sdk/__init__.py", line 117 in _rpc_target
  File "/home/user/github/freedomofpress/securedrop-client/client/securedrop_client/sdk/__init__.py", line 148 in _send_json_request
  File "/home/user/github/freedomofpress/securedrop-client/client/tests/sdk/utils.py", line 66 in _send_json_request
  File "/home/user/github/freedomofpress/securedrop-client/client/securedrop_client/sdk/__init__.py", line 847 in logout
  File "/home/user/github/freedomofpress/securedrop-client/client/securedrop_client/logic.py", line 121 in call_api

Thread 0x000071bb76bfe6c0 (most recent call first):
  File "/usr/lib64/python3.10/subprocess.py", line 1141 in communicate
  File "/usr/lib64/python3.10/subprocess.py", line 505 in run
  File "/usr/lib64/python3.10/subprocess.py", line 421 in check_output
  File "/home/user/github/freedomofpress/securedrop-client/client/securedrop_client/sdk/__init__.py", line 117 in _rpc_target
  File "/home/user/github/freedomofpress/securedrop-client/client/securedrop_client/sdk/__init__.py", line 148 in _send_json_request
  File "/home/user/github/freedomofpress/securedrop-client/client/tests/sdk/utils.py", line 66 in _send_json_request
  File "/home/user/github/freedomofpress/securedrop-client/client/securedrop_client/sdk/__init__.py", line 576 in download_submission
  File "/home/user/github/freedomofpress/securedrop-client/client/securedrop_client/api_jobs/downloads.py", line 318 in call_download_api
  File "/home/user/github/freedomofpress/securedrop-client/client/securedrop_client/api_jobs/downloads.py", line 148 in _download
  File "/home/user/github/freedomofpress/securedrop-client/client/securedrop_client/api_jobs/downloads.py", line 136 in call_api
  File "/home/user/github/freedomofpress/securedrop-client/client/securedrop_client/api_jobs/base.py", line 77 in _do_call_api
  File "/home/user/github/freedomofpress/securedrop-client/client/securedrop_client/queue.py", line 232 in process

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

Extension modules: yaml._yaml, PyQt5.QtCore, PyQt5.QtGui, PyQt5.QtWidgets, sqlalchemy.cprocessors, sqlalchemy.cutils, sqlalchemy.cresultproxy, PyQt5.QtSvg, markupsafe._speedups, PyQt5.QtTest (total: 10)
/usr/bin/xvfb-run: line 181: 107302 Aborted                 (core dumped) DISPLAY=:$SERVERNUM XAUTHORITY=$AUTHFILE "$@" 2>&1
make: *** [Makefile:82: test-functional] Error 1

Which indicates that the background sync job was (improperly?) terminated at the end of the test run while it was in progress and that triggered the segfault.

@rocodes
Copy link
Contributor

rocodes commented Feb 29, 2024

Nice one!

I implemented some logic that may or may not be relevant on the wizard - basically connecting to the appwindow's finished signal, which is fired when the app is closed (although not when it's closed improperly in a crash) and killing in my case a QProcess not a QThread.

# Sends cleanup signal to export if wizard is closed or completed.
# (Avoid orphaned QProcess)
self.finished.connect(self.export.end_process)

and

def end_process(self) -> None:
"""
Tell QProcess to quit if it hasn't already.
Connected to the ExportWizard's `finished` signal, which fires
when the dialog is closed, cancelled, or finished.
"""
self._cleanup_tmpdir()
logger.debug("Terminate process")
if self.process is not None and not self.process.waitForFinished(50):
self.process.terminate()

legoktm added a commit that referenced this issue Mar 5, 2024
These tests are pretty quick that they don't really benefit from xdist.
Plus not all of our tests are threadsafe (e.g. the ones that call
locale.setlocale()), so if there's no real need for parallelization,
let's skip it.

Refs #1880.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants