From patchwork Thu Sep 3 05:48:04 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Pluzhnikov X-Patchwork-Id: 8559 Received: (qmail 29247 invoked by alias); 3 Sep 2015 05:48:39 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 29232 invoked by uid 89); 3 Sep 2015 05:48:38 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.6 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW, SPF_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mail-vk0-f41.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc:content-type; bh=h5+ByRtWqKnToduyop0o/4X0nWVHHV83lQNNAq3T+v8=; b=DS6kvE7rRIHfeV3NpkgWHmTYxUQkBSYFq8lfDLM9eEaoKe3qYhqybUskZQKpbj/IIb 6wh1hs0K8YrmEI3VHG2xr1/TtHvjW0VwOcm2+Bk8SWp6GhJIK9UF+AzyNjHzQn+rtBqz VKV/Kql5VLH5MRv5jrCnwuqBafPNYLn/ZxST6i3j2TJN05exn7gCJRZj0t45spCXgp3i l6vnDnHzXJ9bIWKP5SN/38mMY8x8lxH/cIQh70X2xwavlRptlVo/qVaHjlTYais68hf1 VPoe3VPuOVvkqChi8pBGQugPM5c7U0XBrY+mWq5Od7rZqt5gkUYy32a1ywTGlZyAyYoa kXOw== X-Gm-Message-State: ALoCoQn+067Neq1el32T4/VUotsPowpBtWtILAuhZv17pYlvuRVpFRXgPNYcWYe8XqpB1wxWtVis X-Received: by 10.52.94.42 with SMTP id cz10mr44010473vdb.22.1441259313895; Wed, 02 Sep 2015 22:48:33 -0700 (PDT) MIME-Version: 1.0 In-Reply-To: <55E73436.1050305@redhat.com> References: <1440571295-20230-1-git-send-email-eggert@cs.ucla.edu> <55DFB7C7.50307@redhat.com> <55E06924.2000209@redhat.com> <55E73436.1050305@redhat.com> From: Paul Pluzhnikov Date: Wed, 2 Sep 2015 22:48:04 -0700 Message-ID: Subject: Re: [PATCH] Fix memory leak in printf_positional To: "Carlos O'Donell" Cc: Joseph Myers , Paul Eggert , GLIBC Devel On Wed, Sep 2, 2015 at 10:39 AM, Carlos O'Donell wrote: >>> I think at that point it becomes easier to just use a generator script >>> to write the test. Any objection to that? >> >> I don't object to that given an appropriate comment on why it is being >> used. > > Agreed. What's the appropriate place to put this comment? 2015-09-01 Paul Eggert Paul Pluzhnikov [BZ #18872] * stdio-common/Makefile (tst-printf-bz18872): New test. (tst-printf-bz18872-mem.out): Likewise. * stdio-common/tst-printf-bz18872.sh: Generate new test. * stdio-common/vfprintf.c: Fix memory leaks. diff --git a/stdio-common/Makefile b/stdio-common/Makefile index d0bf0e1..d91533f 100644 --- a/stdio-common/Makefile +++ b/stdio-common/Makefile @@ -57,17 +57,23 @@ tests := tstscanf test_rdwr test-popen tstgetln test-fseek \ bug19 bug19a tst-popen2 scanf13 scanf14 scanf15 bug20 bug21 bug22 \ scanf16 scanf17 tst-setvbuf1 tst-grouping bug23 bug24 \ bug-vfprintf-nargs tst-long-dbl-fphex tst-fphex-wide tst-sprintf3 \ - bug25 tst-printf-round bug23-2 bug23-3 bug23-4 bug26 tst-fmemopen3 + bug25 tst-printf-round bug23-2 bug23-3 bug23-4 bug26 tst-fmemopen3 \ + tst-printf-bz18872 test-srcs = tst-unbputc tst-printf ifeq ($(run-built-tests),yes) tests-special += $(objpfx)tst-unbputc.out $(objpfx)tst-printf.out \ + $(objpfx)tst-printf-bz18872-mem.out \ $(objpfx)tst-setvbuf1-cmp.out +generated += tst-printf-bz18872.c tst-printf-bz18872.mtrace \ + tst-printf-bz18872-mem.out endif include ../Rules +tst-printf-bz18872-ENV = MALLOC_TRACE=$(objpfx)tst-printf-bz18872.mtrace + ifeq ($(run-built-tests),yes) $(objpfx)tst-unbputc.out: tst-unbputc.sh $(objpfx)tst-unbputc $(SHELL) $< $(common-objpfx) '$(test-program-prefix)'; \ @@ -76,6 +82,13 @@ $(objpfx)tst-unbputc.out: tst-unbputc.sh $(objpfx)tst-unbputc $(objpfx)tst-printf.out: tst-printf.sh $(objpfx)tst-printf $(SHELL) $< $(common-objpfx) '$(test-program-prefix)'; \ $(evaluate-test) + +$(objpfx)tst-printf-bz18872.c: tst-printf-bz18872.sh + rm -f $@ + $(BASH) $^ > $@ +$(objpfx)tst-printf-bz18872-mem.out: $(objpfx)tst-printf-bz18872.out + $(common-objpfx)malloc/mtrace $(objpfx)tst-printf-bz18872.mtrace > $@; \ + $(evaluate-test) endif CFLAGS-vfprintf.c = -Wno-uninitialized diff --git a/stdio-common/tst-printf-bz18872.sh b/stdio-common/tst-printf-bz18872.sh new file mode 100755 index 0000000..75ec92f --- /dev/null +++ b/stdio-common/tst-printf-bz18872.sh @@ -0,0 +1,66 @@ +#!/bin/bash +# Copyright (C) 1999-2015 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with the GNU C Library; if not, see +# . + +# To test BZ #18872, we need a printf() with 10K arguments. +# Such a printf could be generated with non-trivial macro +# application, but it's simpler to generate the test source +# via this script. + +n_args=10000 + +cat <<'EOF' +#include +#include + +/* + Compile do_test without optimization: GCC 4.9/5.0/6.0 takes a long time + to build this source. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67396 */ +#pragma GCC push_options +#pragma GCC optimize ("-O0") + +int do_test (void) +{ + mtrace (); + printf ( +EOF + +for j in $(seq 1 $n_args); do + if [[ $(($j % 10)) == 1 ]]; then printf "\n"; fi + printf '"%%%d$s" ' $j +done + +printf ' "%%%d$s",' $(($n_args + 1)) + +for j in $(seq 1 $n_args); do + if [[ $(($j % 10)) == 1 ]]; then printf "\n"; fi + printf '"a", ' +done + +printf '"\\n");' + + +cat <<'EOF' + + return 0; +} +#pragma GCC pop_options + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" + +EOF diff --git a/stdio-common/vfprintf.c b/stdio-common/vfprintf.c index 0592e70..45c4779 100644 --- a/stdio-common/vfprintf.c +++ b/stdio-common/vfprintf.c @@ -2091,6 +2091,10 @@ printf_positional (_IO_FILE *s, const CHAR_T *format, int readonly_format, - specs[nspecs_done].end_of_fmt); } all_done: + if (__glibc_unlikely (specs_malloced)) + free (specs); + if (__glibc_unlikely (args_malloced != NULL)) + free (args_malloced); if (__glibc_unlikely (workstart != NULL)) free (workstart); return done;