-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
Description
This issue refers to version 2.0.
Firstly, the edge source has the following two members:
class SrsSource : public ISrsReloadHandler
{
......
SrsRequest* _req;
SrsHls* hls;
......
}
The hls also has a member _req:
class SrsHls
{
...
SrsRequest* _req;
...
}
Next, there are two ways to fetch the edge source: pull and push.
When pulling the source, the edge source's hls is functionally identical to the origin source's hls, and it can slice normally. The hls _req is initialized in the source->on_publish call to hls->on_publish, and the assignment logic is to copy the request, as shown in the code snippet below:
int SrsHls::on_publish(SrsRequest* req, bool fetch_sequence_header)
{
......
srs_freep(_req);
_req = req->copy();
......
}
At this point, both the source and its hls member have a valid _req member (the source's _req is initialized in its initialize method).
However, the situation is different when pushing to the edge.
When pushing to an edge, SrsRtmpConn::publishing calls acquire_publish, and if the current device is an edge, it will not call source->on_publish. As a result, the edge source's hls member's on_publish is not called, and the _req member of the edge source's hls member is empty.
An empty hls _req will cause a coredump. When source->dispose() calls hls->dispose, the SrsHls::dispose method will reference the empty _req, resulting in a coredump:
void SrsHls::dispose()
{
......
int hls_dispose = _srs_config->get_hls_dispose(_req->vhost);
......
}
Most of the above logic is also mentioned in #1055, but that PR has issues, so it was closed.