CSecureSocket resource leak (CONE 36)
Login to reply to this topic.
Tue, 2008-06-17 11:36
Joined: 2008-06-17
Forum posts: 2

Hi,

I'm trying to resolve a resource leak with CSecureSocket which I can reproduce on both UIQ and Series60 emulators. I've seen previous posts on this topic but without any resolution.

Generally, the following example code will connect to a secure server and shut down cleanly. On one particular server (yahoo's pop3 server) I get a resource leak. Puzzled

Can anyone shead any light on this?

Thanks in advance,

Tom

SecureTestL(_L("plus.smtp.mail.yahoo.com"), 465, _L("TLS1.0")); // clean
SecureTestL(_L("plus.pop.mail.yahoo.com"), 995, _L("TLS1.0")); // leaky

void SecureTestL(const TDesC& serverAddress, TInt portNumber, const TDesC& secureProtocol)
{
        TInt processHandleCount0;
        TInt threadHandleCount0;

        FLOG(_L("Attempting connection to '%S' %i using '%S'"), &serverAddress, portNumber, &secureProtocol);
       
        RThread().HandleCount(processHandleCount0, threadHandleCount0);
       
        RSocketServ                                socketServer;
        RConnection                                connection;
        RHostResolver                        hostResolver;
        TNameEntry                                nameEntry;
        RSocket                                        socketOpen;
        CSecureSocket*                        secureSocket;
        TRequestStatus                        status;

        TInt err = socketServer.Connect();
        User::LeaveIfError(err);
       
        err = connection.Open(socketServer, KConnectionTypeDefault);
        User::LeaveIfError(err);
       
        err = connection.Start();
        User::LeaveIfError(err);
       
        hostResolver.Open(socketServer, KAfInet, KProtocolInetUdp, connection);
        err = hostResolver.GetByName(serverAddress, nameEntry);
        User::LeaveIfError(err);
       
        TInetAddr address(nameEntry().iAddr);
        address.SetPort(portNumber);
        socketOpen.Open(socketServer, KAfInet, KSockStream, KUndefinedProtocol, connection);
        socketOpen.Connect(address, status);
        User::WaitForRequest(status);
        User::LeaveIfError(status.Int());
       
        secureSocket = CSecureSocket::NewL(socketOpen, secureProtocol);
       
        TBuf8<256> serverAddress8;
        serverAddress8.Copy(serverAddress);
        err = secureSocket->SetOpt(KSoSSLDomainName,        KSolInetSSL, serverAddress8);
        secureSocket->FlushSessionCache();
   
        TBuf8<2> buf;
        buf.SetLength(2);
        buf[0]=0; buf[1]=10;                                               
        err = secureSocket->SetAvailableCipherSuites( buf );
        User::LeaveIfError(status.Int());
 
        secureSocket->StartClientHandshake( status );
        TBool ran;
        do
            {
                User::WaitForAnyRequest();
                TInt errorCode;
                ran = CActiveScheduler::RunIfReady(errorCode, CActive::EPriorityIdle);
            } while (ran);

        User::LeaveIfError(status.Int());
         
        delete secureSocket;
        socketOpen.Close();
        hostResolver.Close();
        connection.Close();
        socketServer.Close();
   
        TInt processHandleCount1;
        TInt threadHandleCount1;
        RThread().HandleCount(processHandleCount1, threadHandleCount1);
       
        FLOG(_L8("Leaks %i, %i"), processHandleCount1 - processHandleCount0, threadHandleCount1 - threadHandleCount0);
       
        if (processHandleCount0 != processHandleCount1 || threadHandleCount0 != threadHandleCount1)
                {
                User::Leave(1);
                }
        }


Tue, 2008-06-17 12:57
Joined: 2007-09-24
Forum posts: 94

hi
CONE 36 is Open handles were found during application shutdown
This happens if a call to RThread::HandleCount(TInt & aProcessHandleCount, TInt & aThreadHandleCount) const ; returns anything other than zero on application exit.
Things which have a handle are generally things that you Open() and Close() and usually are R classes. Check through your code that all Open()'s are matched with a Close().

Possibles are RThread, RHeap, RArray (doesn't need an Open(), but does need a Close() or Reset) etc.
for more news on Symbian Visit regularly http://symbianeasy.blogspot.com/

Tue, 2008-06-17 14:00
Joined: 2004-11-29
Forum posts: 1394

Ehm.. I think he obviously knows that very well Smiling
If you try read the post too, and look at what he is asking, and what he tries in the code...

To me, it sounds like something you need to take up with symbian directly, try ask on their forums on developer.symbian.com

Tue, 2008-06-17 16:24
Joined: 2007-11-14
Forum posts: 10

That code isn't leave-safe. If any of those opens and connects fail, it will leave the connection open. You should be using
CleanupClosePushL()
and the like to put your open resources onto the cleanup stack so that they are destroyed if the code leaves at any point.
The same is true with your CSecureSocket creation, although that can be put on the cleanup stack normally.

Of course, that doesn't help if the code isn't leaving Smiling Have you stepped through the code in the emulator to see if it is causing an error at any point and doing so? If not, I'd suggest doing so and checking if the code leaves anywhere.

Tue, 2008-06-17 16:40
Joined: 2008-06-17
Forum posts: 2

Cheers for the responses guys.

I have checked that the code doesn't leave (before posting).
I do Close() all the R classes.
The code above is intended to be readable, rather than best practice. The actual code I am working with is a big state machine.

I guess the next step is to head to the symbian forums and see what happens there.

Tue, 2008-06-17 16:44
Joined: 2007-09-24
Forum posts: 94

keep it up
Smiling Smiling Smiling Smiling Smiling Smiling Smiling Smiling Smiling

Tue, 2008-06-17 17:41
Joined: 2007-11-14
Forum posts: 10

My only other suggestion would be to try calling Stop() on your connection rather than Close() then. The documentation for Close() does state it doesn't disconnect the socket immediately, although it should close your connection to it. Stop will immediately shut down the connection without careing about it Smiling

And yeah, check out what they say over at Symbian.

Tue, 2008-07-01 06:04
Joined: 2007-01-17
Forum posts: 101

I have Resolved the CONE 36 Errors by using this in the ConstructL() of my AppUi

iCoeEnv->DisableExitChecks(ETrue);

This CONE 36 Panic happens only in emulator , In the Device all the Resouce handles get closed upon calling Close/stop etc


Shashi Kiran G M

Tue, 2008-07-01 09:33
Joined: 2004-11-29
Forum posts: 1394

gmsk19:
No... You have not "resolved" it... you have hidden the error.
You still have the programmatic error in your application, you just choose to ignore it now...
Ofcourse, its possible it won't cause any problems (depending a bit on the exact cause of it) but you have not fixed it, its still there, with all that could mean.
Just wanted to make that clear Smiling

Mon, 2008-07-14 14:17
Joined: 2007-01-17
Forum posts: 101

i have resolved the issue now. I make sure that all the resources i used are closed appropriately.

//For example in case of RHostResolver
iResolver.Cancel();
iResolver.Stop();
//even though stop() is enough.

//like wise for socket:
iSoket.CancellAll();
iTlsSocket->CancelAll();
iTlsSocket.Close();
delete iTlsSocket();
iTlsSocket = 0;
iSocket.Close();
//Finally SocketServ
iSocketServ.Close();


Shashi Kiran G M

Mon, 2008-07-14 14:16
Joined: 2007-01-17
Forum posts: 101

But i have also noticed with my earlier code in N95 that this does CONE 36 did not happen. now N95 panics if there anything wrong . it only happened in the emulator


Shashi Kiran G M

Thu, 2008-11-06 09:28
Joined: 2008-11-06
Forum posts: 3

TInetAddr address;
TRequestStatus iStatus;
RHostResolver resolver;
TNameEntry entry;

User::LeaveIfError(resolver.Open(iSocketServ, KAfInet, KProtocolInetTcp));
CleanupClosePushL( resolver );
resolver.GetByName(_L("192.168.2.24"), entry);

CleanupStack::PopAndDestroy();//for resolver

address.SetAddress((TInetAddr::Cast(entry().iAddr)).Address());
address.SetPort(2801);
User::LeaveIfError(clientSockId.Open(iSocketServ, KAfInet, KSockStream, KProtocolInetTcp));

clientSockId.Connect(address, iStatus);
User::WaitForRequest(iStatus);
if(iStatus == KErrNone)
{
_LIT(KTLS1,"TLS1.0");
iTlsSocket = CSecureSocket::NewL(clientSockId,KTLS1);
iTlsSocket->FlushSessionCache();
iTlsSocket->StartClientHandshake(iStatus);
User::WaitForRequest(iStatus);
User::LeaveIfError(iStatus.Int());
if(iStatus == KErrNone)
readDatastrt(); //read welcome after handshake
}

its hangs out after StartClientHandshake


copyright 2003-2009 NewLC SARL