Message ID | 20190522224053.15351-1-hjl.tools@gmail.com |
---|---|
State | Dropped |
Headers |
Received: (qmail 80492 invoked by alias); 22 May 2019 22:40:58 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: <libc-alpha.sourceware.org> List-Unsubscribe: <mailto:libc-alpha-unsubscribe-##L=##H@sourceware.org> List-Subscribe: <mailto:libc-alpha-subscribe@sourceware.org> List-Archive: <http://sourceware.org/ml/libc-alpha/> List-Post: <mailto:libc-alpha@sourceware.org> List-Help: <mailto:libc-alpha-help@sourceware.org>, <http://sourceware.org/ml/#faqs> Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 80413 invoked by uid 89); 22 May 2019 22:40:58 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-22.4 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, SPF_SOFTFAIL autolearn=ham version=3.3.1 spammy=HX-Languages-Length:1918, HContent-Transfer-Encoding:8bit X-HELO: mga02.intel.com From: "H.J. Lu" <hjl.tools@gmail.com> To: libc-alpha@sourceware.org Subject: [PATCH] Don't pass NULL pointer to error [BZ #24556] Date: Wed, 22 May 2019 15:40:53 -0700 Message-Id: <20190522224053.15351-1-hjl.tools@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit |
Commit Message
H.J. Lu
May 22, 2019, 10:40 p.m. UTC
GCC 9 with -O3 will issue a warning for passing NULL pointer to ‘%s': In file included from ../include/bits/error.h:1, from ../misc/error.h:57, from ../include/error.h:2, from bench-string.h:60, from bench-strstr.c:22: In function ‘error’, inlined from ‘do_one_test’ at bench-strstr.c:149:7, inlined from ‘do_test’ at bench-strstr.c:201:5, inlined from ‘test_main’ at bench-strstr.c:220:2: ../include/bits/../../misc/bits/error.h:42:5: error: ‘%s’ directive argument is null [-Werror=format-overflow=] 42 | __error_alias (__status, __errnum, __format, __va_arg_pack ()); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In function ‘error’, inlined from ‘do_one_test’ at bench-strstr.c:149:7, inlined from ‘do_test’ at bench-strstr.c:201:5, inlined from ‘test_main’ at bench-strstr.c:227:2: ../include/bits/../../misc/bits/error.h:42:5: error: ‘%s’ directive argument is null [-Werror=format-overflow=] 42 | __error_alias (__status, __errnum, __format, __va_arg_pack ()); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cc1: all warnings being treated as errors We can either disable -Werror=format-overflow= or don't pass NULL pointer to error. This patch does the latter. [BZ #24556] * benchtests/bench-strstr.c (do_one_test): Don't pass NULL pointer to error. --- benchtests/bench-strstr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Comments
* H. J. Lu: > In function ‘error’, > inlined from ‘do_one_test’ at bench-strstr.c:149:7, > inlined from ‘do_test’ at bench-strstr.c:201:5, > inlined from ‘test_main’ at bench-strstr.c:220:2: > ../include/bits/../../misc/bits/error.h:42:5: error: ‘%s’ directive argument is null [-Werror=format-overflow=] > 42 | __error_alias (__status, __errnum, __format, __va_arg_pack ()); > | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Isn't this warning wrong for glibc in general (but not for _dl_debug_printf)? I think printing "(null)" for null pointers is a widely-used GNU extension. Martin, I assume this warning is yours. Has this matter come up during its implementation? Thanks, Florian
On Thu, May 23, 2019 at 12:02 AM Florian Weimer <fweimer@redhat.com> wrote: > > * H. J. Lu: > > > In function ‘error’, > > inlined from ‘do_one_test’ at bench-strstr.c:149:7, > > inlined from ‘do_test’ at bench-strstr.c:201:5, > > inlined from ‘test_main’ at bench-strstr.c:220:2: > > ../include/bits/../../misc/bits/error.h:42:5: error: ‘%s’ directive argument is null [-Werror=format-overflow=] > > 42 | __error_alias (__status, __errnum, __format, __va_arg_pack ()); > > | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > Isn't this warning wrong for glibc in general (but not for > _dl_debug_printf)? > > I think printing "(null)" for null pointers is a widely-used GNU > extension. Only for limited cases: [hjl@gnu-cfl-1 tmp]$ cat x.c #include <stdio.h> char *p; int main () { printf("null string:%s\n", p); printf ("%s\n", p); return 0; } [hjl@gnu-cfl-1 tmp]$ gcc x.c [hjl@gnu-cfl-1 tmp]$ ./a.out null string:(null) Segmentation fault [hjl@gnu-cfl-1 tmp]$ > Martin, I assume this warning is yours. Has this matter come up during > its implementation? > > Thanks, > Florian
* H. J. Lu: > On Thu, May 23, 2019 at 12:02 AM Florian Weimer <fweimer@redhat.com> wrote: >> >> * H. J. Lu: >> >> > In function ‘error’, >> > inlined from ‘do_one_test’ at bench-strstr.c:149:7, >> > inlined from ‘do_test’ at bench-strstr.c:201:5, >> > inlined from ‘test_main’ at bench-strstr.c:220:2: >> > ../include/bits/../../misc/bits/error.h:42:5: error: ‘%s’ directive argument is null [-Werror=format-overflow=] >> > 42 | __error_alias (__status, __errnum, __format, __va_arg_pack ()); >> > | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >> >> Isn't this warning wrong for glibc in general (but not for >> _dl_debug_printf)? >> >> I think printing "(null)" for null pointers is a widely-used GNU >> extension. > > Only for limited cases: > > [hjl@gnu-cfl-1 tmp]$ cat x.c > #include <stdio.h> > > char *p; > > int > main () > { > printf("null string:%s\n", p); > printf ("%s\n", p); > return 0; > } > [hjl@gnu-cfl-1 tmp]$ gcc x.c > [hjl@gnu-cfl-1 tmp]$ ./a.out > null string:(null) > Segmentation fault > [hjl@gnu-cfl-1 tmp]$ Ah, because GCC transforms printf with "%s\n" to puts? Hmm. Thanks, Florian
On Thu, May 23, 2019 at 8:20 AM Florian Weimer <fweimer@redhat.com> wrote: > > * H. J. Lu: > > > On Thu, May 23, 2019 at 12:02 AM Florian Weimer <fweimer@redhat.com> wrote: > >> > >> * H. J. Lu: > >> > >> > In function ‘error’, > >> > inlined from ‘do_one_test’ at bench-strstr.c:149:7, > >> > inlined from ‘do_test’ at bench-strstr.c:201:5, > >> > inlined from ‘test_main’ at bench-strstr.c:220:2: > >> > ../include/bits/../../misc/bits/error.h:42:5: error: ‘%s’ directive argument is null [-Werror=format-overflow=] > >> > 42 | __error_alias (__status, __errnum, __format, __va_arg_pack ()); > >> > | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > >> > >> Isn't this warning wrong for glibc in general (but not for > >> _dl_debug_printf)? > >> > >> I think printing "(null)" for null pointers is a widely-used GNU > >> extension. > > > > Only for limited cases: > > > > [hjl@gnu-cfl-1 tmp]$ cat x.c > > #include <stdio.h> > > > > char *p; > > > > int > > main () > > { > > printf("null string:%s\n", p); > > printf ("%s\n", p); > > return 0; > > } > > [hjl@gnu-cfl-1 tmp]$ gcc x.c > > [hjl@gnu-cfl-1 tmp]$ ./a.out > > null string:(null) > > Segmentation fault > > [hjl@gnu-cfl-1 tmp]$ > > Ah, because GCC transforms printf with "%s\n" to puts? Hmm. > Yes.
* H. J. Lu: > On Thu, May 23, 2019 at 8:20 AM Florian Weimer <fweimer@redhat.com> wrote: >> >> * H. J. Lu: >> >> > On Thu, May 23, 2019 at 12:02 AM Florian Weimer <fweimer@redhat.com> wrote: >> >> >> >> * H. J. Lu: >> >> >> >> > In function ‘error’, >> >> > inlined from ‘do_one_test’ at bench-strstr.c:149:7, >> >> > inlined from ‘do_test’ at bench-strstr.c:201:5, >> >> > inlined from ‘test_main’ at bench-strstr.c:220:2: >> >> > ../include/bits/../../misc/bits/error.h:42:5: error: ‘%s’ directive argument is null [-Werror=format-overflow=] >> >> > 42 | __error_alias (__status, __errnum, __format, __va_arg_pack ()); >> >> > | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >> >> >> >> Isn't this warning wrong for glibc in general (but not for >> >> _dl_debug_printf)? >> >> >> >> I think printing "(null)" for null pointers is a widely-used GNU >> >> extension. >> > >> > Only for limited cases: >> > >> > [hjl@gnu-cfl-1 tmp]$ cat x.c >> > #include <stdio.h> >> > >> > char *p; >> > >> > int >> > main () >> > { >> > printf("null string:%s\n", p); >> > printf ("%s\n", p); >> > return 0; >> > } >> > [hjl@gnu-cfl-1 tmp]$ gcc x.c >> > [hjl@gnu-cfl-1 tmp]$ ./a.out >> > null string:(null) >> > Segmentation fault >> > [hjl@gnu-cfl-1 tmp]$ >> >> Ah, because GCC transforms printf with "%s\n" to puts? Hmm. >> > > Yes. We document the printf behavior: | If you accidentally pass a null pointer as the argument for a ‘%s’ | conversion, the GNU C Library prints it as ‘(null)’. We think this is | more useful than crashing. But it’s not good practice to pass a null | argument intentionally. So we should perhaps fix puts to behave in the same way. (puts isn't even annotated with __nonnull today.) Thanks, Florian
On 5/23/19 9:41 AM, Florian Weimer wrote: > * H. J. Lu: > >> On Thu, May 23, 2019 at 8:20 AM Florian Weimer <fweimer@redhat.com> wrote: >>> >>> * H. J. Lu: >>> >>>> On Thu, May 23, 2019 at 12:02 AM Florian Weimer <fweimer@redhat.com> wrote: >>>>> >>>>> * H. J. Lu: >>>>> >>>>>> In function ‘error’, >>>>>> inlined from ‘do_one_test’ at bench-strstr.c:149:7, >>>>>> inlined from ‘do_test’ at bench-strstr.c:201:5, >>>>>> inlined from ‘test_main’ at bench-strstr.c:220:2: >>>>>> ../include/bits/../../misc/bits/error.h:42:5: error: ‘%s’ directive argument is null [-Werror=format-overflow=] >>>>>> 42 | __error_alias (__status, __errnum, __format, __va_arg_pack ()); >>>>>> | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >>>>> >>>>> Isn't this warning wrong for glibc in general (but not for >>>>> _dl_debug_printf)? >>>>> >>>>> I think printing "(null)" for null pointers is a widely-used GNU >>>>> extension. >>>> >>>> Only for limited cases: >>>> >>>> [hjl@gnu-cfl-1 tmp]$ cat x.c >>>> #include <stdio.h> >>>> >>>> char *p; >>>> >>>> int >>>> main () >>>> { >>>> printf("null string:%s\n", p); >>>> printf ("%s\n", p); >>>> return 0; >>>> } >>>> [hjl@gnu-cfl-1 tmp]$ gcc x.c >>>> [hjl@gnu-cfl-1 tmp]$ ./a.out >>>> null string:(null) >>>> Segmentation fault >>>> [hjl@gnu-cfl-1 tmp]$ >>> >>> Ah, because GCC transforms printf with "%s\n" to puts? Hmm. >>> >> >> Yes. > > We document the printf behavior: > > | If you accidentally pass a null pointer as the argument for a ‘%s’ > | conversion, the GNU C Library prints it as ‘(null)’. We think this is > | more useful than crashing. But it’s not good practice to pass a null > | argument intentionally. > > So we should perhaps fix puts to behave in the same way. (puts isn't > even annotated with __nonnull today.) There are two transformations that don't handle null pointers: printf to puts and sprintf to strcpy (or memcpy). They have been in GCC since at least 2005, and in Clang since at least 2011. I'd rather discourage relying on the Glibc printf extension than remove the transformations or suppress the warning. Martin
On 5/23/19 9:21 AM, Martin Sebor wrote: > I'd rather discourage > relying on the Glibc printf extension than remove the transformations > or suppress the warning. I agree that this is a good way to go, as we can't keep fighting compilers forever. I wrote a patch implementing this suggestion and filed a bug report proposing it here: https://sourceware.org/bugzilla/show_bug.cgi?id=24616
On Thu, May 23, 2019 at 12:35 PM Paul Eggert <eggert@cs.ucla.edu> wrote: > > On 5/23/19 9:21 AM, Martin Sebor wrote: > > I'd rather discourage > > relying on the Glibc printf extension than remove the transformations > > or suppress the warning. > > I agree that this is a good way to go, as we can't keep fighting > compilers forever. I wrote a patch implementing this suggestion and > filed a bug report proposing it here: > > https://sourceware.org/bugzilla/show_bug.cgi?id=24616 > GCC 9 can't build bench today. What should we do?
On 6/17/19 9:32 PM, H.J. Lu wrote: > On Thu, May 23, 2019 at 12:35 PM Paul Eggert <eggert@cs.ucla.edu> wrote: >> >> On 5/23/19 9:21 AM, Martin Sebor wrote: >>> I'd rather discourage >>> relying on the Glibc printf extension than remove the transformations >>> or suppress the warning. >> >> I agree that this is a good way to go, as we can't keep fighting >> compilers forever. I wrote a patch implementing this suggestion and >> filed a bug report proposing it here: >> >> https://sourceware.org/bugzilla/show_bug.cgi?id=24616 >> > > GCC 9 can't build bench today. What should we do? > Sorry. I've just recognized this thread. I've already posted a patch which also fixes "make bench" with gcc 9: "[PATCH] Fix gcc 9 build errors for make xcheck." https://www.sourceware.org/ml/libc-alpha/2019-06/msg00374.html Bye Stefan
diff --git a/benchtests/bench-strstr.c b/benchtests/bench-strstr.c index b4cd141083..104dd979f0 100644 --- a/benchtests/bench-strstr.c +++ b/benchtests/bench-strstr.c @@ -147,7 +147,7 @@ do_one_test (impl_t *impl, const char *s1, const char *s2, char *exp_result) if (res != exp_result) { error (0, 0, "Wrong result in function %s %s %s", impl->name, - res, exp_result); + res, exp_result ? exp_result : "(null)"); ret = 1; } }