vmime icon indicating copy to clipboard operation
vmime copied to clipboard

Exception during vmime::exceptions::operation_timed_out terminates whole program

Open SoulfreezerXP opened this issue 11 years ago • 4 comments

Hi,

I have found a problem, when dealing with the new timeoutHandler-mechanism. The Problem is, that it is possible, that after the "vmime::exceptions::operation_timed_out" another exception is thrown, so std::terminate is called and the program terminates. Because I need a bullet-proofed Mail-Receiver-Main-Loop, this behavior is very suboptimal for me, cause I cannot do anything to catch this errror :(

terminate called after throwing an instance of 'vmime::exceptions::operation_timed_out' what(): Operation timed out. Abgebrochen (Speicherabzug geschrieben)

I think the right solution is, to check, if an operation_timed_out-exception is already thrown, so do not throw a second exception?!

Here u can see the problem: (fresh GIT-Source from Today 06.10.2014)

I have "linked in" my own TimeoutHandler (set to 1 Second to provocate the error), and after one second, the function m_connection->connect() throws the timeout-exception. That is ok, and the expected behavior.

void POP3Store::connect() { if (isConnected()) throw exceptions::already_connected();

m_connection = make_shared <POP3Connection>
    (dynamicCast <POP3Store>(shared_from_this()), getAuthenticator());

try
{
    m_connection->connect();
}
catch (std::exception&)
{
    m_connection = null;
    throw;
}

}

But then, in the progress of stack-unwinding, the m_connection-shared-pointer destroys the POP3Connection - object. Now see here the destructor of this object:

POP3Connection::~POP3Connection() { try { if (isConnected()) disconnect(); else if (m_socket) internalDisconnect(); } catch (vmime::exception&) { // Ignore } }

Cause of the short time-delay (1 Second), the internalDisconnect()-function is called.

void POP3Connection::internalDisconnect() { if (m_socket) { if (m_socket->isConnected()) { try { POP3Command::QUIT()->send(dynamicCast <POP3Connection>(shared_from_this())); POP3Response::readResponse(dynamicCast <POP3Connection>(shared_from_this())); } catch (exception&) { // Not important }

        m_socket->disconnect();
    }

    m_socket = null;
}

m_timeoutHandler = null;

m_authenticated = false;
m_secured = false;

m_cntInfos = null;

}

Here I believe, "the POP3Command::QUIT()->send" throws another exception and the programm terminates immediatly without catching this exception. If I comment this line out, my programm works fine and I am able to catch the timeout-exception in my application.

SoulfreezerXP avatar Oct 06 '14 11:10 SoulfreezerXP

Hello!

Thanks for your report. Unfortunately, I can't manage to reproduce the problem. Could you provide me a ZIP file which the minimal test program which reproduces the issue?

Thanks,

Vincent

vincent-richard avatar Oct 10 '14 20:10 vincent-richard

Sent a zipped example to the E-Mail: [email protected]

SoulfreezerXP avatar Oct 15 '14 09:10 SoulfreezerXP

Hi!

Thanks for the example project. I am still investigating on the problem, will let you know when I find something.

Thanks,

Vincent

vincent-richard avatar Nov 02 '14 10:11 vincent-richard

Hello!

Did the following commit fix the problem? https://github.com/kisli/vmime/commit/31df6171de026e7c1868f6d32f84a3bc6200f5fb

Vincent

vincent-richard avatar Jan 14 '15 18:01 vincent-richard