Description
The core dump is the same as TS-2882.
When we meet with error, we use the spdy protocol.
(gdb)
#0 0x000000000070f3f7 in handleEvent (event=105, vc=0x2b5f1c27baf0) at ../../iocore/eventsystem/I_Continuation.h:146
#1 read_signal_and_update (event=105, vc=0x2b5f1c27baf0) at UnixNetVConnection.cc:138
#2 0x000000000071381f in UnixNetVConnection::mainEvent (this=0x2b5f1c27baf0, event=<value optimized out>, e=<value optimized out>) at UnixNetVConnection.cc:1066
#3 0x00000000007080c5 in handleEvent (this=0x1bd9130, event=<value optimized out>, e=0x13888d0) at ../../iocore/eventsystem/I_Continuation.h:146
#4 InactivityCop::check_inactivity (this=0x1bd9130, event=<value optimized out>, e=0x13888d0) at UnixNet.cc:80
#5 0x000000000073409f in handleEvent (this=0x2b5ec2eb2010, e=0x13888d0, calling_code=2) at I_Continuation.h:146
#6 EThread::process_event (this=0x2b5ec2eb2010, e=0x13888d0, calling_code=2) at UnixEThread.cc:145
#7 0x0000000000734c13 in EThread::execute (this=0x2b5ec2eb2010) at UnixEThread.cc:224
#8 0x000000000073344a in spawn_thread_internal (a=0x174b830) at Thread.cc:88
#9 0x00002b5c8b3de851 in start_thread () from /lib64/libpthread.so.0
#10 0x000000366a4e894d in clone () from /lib64/libc.so.6
And actually, the UnixNetVConnection pointer is a SSLNetVConnection pointer. and the crashed continuation is 'ProtocolProbeTrampoline'.
The root cause for this problem is that 'ProtocolProbeTrampoline::ioCompletionEvent', this function will hand over the
process logic to next upper protocol such as http and spdy after ssl handshake
is finished in our case.
From the core dump, if we use ssl and spdy, so in the function
'ProtocolProbeTrampoline::ioCompletionEvent', it will first disable the read io
adn handover the continuation of read.vio._cont from 'ProtocolProbeTrampoline'
to 'SpdyClientSession' by below two steps:
1. first disable current io by using 'netvc->do_io_read(this, 0, NULL)'.
2. change the read.vio._cont by using
'probeParent->endpoint[key]>accept(netvc, this>iobuf, reader);' which will be
'SpdySessionAccept::accept' in our case. and in the end, it will call
'SpdyClientSession::state_session_start' which will call 'this->vc->do_io_read'
to set read.vio._cont to SpdyClientSession.
the main point is that the function 'SpdySessionAccept::accept' function will
put an SpdyClientSession event into eventProcessor for net
'eventProcessor.schedule_imm(sm, ET_NET);'
and because each 'net' thread will put a check_inactivity event into the queue
So, in the end, between 'netvc->do_io_read(this, 0, NULL)' and
spdy handler is set, the
check_inactivity may be executed, and if so, the crash will occur.