From patchwork Sun Apr 16 11:28:19 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zalewa X-Patchwork-Id: 3428 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.3.129 with SMTP id 123csp891548vsd; Sun, 16 Apr 2017 04:28:34 -0700 (PDT) X-Received: by 10.223.173.23 with SMTP id p23mr15933199wrc.116.1492342114260; Sun, 16 Apr 2017 04:28:34 -0700 (PDT) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id r14si11526772wrb.298.2017.04.16.04.28.33; Sun, 16 Apr 2017 04:28:34 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id C231C68978C; Sun, 16 Apr 2017 14:28:22 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-lf0-f42.google.com (mail-lf0-f42.google.com [209.85.215.42]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id B1F43688345 for ; Sun, 16 Apr 2017 14:28:15 +0300 (EEST) Received: by mail-lf0-f42.google.com with SMTP id 88so8901426lfr.0 for ; Sun, 16 Apr 2017 04:28:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:to:references:from:message-id:date:user-agent:mime-version :in-reply-to; bh=ium2xMEPNRD3wDDGQZH7/Mt09ENyKYJ7Uhf26NCKo9A=; b=gVjiFcBjvN1O+hKe298aGE01WIAsuHtfeDyR67ksOfZozhLTR1YEuTPolGy9S32P9n dzkq1hIrN77uQ+6aV8MS5+rSBZd7yxs28a5MQEbWL6160OTxLwmqvgKRI0vlV3DdipQS LPuI2zm6I0MJWGk0f49OhDgd3PH07V4KswGzioM6Zr+kdqu5HRxyGOJYEIeWNz5Yk7Ua xfgQ479SLmyTG2kKZEKpRsavYm8Xn1E8eVvNk6quWeekV2vFc2rL8LPM5vTAnyOjPeBC W6baywJb1WAo0dxPMeHmQ9/rDIGRuKjshXZVcLD+seQkKrvsvVPIc1072QvYhXSmy2j+ wBSg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:references:from:message-id:date :user-agent:mime-version:in-reply-to; bh=ium2xMEPNRD3wDDGQZH7/Mt09ENyKYJ7Uhf26NCKo9A=; b=pfdzBnmg0MuWDI/V14MKvX866TXG4pR04PpJL7fnxijfIZJInROeXuL9ofG+KpdMLL vISf59OcNdQXzHXzhU7AlWmkaapXVP6EB+NtdtxG/URNXS2oN7ZgAX9FUqySmn5BAWqw Ri8OFd3gHhhxf6kEDQq0DEbsTUQrRJ5L4stoKulNEZIAY3rB9Jmxs4qeCMa7qxpoANy/ B5w0Xh9iPgIaQ7LdBpOsPDSLFHOf7XgJfriXGhOMXFIO9sQ0u4+zwvybZQlTqHxOGqZn VWg4MQoP61fH0Ew6iBk/lTakiI5QTYc6jXmTNZcB72mPCys3sa2hz6rq+/y436SeAAn8 ozog== X-Gm-Message-State: AN3rC/4cJ+W3bdkb2qa0l5T3zrUdSovKbONVjw/zWNq6I+w89dgV4GD7 bkOnF08ko7dI8elslFM= X-Received: by 10.25.56.11 with SMTP id f11mr1886550lfa.83.1492342102081; Sun, 16 Apr 2017 04:28:22 -0700 (PDT) Received: from [192.168.0.3] (89-67-32-30.dynamic.chello.pl. [89.67.32.30]) by smtp.googlemail.com with ESMTPSA id i13sm1417425lfe.30.2017.04.16.04.28.20 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 16 Apr 2017 04:28:21 -0700 (PDT) To: FFmpeg development discussions and patches References: <20170414152306.44af65fd@debian> <20170415151421.6e963590@debian> From: Zalewa Message-ID: Date: Sun, 16 Apr 2017 13:28:19 +0200 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Thunderbird/45.8.0 MIME-Version: 1.0 In-Reply-To: <20170415151421.6e963590@debian> Subject: Re: [FFmpeg-devel] [PATCH] ffserver: fix memory leaks pointed out by valgrind. X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Hello, Approach 2. This one reverses the shared state created by unlayer_stream() by nullifying the pointers to shared objects and then passes the "cleaned" AVFormatContext to avformat_free_context(). In result we have less code and less meddling with internals. See close_unlayered_format_context() function in ffserver.c. The drawback of this approach is that I also had to modify free_stream() in libavformat/utils.c because it was not expecting that the "codec" pointer in AVStream can be null. Let me know what you think. Best regards, Z. From 4af94953f03989447e10f9aae013b4afb158c2e0 Mon Sep 17 00:00:00 2001 From: Zalewa Date: Fri, 14 Apr 2017 09:26:18 +0200 Subject: [PATCH] ffserver: fix memory leaks pointed out by valgrind. Many memory leaks were created upon HTTP client disconnect. Many clients connecting & disconnecting rapidly could very quickly create leaks going into Gigabytes of memory. --- ffserver.c | 40 +++++++++++++++++++++++----------------- libavformat/utils.c | 8 +++++--- 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/ffserver.c b/ffserver.c index 8b819b6..1748d81 100644 --- a/ffserver.c +++ b/ffserver.c @@ -270,6 +270,22 @@ static void unlayer_stream(AVStream *st, LayeredAVStream *lst) COPY(recommended_encoder_configuration) } +/* NULLify all shared state that was applied in unlayer_stream. */ +static void detach_unlayered_stream(AVStream *st) +{ + st->codec = 0; + st->codecpar = 0; + st->recommended_encoder_configuration = 0; +} + +static void close_unlayered_format_context(AVFormatContext *ctx) +{ + int i = 0; + for (i = 0; i < ctx->nb_streams; ++i) + detach_unlayered_stream(ctx->streams[i]); + avformat_free_context(ctx); +} + static inline void cp_html_entity (char *buffer, const char *entity) { if (!buffer || !entity) return; @@ -936,9 +952,7 @@ static void close_connection(HTTPContext *c) ctx = c->rtp_ctx[i]; if (ctx) { av_write_trailer(ctx); - av_dict_free(&ctx->metadata); - av_freep(&ctx->streams[0]); - av_freep(&ctx); + avformat_free_context(ctx); } ffurl_close(c->rtp_handles[i]); } @@ -954,11 +968,9 @@ static void close_connection(HTTPContext *c) avio_close_dyn_buf(ctx->pb, &c->pb_buffer); } } - for(i=0; inb_streams; i++) - av_freep(&ctx->streams[i]); - av_freep(&ctx->streams); - av_freep(&ctx->priv_data); - } + close_unlayered_format_context(ctx); + c->pfmt_ctx = 0; + } if (c->stream && !c->post && c->stream->stream_type == STREAM_TYPE_LIVE) current_bandwidth -= c->stream->bandwidth; @@ -3836,7 +3848,7 @@ drop: } s->oformat = feed->fmt; for (i = 0; inb_streams; i++) { - AVStream *st = avformat_new_stream(s, NULL); // FIXME free this + AVStream *st = avformat_new_stream(s, NULL); if (!st) { http_log("Failed to allocate stream\n"); goto bail; @@ -3846,17 +3858,11 @@ drop: if (avformat_write_header(s, NULL) < 0) { http_log("Container doesn't support the required parameters\n"); avio_closep(&s->pb); - s->streams = NULL; - s->nb_streams = 0; - avformat_free_context(s); + close_unlayered_format_context(s); goto bail; } - /* XXX: need better API */ - av_freep(&s->priv_data); avio_closep(&s->pb); - s->streams = NULL; - s->nb_streams = 0; - avformat_free_context(s); + close_unlayered_format_context(s); } /* get feed size and write index */ diff --git a/libavformat/utils.c b/libavformat/utils.c index ba82a76..a392743 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -4266,9 +4266,11 @@ static void free_stream(AVStream **pst) av_freep(&st->index_entries); #if FF_API_LAVF_AVCTX FF_DISABLE_DEPRECATION_WARNINGS - av_freep(&st->codec->extradata); - av_freep(&st->codec->subtitle_header); - av_freep(&st->codec); + if (st->codec) { + av_freep(&st->codec->extradata); + av_freep(&st->codec->subtitle_header); + av_freep(&st->codec); + } FF_ENABLE_DEPRECATION_WARNINGS #endif av_freep(&st->priv_data);