Summary: | memory leak in qtruby? (Qt::Socket) | ||
---|---|---|---|
Product: | [Developer tools] bindings | Reporter: | Caleb Tennis <caleb> |
Component: | general | Assignee: | kde-bindings |
Status: | RESOLVED UNMAINTAINED | ||
Severity: | normal | CC: | opensource |
Priority: | NOR | ||
Version: | unspecified | ||
Target Milestone: | --- | ||
Platform: | Gentoo Packages | ||
OS: | Linux | ||
Latest Commit: | Version Fixed In: |
Description
Caleb Tennis
2005-07-06 15:42:50 UTC
As a side note, on another machine where I use this class only for sending data ( using @socket.writeBlock() ), and not receiving, the memory usage does not grow at all. However, it seems that any time I receive a message from a Qt::Socket using the above mentioned methods, the memory usage grows. If I disconnect my readyRead() signal from the MessageReceivedSlot, and set my socket's readBufferSize to a maximum of 500, and run my test, the program memory does not grow. In other words, if I don't read data out of the socket buffer and let it fill up, the memory consumption stops. However, if I read the data out of the socket, the memory goes up. As an alternative test, I could use the readBlock method, but it takes a char * argument and I haven't figured out yet what to pass to it to get the data. A String doesn't seem to work nor does a Qt::ByteArray. This seems to work as a workaround: def MessageReceivedSlot bytes = [ ] while true c = @socket.getch break if c == -1 bytes << c end strings = bytes.pack("C*") strings.split("\n").each { |s| emit MessageSignal(s) unless s.empty? } end The code in comment #3 doesn't work, after 24 hours of running I'm getting a leak again. I can't seem to find anything leaky in the ObjectSpace of ruby itself. I dont' see the number or size of strings, arrays, and hashes getting any bigger. And I don't notice an increase in the number of Qt:: objects. I doubt that the leak is in Qt itself, so perhaps somewhere in the glue code (smoke?) in between the two? On Wednesday 06 July 2005 14:42, Caleb Tennis wrote: [bugs.kde.org quoted mail] Yes, you're right there is a leak for QString value return types. When a Smoke method returns a QString, it creates a new temporary QString with 'new', but never deletes it. I also tried 'QString*' and 'QString&' return types with readLine(), and those don't create a temporary string. virtual QString readLine(); Generates this code: void x_45(Smoke::Stack x) { // readLine() QString xret = this->QSocket::readLine(); x[0].s_voidp = (void*)new QString(xret); } virtual QString * readLine(); Becomes Generates this code: void x_45(Smoke::Stack x) { // readLine() QString* xret = this->QSocket::readLine(); x[0].s_voidp = (void*)xret; } virtual QString & readLine(); Generates this code: void x_45(Smoke::Stack x) { // readLine() QString& xret = this->QSocket::readLine(); x[0].s_voidp = (void*)&xret; } In Qt.cpp, the class to handle a return value has a boolean method called cleanup(), which is false. class MethodReturnValue : public Marshall { ... bool cleanup() { return false; } }; In handlers.cpp, the code to marshall a QString to a ruby string will only delete the QString if cleanup() is true: case Marshall::ToVALUE: { QString *s = (QString*)m->item().s_voidp; if(s) { if (s->isNull()) { *(m->var()) = Qnil; } else { *(m->var()) = rstringFromQString(s); } if(m->cleanup()) delete s; } else { *(m->var()) = Qnil; } } So the temporary QString from the 'QString readLine()' version of the method is never deleted. Either cleanup() should return true in MethodReturnValue, or the marshalling code should check if the QString is a value type and only delete it if it is. I looked at the PerlQt code in PerlQt-3.009 beta and it's just the same, and will have this leak too. -- Richard SVN commit 433005 by rdale: 2005-07-09 Richard Dale <Richard_Dale@tipitina.demon.co.uk> * When a Qt method returned a QString value type, such as: QString QSocket::readLine() A temporary QString was being created that wasn't deleted and caused a memory leak. Fixes problem reported by Caleb Tennis. CCBUGS:108650 M +7 -0 ChangeLog M +1 -1 rubylib/qtruby/handlers.cpp --- trunk/KDE/kdebindings/qtruby/ChangeLog #433004:433005 @@ -1,3 +1,10 @@ +2005-07-09 Richard Dale <Richard_Dale@tipitina.demon.co.uk> + + * When a Qt method returned a QString value type, such as: + QString QSocket::readLine() + A temporary QString was being created that wasn't deleted and caused a + memory leak. Fixes problem reported by Caleb Tennis. + 2005-06-28 Richard Dale <Richard_Dale@tipitina.demon.co.uk> * Improved display of Qt::Enums in the KDevelop debugger. With a p --- trunk/KDE/kdebindings/qtruby/rubylib/qtruby/handlers.cpp #433004:433005 @@ -863,7 +863,7 @@ } else { *(m->var()) = rstringFromQString(s); } - if(m->cleanup()) + if(m->cleanup() || m->type().isStack()) delete s; } else { *(m->var()) = Qnil; I've patched my source, recompiled, but now it dies: tc@supercell ~/subversion/ruby/unico $ ruby unico.rb /usr/lib/ruby/site_ruby/1.8/gina/client.rb:76: [BUG] Segmentation fault ruby 1.8.2 (2004-12-25) [i686-linux] Aborted (Line 76 is my line where I call a method that returns a QString). Removing the patch and recompiling, the program runs fine again, but with the memory leak. SVN commit 434490 by rdale: * Added example programs for client/server programming with Qt::Socket and associated classes. client.rb illustrates current bugs in QtRuby * Qt::Socket.canReadLine() always returns true * Qt::readLine() seg faults when called a second time * A memory leak and seg faulting problems like the above were reported by Caleb Tennis CCBUGS: 108650 M +9 -0 ChangeLog A rubylib/examples/network (directory) A rubylib/examples/network/clientserver (directory) A rubylib/examples/network/clientserver/client (directory) A rubylib/examples/network/clientserver/client/client.rb A rubylib/examples/network/clientserver/server (directory) A rubylib/examples/network/clientserver/server/server.rb --- trunk/KDE/kdebindings/qtruby/ChangeLog #434489:434490 @@ -1,3 +1,12 @@ +2005-07-14 Richard Dale <Richard_Dale@tipitina.demon.co.uk> + + * Added example programs for client/server programming with Qt::Socket + and associated classes. client.rb illustrates current bugs in QtRuby + * Qt::Socket.canReadLine() always returns true + * Qt::readLine() seg faults when called a second time + * A memory leak and seg faulting problems like the above were reported + by Caleb Tennis + 2005-07-09 Richard Dale <Richard_Dale@tipitina.demon.co.uk> * When a Qt method returned a QString value type, such as: SVN commit 434751 by rdale: * Qt::Socket started working correctly when I and regenerated and rebuilt my Smoke library. Before then it was calling the wrong version of QSocket::at() for some reason, and wasn't discarding bytes that had already been read. * Removed comment from the client.rb example about Qt::Socket.canReadLine always returning true now it works. CCBUGS: 108650 M +9 -0 ChangeLog M +0 -2 rubylib/examples/network/clientserver/client/client.rb --- trunk/KDE/kdebindings/qtruby/ChangeLog #434750:434751 @@ -1,3 +1,12 @@ +2005-07-15 Richard Dale <Richard_Dale@tipitina.demon.co.uk> + + * Qt::Socket started working correctly when I and regenerated and rebuilt + my Smoke library. Before then it was calling the wrong version of + QSocket::at() for some reason, and wasn't discarding bytes that had + already been read. + * Removed comment from the client.rb example about Qt::Socket.canReadLine + always returning true now it works. + 2005-07-14 Richard Dale <Richard_Dale@tipitina.demon.co.uk> * Added example programs for client/server programming with Qt::Socket --- trunk/KDE/kdebindings/qtruby/rubylib/examples/network/clientserver/client/client.rb #434750:434751 @@ -59,8 +59,6 @@ def socketReadyRead() # read from the server - # This loops forever in QtRuby because 'canReadLine()' - # is alway true while @socket.canReadLine() do @infoText.append( @socket.readLine() ) end Thank you for the bug report. As this report hasn't seen any changes in 5 years or more, we ask if you can please confirm that the issue still persists. If this bug is no longer persisting or relevant please change the status to resolved. QtRuby only existed for Qt4 and Korundum, which never got updated for 5.x This is unmaintained and any effort towards QtRuby for Qt6 will be from scratch. Therefore, closing this ticket |