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