Segmentation fault for scoped references with multiple QNetworkReply objects
Phil Thompson
phil at riverbankcomputing.com
Tue Aug 13 12:05:04 BST 2024
On 12/08/2024 21:33, ekhumoro wrote:
> On 12/08/2024 10:02, Phil Thompson wrote:
>> First off, I can't reproduce the problem - even if I double the number
>> of URLs to 200.
>>
>> However looking at the reply object using sip.dump() shows it has no
>> parent wrapped object whereas the docs for
>> QNetworkReply::manager() state that the manager is the reply's parent.
>> Adding a /Transfer/ annotation to
>> QNetworkManager::get() fixes this - but I have no idea if this has any
>> effect on your test case.
>
> I also tried the script, and was able to reproduce the problem on
> Linux using Python-3.12.4 with PyQt-5.15.11. For me,
> the test-script also usually dumps core after 10-20 replies.
>
> I found the problem can be "fixed" in a number of ways. The simplest is
> to add:
>
> self.nam.setAutoDeleteReplies(True)
>
> Alternatively, disconnecting all the slots inside the closure also
> works:
>
> def testWithReference():
> reply.finished.disconnect()
>
> as does explicitly transferring ownership via sip:
>
> reply = self.nam.get(QNetworkRequest(url))
> sip.transferto(reply, self.nam)
>
> However, it does seems to be the closure cell-reference itself that is
> causing the problem. Keeping an additional
> reference to all the closure slots also "fixes" the problem, as does
> avoiding the cell-reference by using a default
> argument (i.e. def testWithReference(reply=reply)).
>
> Does this indicate an issue with the internal proxy-slot created for
> the closure? As it is, the unmodified script never
> deletes any of the QNetworkReply objects, and none of the slots
> connected to them are ever removed. What could be
> happening with that cell-reference? If nothing is being deleted (or so
> it seems), why does transferring ownership help?
Without the new /Transfer/ the reply Python objects were being garbage
collected when they went out of scope (but the C++ instances were still
alive).
Now the Python object should have the same lifecycle as the C++
instances (ie. get destroyed when the access manager gets destroyed).
Phil
More information about the PyQt
mailing list