[Live-devel] libasan detects memory access error
Gerald Hansink
gerald.hansink at ieee.org
Wed May 24 02:29:46 PDT 2017
hi ross,
colleague could not subscribe to the mailing list with his email address so
see below for the forwarded question.
best regards,
gerald
------------------------------------------------------------
----------------------------------------------------
Hi,
three weeks ago we've started using libAsan on gcc 4.9 and we have fixed a
dozen of small memory errors on our code ever since.
Today I'm having an error in the live555 code that came up using libAsan.
It seems that the taskscheduler fires up the destructor of SocketDescriptor
after an evaluation of true on the fDeleteMyselfNext flag which is set
implicitly by calling Medium::close(our_session).
The problem is that this event can be fired after the destruction of
SocketDescriptor's rtpInterface, meaning that the global variable
"rtpInterface" inside SocketDescriptor points to a free'd address.
It appears that in our code this has never caused any troubles but now that
we use libAsan it has come to our attention since Asan fire a segfault when
memory corruption occurs, there are no false positives when using libAsan.
An example of the output when printing a line in
RTPInterface::removeStreamSocket and in ~RTPInterface:
...
Debug: removeStreamSocket @ 0xad3056c8
Debug: delete RTPInterface 0xad3056c8
Debug: removeStreamSocket @ 0xad3056c8
...
As can be seen, after the RTPInterface was delete, removeStreamSocket is
being called on the same rtpInterface ptr.
As it happens the code inside removeStreamSocket using the invalid ptr
doesn't do anything wrong on our side, the first variable being tested is
always NULL, a null check prevents that the code continues, this however is
purely a coincidence.
I've modified ~SocketDescriptor for debugging,
lookupRTPInterface(fStreamChannelId) yields 0x0 so that's another way of
telling that something is wrong (see code below).
Can someone put the same debug prints in their live555 implementation so
that it can be confirmed that there is a issue?
Regards,
Frederik
SocketDescriptor::~SocketDescriptor() {
fEnv.taskScheduler().turnOffBackgroundReadHandling(fOurSocketNum);
removeSocketDescription(fEnv, fOurSocketNum);
if (fSubChannelHashTable != NULL) {
// Remove knowledge of this socket from any "RTPInterface"s that
are using it:
HashTable::Iterator* iter = HashTable::Iterator::create(*f
SubChannelHashTable);
RTPInterface* rtpInterface;
char const* key;
while ((rtpInterface = (RTPInterface*)(iter->next(key))) != NULL) {
u_int64_t streamChannelIdLong = (u_int64_t)key;
unsigned char streamChannelId = (unsigned
char)streamChannelIdLong;
auto i = lookupRTPInterface(fStreamChannelId);
if (i == rtpInterface)
{
rtpInterface->removeStreamSocket(fOurSocketNum,
streamChannelId);
}
else
{
qDebug() << "lookupRTPInterface(fStreamChannelId) (" << i
<< ") != rtpInterface (" << rtpInterface << ") @ SocketDescriptor " << this;
// prevent further errors:
fServerRequestAlternativeByteHandler = nullptr;
}
}
delete iter;
// Then remove the hash table entries themselves, and then remove
the hash table:
while (fSubChannelHashTable->RemoveNext() != NULL) {}
delete fSubChannelHashTable;
}
// Finally:
if (fServerRequestAlternativeByteHandler != NULL) {
// Hack: Pass a special character to our alternative byte handler,
to tell it that either
// - an error occurred when reading the TCP socket, or
// - no error occurred, but it needs to take over control of the
TCP socket once again.
u_int8_t specialChar = fReadErrorOccurred ? 0xFF : 0xFE;
(*fServerRequestAlternativeByteHandler)(fServerRequestAlternativeByteHandlerClientData,
specialChar);
}
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.live555.com/pipermail/live-devel/attachments/20170524/aa4db477/attachment.html>
More information about the live-devel
mailing list