public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Ingo Molnar <mingo@kernel.org>
To: Jakub Jelinek <jakub@redhat.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>,
	Peter Zijlstra <peterz@infradead.org>,
	Colin King <colin.king@canonical.com>,
	Ingo Molnar <mingo@redhat.com>,
	linux-kernel@vger.kernel.org, Richard Henderson <rth@twiddle.net>,
	Dan Carpenter <dan.carpenter@oracle.com>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	Andrew Morton <akpm@linux-foundation.org>
Subject: Re: Q: why didn't GCC warn about this uninitialized variable? (was: Re: [PATCH] perf tests: initialize sa.sa_flags)
Date: Thu, 3 Mar 2016 14:24:34 +0100	[thread overview]
Message-ID: <20160303132433.GA9460@gmail.com> (raw)
In-Reply-To: <20160303125542.GD3017@tucnak.redhat.com>


* Jakub Jelinek <jakub@redhat.com> wrote:

> On Thu, Mar 03, 2016 at 01:19:44PM +0100, Ingo Molnar wrote:
> >         struct sigaction sa;
> > 
> > 	...
> > 
> >         sigfillset(&sa.sa_mask);
> >         sa.sa_sigaction = segfault_handler;
> >         sigaction(SIGSEGV, &sa, NULL);
> > 
> > ... which uninitialized sa.sa_flags field GCC merrily accepted as proper C code, 
> > despite us turning on essentially _all_ GCC warnings for the perf build that exist 
> > under the sun:
> 
> GCC -W{,maybe-}uninitialized warning works only on SSA form, so in order to
> get that warning, either it needs to be some scalar that is uninitialized,
> or Scalar Replacement of Aggregates needs to be able to turn the structure
> into independent scalars.  Neither is the case here, as you take address of
> the struct when passing its address to sigaction, and that call can't be
> inlined nor is in any other way visible to the compiler, so that it could
> optimize both the caller and sigaction itself at the same time.
> 
> Even if GCC added infrastructure for tracking which bits/bytes in
> aggregates are or might be uninitialized at which point, generally,
>   struct XYZ abc;
>   foo (&abc);
> is so common pattern that warning here that the fields are uninitialized
> would have extremely high false positive ratio.

So at least for the kernel, people rely on external tools that do something like 
this anyway, and which are essentially annotated manually that duplicates much of 
the effort it would take to make a simple GCC solution work.

So in the aggregate, we already have this overhead _anyway_, except that:

 - some of the best tools are closed (so the techniques never enter the free 
   software world)

 - the fashion we get the feedback is per tool and inefficient

 - that there's also an inevitable lag between code added upstream and tools 
   finding uninitialized variables bugs.

So it's all highly inefficient and fragile.

There's also another cost, the cost of finding the bugs themselves - for example 
here's a recent upstream kernel fix:

  commit e01d8718de4170373cd7fbf5cf6f9cb61cebb1e9
  Author: Peter Zijlstra <peterz@infradead.org>
  Date:   Wed Jan 27 23:24:29 2016 +0100

    perf/x86: Fix uninitialized value usage
    
    When calling intel_alt_er() with .idx != EXTRA_REG_RSP_* we will not
    initialize alt_idx and then use this uninitialized value to index an
    array.
    
    When that is not fatal, it can result in an infinite loop in its
    caller __intel_shared_reg_get_constraints(), with IRQs disabled.
    
    Alternative error modes are random memory corruption due to the
    cpuc->shared_regs->regs[] array overrun, which manifest in either
    get_constraints or put_constraints doing weird stuff.
    
    Only took 6 hours of painful debugging to find this. Neither GCC nor
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    Smatch warnings flagged this bug.
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  --- a/arch/x86/kernel/cpu/perf_event_intel.c
  +++ b/arch/x86/kernel/cpu/perf_event_intel.c
  @@ -1960,7 +1960,8 @@ intel_bts_constraints(struct perf_event *event)
 
   static int intel_alt_er(int idx, u64 config)
   {
  -       int alt_idx;
  +       int alt_idx = idx;
  +
          if (!(x86_pmu.flags & PMU_FL_HAS_RSP_1))
                  return idx;

6 hours of PeterZ time translates to quite a bit of code restructuring overhead to 
eliminate false positive warnings...

So it would scale far better if we could do this kind of checking and annotation 
in the kernel code, C module by C module, interface by interface. We could also 
push the detection to the stage where such bugs are introduced: when new code is 
written - which scales a lot better than the current method of a handful of people 
looking at static analysis tools.

If GCC could warn in some really simplistic fashion (accepting tons of false 
positives), I'd definitely try to wade through the warnings, eliminate them step 
by step and make it all work for a couple of key subsystems I maintain. Most 
on-stack structures in the kernel are small, so there's very little reason to be 
overly clever with not initializing them.

Thanks,

	Ingo

  reply	other threads:[~2016-03-03 13:24 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-03-02 12:55 [PATCH] perf tests: initialize sa.sa_flags Colin King
2016-03-02 12:59 ` Peter Zijlstra
2016-03-02 13:03   ` Arnaldo Carvalho de Melo
2016-03-02 13:21     ` Peter Zijlstra
2016-03-02 13:23       ` Arnaldo Carvalho de Melo
2016-03-03 12:19         ` Q: why didn't GCC warn about this uninitialized variable? (was: Re: [PATCH] perf tests: initialize sa.sa_flags) Ingo Molnar
2016-03-03 12:25           ` Q: why didn't GCC warn about this uninitialized variable? Colin Ian King
2016-03-03 12:31           ` Måns Rullgård
2016-03-03 12:43             ` Ingo Molnar
2016-03-03 12:49               ` Joe Perches
2016-03-03 12:55           ` Q: why didn't GCC warn about this uninitialized variable? (was: Re: [PATCH] perf tests: initialize sa.sa_flags) Jakub Jelinek
2016-03-03 13:24             ` Ingo Molnar [this message]
2016-03-03 13:46               ` Jakub Jelinek
2016-03-03 14:04                 ` Ingo Molnar
2016-03-03 13:47               ` Ingo Molnar
2016-03-03 14:19                 ` Jakub Jelinek
2016-03-03 14:40                   ` Ingo Molnar
2016-03-03 14:53                   ` Ingo Molnar
2016-03-03 15:04                     ` Ingo Molnar
2016-03-02 13:02 ` [PATCH] perf tests: initialize sa.sa_flags Arnaldo Carvalho de Melo
2016-03-05  8:20 ` [tip:perf/core] perf tests: Initialize sa.sa_flags tip-bot for Colin Ian King

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20160303132433.GA9460@gmail.com \
    --to=mingo@kernel.org \
    --cc=acme@kernel.org \
    --cc=akpm@linux-foundation.org \
    --cc=colin.king@canonical.com \
    --cc=dan.carpenter@oracle.com \
    --cc=jakub@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.org \
    --cc=rth@twiddle.net \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox