< Previous by Date Date Index Next by Date >
  Thread Index Next in Thread >

Re: [reSIProcate] websockets heap corruption


It appears the corruption has to do with the tryAgain flag and things not being aligned correctly in the buffers.  I created a quick fix for this - but it seems the entire wsProcessData needs a good round of review and optimization - there seems to be a lot data copies in it - which is fine for testing but not great for large scale deployments.

With my fix I can now get a call to establish with JSSIP (tryit.jssip.net)!

I have committed this fix.

Scott

On Mon, Apr 29, 2013 at 3:43 PM, Scott Godin <sgodin@xxxxxxxxxxxxxxx> wrote:
Thanks Daniel.

>I did correct some issues (not just in the WebSocket code) where there
>was a new[]/delete mismatch (r10071)

I am using the latest revision and that fix looks isolated to SIPCOMP anyway.  I'll see what I can find.

Scott


On Mon, Apr 29, 2013 at 3:09 PM, Daniel Pocock <daniel@xxxxxxxxxxxxx> wrote:


On 29/04/13 20:58, Scott Godin wrote:
> Hi Daniel,
>
> I'm playing with the websockets stuff in repro now.  I've tried registering
> two JSSIP endpoints (successfully) and placing a call.  I'm running my
> repro instance in the debugger so it is looking for heap corruption and
> stops on any corruption.   Repro seems to make it through the registration
> process fine, but it will trap at various locations in the call
> establishment process.  Sometime when the 180's are flowing (before the
> call is answered) and sometimes after the 200 is sent.  It traps in a
> different location everytime (tried 4 times so far), but it is always on a
> new or delete call.  This leads me to believe the WS transport is causing
> some kind of heap corruption.  I've include two of the stack traces below -
> for these two instances the trap occurs after wsProcessData - not sure if
> that's a clue - but that's what I'm betting on for now.

I did most of my testing with SIPml5, I will have to test more with
JsSIP to see if I see different issues...

> Just wanted to run this by you incase you've seen this before or have any
> pointers on what the cause might be.

I did correct some issues (not just in the WebSocket code) where there
was a new[]/delete mismatch (r10071)


> Note:  One things I noticed in the logs is that the recevie buffer total
> bytes_available appears to grow and not shrink:
> STACK | 20130429-143243.377 | repro.exe | RESIP:TRANSPORT | 13244 |
> connectionbase.cxx:833 | More bytes left over, total bytes_available =
> 16864, consumed only 2596
> ...
> STACK | 20130429-143243.682 | repro.exe | RESIP:TRANSPORT | 13244 |
> connectionbase.cxx:833 | More bytes left over, total bytes_available =
> 21200, consumed only 2596

I'll look at that tomorrow

Received our first patch from a would-be GSoC applicant today, adding
keepalive support to WebSocket, that should be committed soon too.


> Cheers,
> Scott
>
>
> ntdll.dll!RtlpNtEnumerateSubKey()  + 0x1af7 bytes
>   [Frames below may be incorrect and/or missing, no symbols loaded for
> ntdll.dll]
>   ntdll.dll!RtlpNtEnumerateSubKey()  + 0x2a2b bytes
>   ntdll.dll!RtlpNtEnumerateSubKey()  + 0x2b0b bytes
>   ntdll.dll!RtlpNtEnumerateSubKey()  + 0x2d74 bytes
>   ntdll.dll!RtlUlonglongByteSwap()  + 0xdacb bytes
>   ntdll.dll!RtlImageNtHeader()  + 0xb6a bytes
>   ntdll.dll!RtlpNtEnumerateSubKey()  + 0x41ed bytes
>   ntdll.dll!RtlUlonglongByteSwap()  + 0xda2e bytes
>   ntdll.dll!RtlImageNtHeader()  + 0xb6a bytes
>   msvcr100d.dll!_heap_alloc_base(unsigned int size)  Line 55 C
>   msvcr100d.dll!_heap_alloc_dbg_impl(unsigned int nSize, int nBlockUse,
> const char * szFileName, int nLine, int * errno_tmp)  Line 431 + 0x9 bytes
> C++
>   msvcr100d.dll!_nh_malloc_dbg_impl(unsigned int nSize, int nhFlag, int
> nBlockUse, const char * szFileName, int nLine, int * errno_tmp)  Line 239 +
> 0x19 bytes C++
>   msvcr100d.dll!_nh_malloc_dbg(unsigned int nSize, int nhFlag, int
> nBlockUse, const char * szFileName, int nLine)  Line 302 + 0x1d bytes C++
>   msvcr100d.dll!operator new(unsigned int cb, int nBlockUse, const char *
> szFileName, int nLine)  Line 55 + 0x17 bytes C++
>   repro.exe!resip::ConnectionBase::wsProcessData(int bytesRead, bool &
> tryAgain)  Line 848 + 0x1c bytes C++
>> repro.exe!resip::Connection::read()  Line 376 + 0x10 bytes C++
>   repro.exe!resip::Connection::performReads(unsigned int max)  Line 399 +
> 0x8 bytes C++
>   repro.exe!resip::Connection::processPollEvent(unsigned short mask)  Line
> 492 C++
>   repro.exe!resip::FdPollGrp::processItem(resip::FdPollItemIf * item,
> unsigned short mask)  Line 71 + 0x14 bytes C++
>   repro.exe!resip::FdPollImplFdSet::processFdSet(resip::FdSet & fdset)
>  Line 441 C++
>   repro.exe!resip::FdPollImplFdSet::waitAndProcess(int ms)  Line 359 + 0x16
> bytes C++
>   repro.exe!resip::TransportSelectorThread::thread()  Line 38 + 0x28 bytes
> C++
>   repro.exe!threadIfThreadWrapper(void * threadParm)  Line 51 + 0xf bytes
> C++
>   msvcr100d.dll!_callthreadstartex()  Line 314 + 0xf bytes C
>   msvcr100d.dll!_threadstartex(void * ptd)  Line 297 C
>   kernel32.dll!BaseThreadInitThunk()  + 0x12 bytes
>   ntdll.dll!RtlInitializeExceptionChain()  + 0x63 bytes
>   ntdll.dll!RtlInitializeExceptionChain()  + 0x36 bytes
>
>
>
>   ntdll.dll!NtRaiseException()  + 0x12 bytes
>   [Frames below may be incorrect and/or missing, no symbols loaded for
> ntdll.dll]
>   msvcr100d.dll!_CxxThrowException(void * pExceptionObject, const
> _s__ThrowInfo * pThrowInfo)  Line 157 C++
>> msvcp100d.dll!operator new(unsigned int sz, const std::_DebugHeapTag_t &
> tag, char * file, int line)  Line 16 C++
>   msvcp100d.dll!std::_Mutex::_Mutex()  Line 12 + 0x1f bytes C++
>   msvcp100d.dll!std::basic_streambuf<char,std::char_traits<char>
>> ::basic_streambuf<char,std::char_traits<char> >()  Line 25 + 0x3e bytes C++
>   repro.exe!resip::DataBuffer::DataBuffer(resip::Data & str)  Line 18 +
> 0x4d bytes C++
>   repro.exe!resip::oDataStream::oDataStream(resip::Data & str)  Line 141 +
> 0x93 bytes C++
>   repro.exe!resip::Log::Guard::Guard(resip::Log::Level level, const
> resip::Subsystem & subsystem, const char * file, int line)  Line 727 + 0xa7
> bytes C++
>   repro.exe!resip::ConnectionBase::wsProcessData(int bytesRead, bool &
> tryAgain)  Line 865 + 0x38 bytes C++
>   repro.exe!resip::Connection::read()  Line 377 + 0x10 bytes C++
>   repro.exe!resip::Connection::performReads(unsigned int max)  Line 400 +
> 0x8 bytes C++
>   repro.exe!resip::Connection::processPollEvent(unsigned short mask)  Line
> 493 C++
>   repro.exe!resip::FdPollGrp::processItem(resip::FdPollItemIf * item,
> unsigned short mask)  Line 71 + 0x14 bytes C++
>   repro.exe!resip::FdPollImplFdSet::processFdSet(resip::FdSet & fdset)
>  Line 441 C++
>   repro.exe!resip::FdPollImplFdSet::waitAndProcess(int ms)  Line 359 + 0x16
> bytes C++
>   repro.exe!resip::TransportSelectorThread::thread()  Line 38 + 0x28 bytes
> C++
>   repro.exe!threadIfThreadWrapper(void * threadParm)  Line 51 + 0xf bytes
> C++
>   msvcr100d.dll!_callthreadstartex()  Line 314 + 0xf bytes C
>   msvcr100d.dll!_threadstartex(void * ptd)  Line 297 C
>   kernel32.dll!BaseThreadInitThunk()  + 0x12 bytes
>   ntdll.dll!RtlInitializeExceptionChain()  + 0x63 bytes
>   ntdll.dll!RtlInitializeExceptionChain()  + 0x36 bytes
>