When enabling edge push-pull streaming in srs3.0.18, a segmentation fault issue occurs.
xialixin opened this issue · 3 comments
After downloading srs3.0.18 and running the test process, when enabling edge push-pull streaming, a segmentation fault problem occurs. The following is the stack information from gdb.
[2017-02-27 15:46:00.823][Trace][26128][105] dispatch cached gop success. count=0, duration=-1
[2017-02-27 15:46:00.824][Trace][26128][105] create consumer, queue_size=30.00, jitter=1
[2017-02-27 15:46:00.824][Trace][26128][105] ignore disabled exec for vhost=defaultVhost
[2017-02-27 15:46:00.834][Trace][26128][105] exec thread cid=108, current_cid=105
Program received signal SIGSEGV, Segmentation fault.
0x00000000004e05ea in SrsTcpClient::get_recv_bytes (this=0x976590) at src/app/srs_app_st.cpp:520
520 return io->get_recv_bytes();
Missing separate debuginfos, use: debuginfo-install glibc-2.17-157.el7_3.1.x86_64 libgcc-4.8.5-11.el7.x86_64 libstdc++-4.8.5-11.el7.x86_64
(gdb) bt
#0 0x00000000004e05ea in SrsTcpClient::get_recv_bytes (this=0x976590) at src/app/srs_app_st.cpp:520
#1 0x0000000000489231 in SrsKbps::set_io (this=0x976270, in=0x9765c0, out=0x9765c0)
at src/protocol/srs_protocol_kbps.cpp:129
#2 0x00000000004abac3 in SrsSimpleRtmpClient::connect (this=0x976220) at src/app/srs_app_rtmp_conn.cpp:112
#3 0x0000000000553ef0 in SrsEdgeRtmpUpstream::connect (this=0x970650, r=0x970e30, lb=0x971570)
at src/app/srs_app_edge.cpp:129
#4 0x000000000055494a in SrsEdgeIngester::cycle (this=0x970600) at src/app/srs_app_edge.cpp:242
#5 0x00000000004db345 in SrsReusableThread2::cycle (this=0x971520) at src/app/srs_app_thread.cpp:315
#6 0x00000000004de72b in internal::SrsThread::thread_cycle (this=0x970ac0) at src/app/srs_app_st.cpp:215
#7 0x00000000004de929 in internal::SrsThread::thread_fun (arg=0x970ac0) at src/app/srs_app_st.cpp:255
#8 0x000000000058c325 in _st_thread_main () at sched.c:337
#9 0x000000000058caad in st_thread_create (start=0xffffffff, arg=0x7ffff7f826f0, joinable=0, stk_size=4096) at sched.c:616
#10 0x0000000000976190 in ?? ()
#11 0x00007ffff7f827d0 in ?? ()
#12 0x000000000058cad1 in st_thread_create (start=0x6d, arg=0x7ffff7f3ae30, joinable=0, stk_size=0) at sched.c:624
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
(gdb)
Based on the stack information, I traced the code and found that the "io" member variable in srs_app_st.cpp is NULL and not assigned, causing a segmentation fault. Analyzing the code, the reason is in srs_app_rtmp_conn.cpp.
int SrsSimpleRtmpClient::connect()
{
int ret = ERROR_SUCCESS;
close();
transport = new SrsTcpClient(req->host, req->port, connect_timeout);
client = new SrsRtmpClient(transport);
kbps->set_io(transport, transport);
if ((ret = transport->connect()) != ERROR_SUCCESS) {
close();
return ret;
}
client->set_recv_timeout(stream_timeout);
client->set_send_timeout(stream_timeout);
''''''''
The line 'kbps->set_io(transport, transport);' is calling the value of 'io', and the assignment of 'io' variable is set in 'transport->connect()'.
int SrsTcpClient::connect()
{
int ret = ERROR_SUCCESS;
close();
srs_assert(stfd == NULL);
if ((ret = srs_socket_connect(host, port, timeout, &stfd)) != ERROR_SUCCESS) {
srs_error("connect tcp://%s:%d failed, to=%"PRId64"ms. ret=%d", host.c_str(), port, timeout, ret);
return ret;
}
srs_assert(io == NULL);
io = new SrsStSocket(stfd);
return ret;
} The 'io' was called before it was set. This resulted in using a null value and causing a segmentation fault.
In the test, the code in 'int SrsSimpleRtmpClient::connect()' in 'srs_app_st.cpp' was modified as follows:
int SrsSimpleRtmpClient::connect()
{
int ret = ERROR_SUCCESS;
close();
transport = new SrsTcpClient(req->host, req->port, connect_timeout);
if ((ret = transport->connect()) != ERROR_SUCCESS) {
close();
return ret;
}
client = new SrsRtmpClient(transport);
kbps->set_io(transport, transport);
client->set_recv_timeout(stream_timeout);
client->set_send_timeout(stream_timeout);
''''''''
}
After compiling and running, the edge pushing and pulling streams are normal, and there are no more segmentation faults.
TRANS_BY_GPT3
I think it should be changed to the SrsTcpClient class, which should ensure that the interface is available even without a connection.
TRANS_BY_GPT3
I made some changes to SrsTcpClient and also changed it to new-delete mode, so there is no need to close and reuse objects.
o = new SrsTcpClient()
o.connect();
o.read()
o.write()
delete o;
The close method has been removed.
TRANS_BY_GPT3
At the same time, SrsStSocket was changed to an empty constructor, finally understanding why it is necessary to keep the constructor simple.
skt = new SrsStSocket();
skt->initialize(stfd);
A simple empty constructor, and then use the initialize function to set some states.
This allows for adapting to an empty object, so after skt = new SrsStSocket()
, it can be called:
skt->get_recv_bytes()
This also makes sense because after constructing this object, it is possible for it to return 0 when asked how many bytes it has received.
TRANS_BY_GPT3