Segmentation Fault With QProcess Manager

Hello,
I tried to play with the qprocess_manager, but I’ve been getting TypeError:

Traceback (most recent call last):
File “~Document/tmp/concurrent/qprocess_manager.py”, line 121, in
return lambda *args: target(job_id, *args)
TypeError: done() missing 1 required positional argument: ‘exit_status’

After I removed ‘exit_status’ from ‘done’ function, it seemed to execute fine, but then the program kept crashing and returned ‘Segmentation fault’.
wonder if it’s possible to avoid this from happening :frowning:

Thanks so much

Ren

Hi @Ren-Hsien_Hsu welcome to the forum!

The first error is actually a bit weird, since we attach it to the finished signal, it should be receiving the exit status, see QProcess Class | Qt Core 5.15.7

First, does your done method have the first self parameter? Since it’s an object method, it needs this to receive the object.

    def done(self, job_id, exit_code, exit_status):
        """
        Task/worker complete. Remove it from the active workers
        dictionary. We leave it in worker_state, as this is used to
        to display past/complete workers too.
        """
        del self._jobs[job_id]
        self.layoutChanged.emit()

If it does then we’ve got something weird going on. I’d try creating another method on your class…

def dump(self, *args):
    print(args)

…to print out everything that is being sent to the done method. You can then hook it up e.g.

p.finished.connect(fwd_signal(self.dump))

(remove the connection to self.done temporarily or it might crash before we see the print. When run there should be 3 variables, the job_id, the exit code, and exit status. Can you post here what you see – and also any changes to the code – should be possible to debug what’s going on from that.

The segmentation fault is even weirder, perhaps you’re ending up with a reference to a destroyed object in your job table (job_id is pointing to something it shouldn’t be).

Hey Marin,
Thanks so much for your reply!!
I didn’t change the code at all, just simply run it sample one.

Here are the output from piping finished to dump
(‘ce89ff6113c940d98c78e8a4392eb365’, 0)
(‘8285dc34ff4546e8a1898799aa53978e’, 0)
(‘8202ec8824fb460bb1993c036c8f8497’, 0)
(‘2c3af20c5c8c4bbdb2648aef337dbde4’, 0)

it seems to be the uuid and the exit_status, somehow the exit_code didn’t come thought :thinking:

That’s weird, but there can be differences in what signals emit between PyQt5/PySide2 (and sometimes different versions of each). Can you let me know which version you’re using?

Since it’s not sending the exit_code through, what happens if you remove that parameter from the handler? e.g.

def done(self, job_id, exit_status):

Since there is nothing in that method that depends on either parameter, you can also discard them by assigning to *args, e.g.

def done(self, job_id, *args):

This will work no matter how many values are sent through.

Hi Martin,

I am running into the exactly same error as Ren-Hsien_Hsu when I run the example code as is. I also tried your suggestions to replace
def done(self, job_id, exit_code, exit_status): with def done(self, job_id, *args):
but as soon as I hit the “Run a command” button I see Segmentation fault (core dumped)

My Python version is Python 3.10.4 on linux and
here’s the PySide2 version

import PySide2 as p
>>> p.__version__
'5.15.2.1'

and here is the output from dump function

('fde34cdd5d5a4042b19000e9b810e0bd', 2)
('769b9e3189524901ab9f347924c0ea93', 2)
('16c73b7ba6834552a8d0a44e8623d5e7', 2)
('f55b0b88093f4f1491923c78a08f3a5e', 2)

Any help is appreciated.

Thanks,
Amit

Of course, I had to find the answer right after I posted the question.

I placed my dummy_script right beside the qprocess_manager.py file assuming that it will find the dummy_script.py file on its own :smiley:

All I had to do was provide the absolute path to dummy_script.py at

self.job.execute(
            "python",
            ["/full/path/to/file/dummy_script.py"],

BUT I still get

qprocess_manager.py", line 110, in <lambda>
    return lambda *args: target(job_id, *args)
TypeError: JobManager.done() missing 1 required positional argument: 'exit_status'

I guess need more reading on how to resolve it and see whats going wrong.

Well, Thanks again for all the awesome content in your book.
Cheers,
Amit

I am running into one issue and not been able to resolve it. If I delete the task/worker from active workers dict, it crashes my Qt App and the parent app I call it from.

    def done(self, job_id, *args):
        del self._jobs[job_id]
        self.layoutChanged.emit()

Do I have to use it?
I also noticed that when I wasn’t deleting it, my processes would complete but wouldn’t close. I could see them all in the system resource manager unless I killed my DCC through which I ran my Qt app. Closing just the Qt app wouldn’t close the command line processes I am running through QProcess.