Als ich meine Anwendung auf Speicherlecks prüfte, stieß ich auf ein sehr eigenartiges Verhalten von Valgrind. Soweit ich verstehe, sieht er den folgenden CodeValgrind sieht Löschen in der Zeile, die sagt
virtual ServiceHandler* createServiceHandler(StreamSocket& socket)
/// Create and initialize a new ServiceHandler instance.
///
/// Subclasses can override this method.
{
return new ServiceHandler(socket, *_pReactor);
}
als ein Ort, wo ich sowohl zuweisen und Speicher freigeben. Dieser Code ist Teil der POCO-Bibliothek und kann gefunden werden here. Im Folgenden finden Sie ein Beispiel für das Protokoll von valgrind, das besagt, dass die bereitgestellte return-Anweisung sowohl zu new als auch zu delete führt.
Invalid read of size 8
==9764== at 0x1C63DC: Poco::Net::Socket::operator!=(Poco::Net::Socket const&) const (Socket.h:340)
==9764== by 0x1C2A5C: SocketHandler::onReadableNotification(Poco::AutoPtr<Poco::Net::ReadableNotification> const&) (SocketHandler.cpp:67)
==9764== by 0x1CA0DF: Poco::NObserver<SocketHandler, Poco::Net::ReadableNotification>::notify(Poco::Notification*) const (NObserver.h:88)
==9764== by 0x5C04077: Poco::NotificationCenter::postNotification(Poco::AutoPtr<Poco::Notification>) (NotificationCenter.cpp:78)
==9764== by 0x579F422: Poco::Net::SocketNotifier::dispatch(Poco::Net::SocketNotification*) (SocketNotifier.cpp:80)
==9764== by 0x579C0DC: Poco::Net::SocketReactor::dispatch(Poco::AutoPtr<Poco::Net::SocketNotifier>&, Poco::Net::SocketNotification*) (SocketReactor.cpp:282)
==9764== by 0x579BEE1: Poco::Net::SocketReactor::dispatch(Poco::Net::Socket const&, Poco::Net::SocketNotification*) (SocketReactor.cpp:258)
==9764== by 0x579B5F4: Poco::Net::SocketReactor::run() (SocketReactor.cpp:114)
==9764== by 0x5C50406: Poco::(anonymous namespace)::RunnableHolder::run() (Thread.cpp:57)
==9764== by 0x5C500E0: Poco::ThreadImpl::runnableEntry(void*) (Thread_POSIX.cpp:349)
==9764== by 0x6D20493: start_thread (pthread_create.c:333)
==9764== by 0x78BBAFE: clone (clone.S:97)
==9764== Address 0x10c8f908 is 40 bytes inside a block of size 352 free'd
==9764== at 0x4C2D2DB: operator delete(void*) (vg_replace_malloc.c:576)
==9764== --> by 0x19D1CD: Poco::Net::SocketAcceptor<SocketHandler>::createServiceHandler(Poco::Net::StreamSocket&) (SocketAcceptor.h:166)
==9764== by 0x19B3E3: Poco::Net::SocketAcceptor<SocketHandler>::onAccept(Poco::Net::ReadableNotification*) (SocketAcceptor.h:157)
==9764== by 0x1A1385: Poco::Observer<Poco::Net::SocketAcceptor<SocketHandler>, Poco::Net::ReadableNotification>::notify(Poco::Notification*) const (Observer.h:86)
==9764== by 0x5C04077: Poco::NotificationCenter::postNotification(Poco::AutoPtr<Poco::Notification>) (NotificationCenter.cpp:78)
==9764== by 0x579F422: Poco::Net::SocketNotifier::dispatch(Poco::Net::SocketNotification*) (SocketNotifier.cpp:80)
==9764== by 0x579C0DC: Poco::Net::SocketReactor::dispatch(Poco::AutoPtr<Poco::Net::SocketNotifier>&, Poco::Net::SocketNotification*) (SocketReactor.cpp:282)
==9764== by 0x579BEE1: Poco::Net::SocketReactor::dispatch(Poco::Net::Socket const&, Poco::Net::SocketNotification*) (SocketReactor.cpp:258)
==9764== by 0x579B5F4: Poco::Net::SocketReactor::run() (SocketReactor.cpp:114)
==9764== by 0x5C50406: Poco::(anonymous namespace)::RunnableHolder::run() (Thread.cpp:57)
==9764== by 0x5C500E0: Poco::ThreadImpl::runnableEntry(void*) (Thread_POSIX.cpp:349)
==9764== by 0x6D20493: start_thread (pthread_create.c:333)
==9764== Block was alloc'd at
==9764== at 0x4C2C21F: operator new(unsigned long) (vg_replace_malloc.c:334)
==9764== --> by 0x19D19E: Poco::Net::SocketAcceptor<SocketHandler>::createServiceHandler(Poco::Net::StreamSocket&) (SocketAcceptor.h:166)
==9764== by 0x19B3E3: Poco::Net::SocketAcceptor<SocketHandler>::onAccept(Poco::Net::ReadableNotification*) (SocketAcceptor.h:157)
==9764== by 0x1A1385: Poco::Observer<Poco::Net::SocketAcceptor<SocketHandler>, Poco::Net::ReadableNotification>::notify(Poco::Notification*) const (Observer.h:86)
==9764== by 0x5C04077: Poco::NotificationCenter::postNotification(Poco::AutoPtr<Poco::Notification>) (NotificationCenter.cpp:78)
==9764== by 0x579F422: Poco::Net::SocketNotifier::dispatch(Poco::Net::SocketNotification*) (SocketNotifier.cpp:80)
==9764== by 0x579C0DC: Poco::Net::SocketReactor::dispatch(Poco::AutoPtr<Poco::Net::SocketNotifier>&, Poco::Net::SocketNotification*) (SocketReactor.cpp:282)
==9764== by 0x579BEE1: Poco::Net::SocketReactor::dispatch(Poco::Net::Socket const&, Poco::Net::SocketNotification*) (SocketReactor.cpp:258)
==9764== by 0x579B5F4: Poco::Net::SocketReactor::run() (SocketReactor.cpp:114)
==9764== by 0x5C50406: Poco::(anonymous namespace)::RunnableHolder::run() (Thread.cpp:57)
==9764== by 0x5C500E0: Poco::ThreadImpl::runnableEntry(void*) (Thread_POSIX.cpp:349)
==9764== by 0x6D20493: start_thread (pthread_create.c:333)
Ich habe -->
zu dem interessanten Teil hinzugefügt.
Sobald dies passiert, beobachte ich mehr von ähnlichen Protokollen, da das Objekt scheint nicht zugeordnet werden. Die App funktioniert für einige Zeit korrekt, bevor ich diesen Fehler sehe und es ist der erste Fehler. Ich denke, dass dieser Fehler auftreten kann, wenn der Socket nicht nett ist.
I valgrind die App mit dem folgenden Befehl
valgrind --vgdb=yes --vgdb-error=0 app
und Verwendung gdb weiter den Code zu untersuchen.
Meine Frage lautet:
- Warum sagt die valgrind mir die bereitgestellten Code neu und löschen ruft?
- Wird dieses Verhalten lokal von diesem Code verursacht, oder sollte ich das Problem woanders suchen?
@edit
Ctor
SocketHandler::SocketHandler(StreamSocket &socket, SocketReactor &reactor) :
_socket(socket) /* copy */, _reactor(reactor) /* reference */ {
_socket.setBlocking(false);
_reactor.addEventHandler(_socket, NObserver<SocketHandler, ReadableNotification>(*this,
&SocketHandler::onReadableNotification));
_reactor.addEventHandler(_socket,
NObserver<SocketHandler, ErrorNotification>(*this, &SocketHandler::onErrorNotification));
_reactor.addEventHandler(_socket, NObserver<SocketHandler, ShutdownNotification>(*this,
&SocketHandler::onShutdownNotification));
_addr = _socket.peerAddress().toString();
}
Die Ctor Nachrichten und löscht dann eine temporäre Objektinstanz? –
Es gibt keine manuellen Zuweisungen in ctor. Ich registriere nur die Rückrufe. Ich werde bald den Code von ctor anhängen. Ich denke auch, dass, wenn so etwas passieren würde, die Stack-Spur länger gewesen wäre – billykun
In Bezug auf die Temp. Instanz, die gelöscht werden könnte, vermute ich '* _pReactor'. Um dies zu beweisen (oder zu widerlegen), wären zwei zusätzliche Dinge notwendig zu wissen: 1. .: Typ von '_pReactor', 2. .: Signatur von' ServiceHandler :: ServiceHandler() '. – Scheff