[jitsi-dev] [libjitsi] crash when stopping streams on conference focus site


#1

Hi list,

I've a problem with conference focus and stopping streams.
When there are running streams, the jvm on conference focus site crashs when receiving udp packets.

This is the method I use for closing the MediaStreams:
public synchronized void stop() {
    System.err.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! JitsiStreamManager.stop()");
    if (mediaStreams != null) {
        Iterator<MediaStream> it = mediaStreams.iterator();
        while (it.hasNext()) {
            MediaStream mediaStream = it.next();
            try {
                System.err.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! JitsiStreamManager.stop(" + mediaStream.getName() + ")");
                mediaStream.stop();
                System.err.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! JitsiStreamManager.stop(" + mediaStream.getName() + ") stopped");
            } finally {
                mediaStream.close();
                it.remove();
                StreamConnector con = streamMap.remove(mediaStream);
                if (con != null) {
                    con.getDataSocket().close();
                    con.getControlSocket().close();
                    System.err.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! JitsiStreamManager.stop(" + mediaStream.getName() + ") closing connector");
                    con.close();
                    System.err.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! JitsiStreamManager.stop(" + mediaStream.getName() + ") connector closed");
                }
                con = null;
                mediaStream = null;
            }
        }
        streamMap.clear();
        mediaStreams.clear();
        System.err.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! JitsiStreamManager.stop() leaving");
    }
}

I explicitely close the connector's sockets as it seems that mediaStream.close() does not always close them and I often get BindException, Address already in use.

This is the log when executing which indicates the error occures while closing the connection while recieving packets (see native log):

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! JitsiStreamManager.stop()
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! JitsiStreamManager.stop(conference focus dummy stream:video)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! JitsiStreamManager.stop(conference focus dummy stream:video) stopped
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! JitsiStreamManager.stop(conference focus dummy stream:video) closing connector
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! JitsiStreamManager.stop(conference focus dummy stream:video) connector closed
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! JitsiStreamManager.stop(engineer:audio)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! JitsiStreamManager.stop(engineer:audio) stopped
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! JitsiStreamManager.stop(engineer:audio) closing connector
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! JitsiStreamManager.stop(engineer:audio) connector closed
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! JitsiStreamManager.stop(engineer:video)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! JitsiStreamManager.stop(engineer:video) stopped

hs_err_pid8452.log (18.1 KB)

hs_err_pid8244.log (17.2 KB)

hs_err_pid6728.log (19.7 KB)

···

#
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x7495139d, pid=6728, tid=5888
#
# JRE version: 7.0-b147
# Java VM: Java HotSpot(TM) Client VM (21.0-b17 mixed mode, sharing windows-x86 )
# Problematic frame:
# C [kernel32.dll+0x1139d]
#
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
#
# An error report file with more information is saved as:
# C:\projects\qonnex1\hs_err_pid6728.log
#
# If you would like to submit a bug report, please visit:
# http://bugreport.sun.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#

I use the latest libjitsi version and the error occures on all windows 7 pc's I've tested.
Anyone with a similar experience?

Cheers, René


#2

public synchronized void stop() {
    System.err.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! JitsiStreamManager.stop()");
    if (mediaStreams != null) {
        Iterator<MediaStream> it = mediaStreams.iterator();
        while (it.hasNext()) {
            MediaStream mediaStream = it.next();
            try {
                System.err.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! JitsiStreamManager.stop(" + mediaStream.getName() + ")");
                mediaStream.stop();

The MediaStream implementation will call stop() as part of the execution of the close() method.

                System.err.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! JitsiStreamManager.stop(" + mediaStream.getName() + ") stopped");
            } finally {
                mediaStream.close();
                it.remove();
                StreamConnector con = streamMap.remove(mediaStream);
                if (con != null) {
                    con.getDataSocket().close();
                    con.getControlSocket().close();

DefaultStreamConnector will close the sockets during the execution of its StreamConnector#close() implementation. Moreover, it has the technical advantage that it will not cause the socket which it is trying to close to be created if it does not exist yet while the calls to StreamConnector#getControlSocket() and getDataSocket() will force the creation of the respective sockets.

                    System.err.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! JitsiStreamManager.stop(" + mediaStream.getName() + ") closing connector");
                    con.close();
                    System.err.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! JitsiStreamManager.stop(" + mediaStream.getName() + ") connector closed");
                }
                con = null;
                mediaStream = null;
            }
        }
        streamMap.clear();
        mediaStreams.clear();
        System.err.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! JitsiStreamManager.stop() leaving");
    }
}

I explicitely close the connector's sockets as it seems that mediaStream.close() does not always close them and I often get BindException, Address already in use.

MediaStream#close() should close the sockets provided to it in the form of a StreamConnector via a call to MediaStream#setConnector(StreamConnector) by calling StreamConnector#close(). If that is not the case, then we should look into it and fix it.

I use the latest libjitsi version and the error occures on all windows 7 pc's I've tested.
Anyone with a similar experience?

Cheers, René

<hs_err_pid8452.log><hs_err_pid8244.log><hs_err_pid6728.log>

No, these logs do not ring any bells right now. Anyway, thank you very much for the report and we'll try to think about it!

···

On Aug 6, 2012, at 7:14 PM, "Rene Lamotte" <chummer25@gmx.net> wrote:


#3

The MediaStream implementation will call stop() as part of the execution of the close() method.

Got that from the AVReceive2 example. stop() is called first there and then close().

DefaultStreamConnector will close the sockets during the execution of its StreamConnector#close() implementation.
Moreover, it has the technical advantage that it will not cause the socket which it is trying to close to be created if it
does not exist yet while the calls to StreamConnector#getControlSocket() and getDataSocket() will force the creation
of the respective sockets.

MediaStream#close() should close the sockets provided to it in the form of a StreamConnector via a call to
MediaStream#setConnector(StreamConnector) by calling StreamConnector#close(). If that is not the case, then we should
look into it and fix it.

Ok, no more cannot bind exceptions, maybe this was an error of an older version of libjitsi.
But the error remains as before. 50% of all calls to stop() result in JVM crash.
My stop() method is now as follows:

public synchronized void stop() {
        System.err.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! JitsiStreamManager.stop()");
        if (mediaStreams != null) {
            Iterator<MediaStream> it = mediaStreams.iterator();
            while (it.hasNext()) {
                MediaStream mediaStream = it.next();
                try {
// System.err.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! JitsiStreamManager.stop(" + mediaStream.getName() + ")");
// mediaStream.stop();
// System.err.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! JitsiStreamManager.stop(" + mediaStream.getName() + ") stopped");
                } finally {
                    mediaStream.close();
                    it.remove();
                    StreamConnector con = streamMap.remove(mediaStream);
                    if (con != null) {
// con.getDataSocket().close();
// con.getControlSocket().close();
// System.err.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! JitsiStreamManager.stop(" + mediaStream.getName() + ") closing connector");
// con.close();
// System.err.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! JitsiStreamManager.stop(" + mediaStream.getName() + ") connector closed");
                    }
                    con = null;
                    mediaStream = null;
                }
            }
            streamMap.clear();
            mediaStreams.clear();
            System.err.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! JitsiStreamManager.stop() leaving");
        }
    }

hs_err_pid5664.log (20.3 KB)


#4

I've switched now back from java 1.7.0_4 to java 1.6.0_24 and this error seems to disappear.
Both 32 bit jvm's.

···

From: Rene Lamotte

Sent: Tuesday, August 07, 2012 2:02 PM
To: dev@jitsi.java.net
Subject: [jitsi-dev] Re: [libjitsi] crash when stopping streams on conference focus site

The MediaStream implementation will call stop() as part of the execution
of the close() method.

Got that from the AVReceive2 example. stop() is called first there and then
close().

DefaultStreamConnector will close the sockets during the execution of its
StreamConnector#close() implementation.
Moreover, it has the technical advantage that it will not cause the socket
which it is trying to close to be created if it
does not exist yet while the calls to StreamConnector#getControlSocket()
and getDataSocket() will force the creation
of the respective sockets.

MediaStream#close() should close the sockets provided to it in the form of
a StreamConnector via a call to
MediaStream#setConnector(StreamConnector) by calling
StreamConnector#close(). If that is not the case, then we should
look into it and fix it.

Ok, no more cannot bind exceptions, maybe this was an error of an older
version of libjitsi.
But the error remains as before. 50% of all calls to stop() result in JVM
crash.
My stop() method is now as follows:

public synchronized void stop() {
        System.err.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
JitsiStreamManager.stop()");
        if (mediaStreams != null) {
            Iterator<MediaStream> it = mediaStreams.iterator();
            while (it.hasNext()) {
                MediaStream mediaStream = it.next();
                try {
//
System.err.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
JitsiStreamManager.stop(" + mediaStream.getName() + ")");
// mediaStream.stop();
//
System.err.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
JitsiStreamManager.stop(" + mediaStream.getName() + ") stopped");
                } finally {
                    mediaStream.close();
                    it.remove();
                    StreamConnector con = streamMap.remove(mediaStream);
                    if (con != null) {
// con.getDataSocket().close();
// con.getControlSocket().close();
//
System.err.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
JitsiStreamManager.stop(" + mediaStream.getName() + ") closing connector");
// con.close();
//
System.err.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
JitsiStreamManager.stop(" + mediaStream.getName() + ") connector closed");
                    }
                    con = null;
                    mediaStream = null;
                }
            }
            streamMap.clear();
            mediaStreams.clear();
            System.err.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
JitsiStreamManager.stop() leaving");
        }
    }


#5

As stated below, the JVM crash disappeared when changing to java 6, in Java 7 it still crashes.
But, I have to close excplicitely the underlying rtp sockets in both cases.

MediaStream#close() should close the sockets provided to it in the form of
a StreamConnector via a call to
MediaStream#setConnector(StreamConnector) by calling
StreamConnector#close(). If that is not the case, then we should
look into it and fix it.

Calling only MediaStream.close() or MediaStream.close() with a following StreamConnector.close() when a peer disconnects, result in most cases in a CannotBindException on the conference focus site once this peer connects again or the same ports are reused.

Removing a peer this way from a session seems to work as supposed and sockets don't remain open:

StreamConnector con = streamMap.remove(mediaStream);
if (con != null) {
    con.getDataSocket().close();
    con.getControlSocket().close();
    con.close();
}
mediaStream.close();

-----Urspr�ngliche Nachricht-----

···

From: Rene Lamotte

Sent: Tuesday, August 07, 2012 2:52 PM
To: dev@jitsi.java.net
Subject: [jitsi-dev] Re: [libjitsi] crash when stopping streams on conference focus site

I've switched now back from java 1.7.0_4 to java 1.6.0_24 and this error
seems to disappear.
Both 32 bit jvm's.

From: Rene Lamotte

Sent: Tuesday, August 07, 2012 2:02 PM
To: dev@jitsi.java.net
Subject: [jitsi-dev] Re: [libjitsi] crash when stopping streams on
conference focus site

The MediaStream implementation will call stop() as part of the execution
of the close() method.

Got that from the AVReceive2 example. stop() is called first there and then
close().

DefaultStreamConnector will close the sockets during the execution of its
StreamConnector#close() implementation.
Moreover, it has the technical advantage that it will not cause the socket
which it is trying to close to be created if it
does not exist yet while the calls to StreamConnector#getControlSocket()
and getDataSocket() will force the creation
of the respective sockets.

MediaStream#close() should close the sockets provided to it in the form of
a StreamConnector via a call to
MediaStream#setConnector(StreamConnector) by calling
StreamConnector#close(). If that is not the case, then we should
look into it and fix it.

Ok, no more cannot bind exceptions, maybe this was an error of an older
version of libjitsi.
But the error remains as before. 50% of all calls to stop() result in JVM
crash.
My stop() method is now as follows:

public synchronized void stop() {
        System.err.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
JitsiStreamManager.stop()");
        if (mediaStreams != null) {
            Iterator<MediaStream> it = mediaStreams.iterator();
            while (it.hasNext()) {
                MediaStream mediaStream = it.next();
                try {
//
System.err.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
JitsiStreamManager.stop(" + mediaStream.getName() + ")");
// mediaStream.stop();
//
System.err.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
JitsiStreamManager.stop(" + mediaStream.getName() + ") stopped");
                } finally {
                    mediaStream.close();
                    it.remove();
                    StreamConnector con = streamMap.remove(mediaStream);
                    if (con != null) {
// con.getDataSocket().close();
// con.getControlSocket().close();
//
System.err.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
JitsiStreamManager.stop(" + mediaStream.getName() + ") closing connector");
// con.close();
//
System.err.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
JitsiStreamManager.stop(" + mediaStream.getName() + ") connector closed");
                    }
                    con = null;
                    mediaStream = null;
                }
            }
            streamMap.clear();
            mediaStreams.clear();
            System.err.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
JitsiStreamManager.stop() leaving");
        }
    }