Re: [Opalvoip-devel] SIP MESSAGE handling bug / race
Brought to you by:
csoutheren,
rjongbloed
From: Stefano P. <ste...@gm...> - 2008-07-14 14:12:14
|
When the assertI reported is triggered, the transactions list contains some/many SIPMessage objects, but none of these object has currentObject->SafeReference() returning true. So transactions->GetAt(0) returns a null smart pointer. An then, the assert is thrown when calling Abort method on the null smart pointer. Maybe this can help. However, I can't undestand what is SIPHandler::CollapseFork method doing. I'm not familiar with this code, so probably I'm making a mistake somewhere... In my test, I try to send many "sip message" msgs, as quickly as possible. So I have many unacknowledged Sip Messages in "transactions" list. Why the arrival of an ack for one of these messages should cause other transactions to Abort ? Bye Stefano On Thu, Jul 10, 2008 at 12:08 PM, Stefano Picerno <ste...@gm...> wrote: > The "Opal Garbage" thread seems to be the cause. All other threads are > waiting, or doing something unrelated. > > Its stack: > simpleOPAL.exe!PSemaphore::Wait() Line 1377 + 0x21 bytes C++ > simpleOPAL.exe!PReadWriteMutex::InternalStartRead() Line 2129 C++ > simpleOPAL.exe!PReadWriteMutex::StartRead() Line 2120 C++ > simpleOPAL.exe!PSafeObject::LockReadOnly() Line 98 C++ > > simpleOPAL.exe!PSafePtrBase::EnterSafetyMode(PSafePtrBase::EnterSafetyModeOption > ref=AlreadyReferenced) Line 610 + 0xb bytes C++ > simpleOPAL.exe!PSafePtrBase::Next() Line 542 C++ > simpleOPAL.exe!PSafePtr<SIPTransaction>::operator++() Line 721 C++ > > simpleOPAL.exe!SIPEndPoint::GarbageCollection() Line 318 C++ > simpleOPAL.exe!OpalManager::GarbageCollection() Line 1390 + 0x1b > bytes C++ > simpleOPAL.exe!OpalManager::GarbageMain(PThread & __formal={...}, > PThread & __formal={...}) Line 1410 + 0x8 bytes C++ > simpleOPAL.exe!OpalManager::GarbageMain_PNotifier::Call(PObject & > note={...}, int extra=0) Line 1306 + 0x2a bytes C++ > simpleOPAL.exe!PNotifier::operator()(PObject & notifier={...}, int > extra=0) Line 96 C++ > simpleOPAL.exe!PSimpleThread::Main() Line 1894 C++ > simpleOPAL.exe!PThread::MainFunction(void * threadPtr=0x0031e978) > Line 708 C++ > msvcr80d.dll!_callthreadstartex() Line 348 + 0xf bytes C > msvcr80d.dll!_threadstartex(void * ptd=0x0031e498) Line 331 C > > PBoolean SIPEndPoint::GarbageCollection() > { > PSafePtr<SIPTransaction> transaction(transactions, PSafeReadOnly); > while (transaction != NULL) { > if (transaction->IsTerminated()) { > PString id = transaction->GetTransactionID(); > ++transaction; > transactions.RemoveAt(id); > } > else > ++transaction; > } /// EIP points here on this thread > > transactions.DeleteObjectsToBeRemoved(); > activeSIPHandlers.DeleteObjectsToBeRemoved(); > > return OpalEndPoint::GarbageCollection(); > } > > I could reproduce the problem with logging enabled. > I'm attaching a gzipped trace file of the whole session. > > > > On Thu, Jul 10, 2008 at 3:09 AM, Robert Jongbloed < > ro...@vo...> wrote: > >> I have looked at the code and I am at a total loss how GetSize() can be >> non-zero but GetAt(0) then returns NULL. >> >> >> >> Really the only way that can happen is if the object is removed in another >> thread between the two lines of code. While this is possible, it is >> extremely unlikely! >> >> >> >> Next time it happens, can you send ALL of the threads? And the trace log >> too. >> >> >> >> >> >> Robert Jongbloed >> >> OPAL/OpenH323 Architect and Co-founder. >> >> >> >> *From:* opa...@li... [mailto: >> opa...@li...] *On Behalf Of *Stefano >> Picerno >> *Sent:* Thursday, 10 July 2008 3:13 AM >> *To:* opa...@li... >> *Subject:* [Opalvoip-devel] SIP MESSAGE handling bug / race >> >> >> >> Hi, >> I tryed to send many "SIP MESSAGE" packets with opal, but sometimes a >> NULL pointer assert is triggered in SIPHandler::CollapseFork >> Sometimes the application works, sometimes an assert is triggered >> >> Sample test code I added to simpleopal: >> >> cout << "Starting send.\n"; >> for(int i = 0; i< 1000; i++) >> { >> sipEP->Message("sip:791@192.168.33.119<sip%3A791@192.168.33.119>", >> "FooBar"); >> } >> cout << "Completed send.\n"; >> >> >> The assertion is triggered here (handlers.cxx line 359): >> >> void SIPHandler::CollapseFork(SIPTransaction & transaction) >> { >> // >> // Take this transaction out and kill all the rest >> transactions.Remove(&transaction); >> while (transactions.GetSize() > 0) { >> PSafePtr<SIPTransaction> transToGo = transactions.GetAt(0); >> transactions.Remove(transToGo); >> * transToGo->Abort(); // transToGo safeptr contains a null pointer !! >> * assertion fails >> } >> >> // And end connect mode on the transport >> transport->SetInterface(transaction.GetInterface()); >> } >> >> As a quick and dirty workaround, I added an " if (transToGo) " before the >> Abort call, but I'm sure it's not a proper fix, as it leaves transaction >> objects in the transactions list. >> Any idea ? >> >> Bye >> Stefano >> >> PS: Here's the full stacktrace >> >> > simpleOPAL.exe!PAssertFunc(const char * msg=0x04c803c0) Line 321 >> C++ >> simpleOPAL.exe!PAssertFunc(const char * file=0x00f5160c, int >> line=701, const char * className=0x00000000, const char * msg=0x00fde6c4) >> Line 140 + 0x3b bytes C++ >> simpleOPAL.exe!PAssertFunc(const char * file=0x00f5160c, int >> line=701, const char * className=0x00000000, PStandardAssertMessage >> msg=PNullPointerReference) Line 117 + 0x18 bytes C++ >> simpleOPAL.exe!PSafePtr<SIPTransaction>::operator->() Line 701 + >> 0x33 bytes C++ >> simpleOPAL.exe!SIPHandler::CollapseFork(SIPTransaction & >> transaction={...}) Line 359 + 0x8 bytes C++ >> simpleOPAL.exe!SIPHandler::OnReceivedOK(SIPTransaction & >> transaction={...}, SIP_PDU & __formal={...}) Line 348 C++ >> simpleOPAL.exe!SIPEndPoint::OnReceivedOK(SIPTransaction & >> transaction={...}, SIP_PDU & response={...}) Line 673 C++ >> simpleOPAL.exe!SIPEndPoint::OnReceivedResponse(SIPTransaction & >> transaction={...}, SIP_PDU & response={...}) Line 518 C++ >> simpleOPAL.exe!SIPTransaction::OnReceivedResponse(SIP_PDU & >> response={...}) Line 2278 C++ >> simpleOPAL.exe!SIPEndPoint::OnReceivedConnectionlessPDU(OpalTransport >> & transport={...}, SIP_PDU * pdu=0x0498d038) Line 431 C++ >> simpleOPAL.exe!SIPEndPoint::OnReceivedPDU(OpalTransport & >> transport={...}, SIP_PDU * pdu=0x0498d038) Line 419 + 0x18 bytes C++ >> simpleOPAL.exe!SIPEndPoint::HandlePDU(OpalTransport & >> transport={...}) Line 248 + 0x18 bytes C++ >> simpleOPAL.exe!SIPEndPoint::NewIncomingConnection(OpalTransport * >> transport=0x04963868) Line 138 C++ >> simpleOPAL.exe!OpalEndPoint::ListenerCallback(PThread & >> __formal={...}, int param=76953704) Line 282 + 0x11 bytes C++ >> simpleOPAL.exe!OpalEndPoint::ListenerCallback_PNotifier::Call(PObject >> & note={...}, int extra=76953704) Line 173 + 0x27 bytes C++ >> simpleOPAL.exe!PNotifier::operator()(PObject & notifier={...}, int >> extra=76953704) Line 96 C++ >> simpleOPAL.exe!OpalListener::ListenForConnections(PThread & >> thread={...}, int __formal=0) Line 456 C++ >> >> simpleOPAL.exe!OpalListener::ListenForConnections_PNotifier::Call(PObject & >> note={...}, int extra=0) Line 350 + 0x27 bytes C++ >> simpleOPAL.exe!PNotifier::operator()(PObject & notifier={...}, int >> extra=0) Line 96 C++ >> simpleOPAL.exe!PSimpleThread::Main() Line 1894 C++ >> simpleOPAL.exe!PThread::MainFunction(void * threadPtr=0x0238bf60) >> Line 708 C++ >> msvcr80d.dll!_callthreadstartex() Line 348 + 0xf bytes C >> msvcr80d.dll!_threadstartex(void * ptd=0x0238c7f8) Line 331 C >> > > |