pycups icon indicating copy to clipboard operation
pycups copied to clipboard

Call getJobs in thread: PyEval_RestoreThread: NULL tstate

Open anxuae opened this issue 3 years ago • 3 comments

Calling the function getJobs in a thread crash the application. It seems that some functions are not thread-safe. How can I handle it?

Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/lib/python3.7/threading.py", line 917, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.7/threading.py", line 865, in run
    self._target(*self._args, **self._kwargs)
  File "test3.py", line 19, in print_jobs
    "job-uri", "job-state"])))
cups.IPPError: (1280, 'No such file or directory')

Fatal Python error: PyEval_RestoreThread: NULL tstate

Current thread 0x76f6cad0 (most recent call first):
  File "test3.py", line 34 in <module>
Abandon

I'm using the following script to reproduce it:

import threading
import time
import cups
import os.path as osp

FILENAME = "test3.py"
RUN = True

def print_jobs():
    time.sleep(1)
    while RUN == True:
        time.sleep(0.1)
        print("Jobs count:", len(conn.getJobs(my_jobs=True, requested_attributes=["job-id", "job-name",
                                                                                  "job-uri", "job-state"])))

THREAD = threading.Thread(target=print_jobs)
THREAD.daemon = True

# Create a CUPS connection
conn = cups.Connection()
name = conn.getDefault()

try:
    THREAD.start()
    while True:
        time.sleep(0.1)
        conn.printFile(name, FILENAME, osp.basename(FILENAME), {})

except KeyboardInterrupt:
    print("Stop")

finally:
    print("Cancel tasks")
    RUN = False
    conn.cancelAllJobs(name)
    THREAD.join()

anxuae avatar Aug 24 '22 20:08 anxuae

Hi,

I've tried to reproduce the issue with your script, but with no luck... are you able to get me C backtraces (the pycups is a module for python written in C) for both issues you see in pibooth?

The first is the one you experience with your script, and the other is Fatal Python error: PyEval_RestoreThread: the function must be called with the GIL held, but the GIL is released (the current Python thread state is NULL).

zdohnal avatar Aug 31 '22 10:08 zdohnal

I've tried to get more logs by exporting those variables:

PYTHONTRACEMALLOC=1
PYTHONTHREADDEBUG=1
PYTHONFAULTHANDLER=1

But I can't get more trace info. Can you tell me how can I get C backtraces ?

Note : I'm using pycups==2.0.1

anxuae avatar Sep 08 '22 17:09 anxuae

When I got a similar bug about incorrect thread handling, python3 process itself got segfault and generated coredump, where I could see thread conflict causing the crash. Does python3 process running pibooth get SIGSEGV as well? If it does, you can get the backtrace from its coredump.

zdohnal avatar Sep 12 '22 10:09 zdohnal