[libvirt] [PATCH (RFC?)] Remove usage of __attribute__((nonnull))
Martin Kletzander
mkletzan at redhat.com
Wed Apr 5 11:13:28 UTC 2017
On Wed, Apr 05, 2017 at 06:53:10AM -0400, John Ferlan wrote:
>
>
>On 04/05/2017 05:06 AM, Daniel P. Berrange wrote:
>> On Tue, Apr 04, 2017 at 09:51:47PM +0200, Martin Kletzander wrote:
>>> On Tue, Apr 04, 2017 at 04:10:59PM +0100, Daniel P. Berrange wrote:
>>>> On Tue, Mar 28, 2017 at 01:46:31PM +0200, Martin Kletzander wrote:
>>>>> The attribute (defined as ATTRIBUTE_NONNULL) was added long time
>>>>> ago (2009), but in 2012 (commit eefb881d4683) it was disabled for
>>>>> normal build, making it used only when coverity was building libvirt
>>>>> or on special request. It was disabled because it was being misused
>>>>> and misunderstood -- the attribute is there as an optimization hint
>>>>> for the compiler, not to enhance static analysis.
>>>>
>>>> Actually the attribute does both and the primary intention of the attribute
>>>> *is* build time warnings and/or static analysis warnings:
>>>>
>>>> [quote]
>>>> 'nonnull (ARG-INDEX, ...)'
>>>> The 'nonnull' attribute specifies that some function parameters
>>>> should be non-null pointers. For instance, the declaration:
>>>>
>>>> extern void *
>>>> my_memcpy (void *dest, const void *src, size_t len)
>>>> __attribute__((nonnull (1, 2)));
>>>>
>>>> causes the compiler to check that, in calls to 'my_memcpy',
>>>> arguments DEST and SRC are non-null. If the compiler determines
>>>
>>> This, however, happens only if we pass NULL directly. There's not much
>>> of a deeper analysis involved IIRC.
>>
>> Yep, coverity is needed to do most deeper analysis of NULL handling
>>
>>>> The use of nonnull attribute would help the compiler report
>>>> mistakes, but the compiler only catches some easy cases at build
>>>> time.
>>>>
>>>
>>> It would. But for now it is only enabled if STATIC_ANALYSIS=1 and that
>>> is only set if you are running in coverity (or explicitly specify that
>>> during configure, which almost nobody does).
>>
>> Easily solvable by enabling it in CI.
>>
>>>> So the key issue is whether we have enough confidence in fact that
>>>> our calling methods really will be passing a non-NULL value or not.
>>>>
>>>
>>> Well, I definitely don't. But from what I see on the list, people only
>>> add these attributes to function declarations if they are added (read:
>>> copy-pasted) near other functions that have this attribute. That is
>>> what sparked this attribute removal idea. So there are *lot of*
>>> functions that don't fail gracefully on NULL parameters because nobody
>>> added (or fixed) the attributes when modifying the code.
>>>
>>>> If we're not confident in our callers for a method, then we should
>>>> remove nonnull, and have an explicit 'if (arg == NULL)' check in
>>>> the code instead.
>>>>
>>>
>>> We already behave like that. Except John (and me for a while), everyone
>>> has ATTRIBUTE_NONNULL defined as nothing. And I believe no distribution
>>> is defining STATIC_ANALYSIS when building their packages. However that
>>> leads to unnecessary late removals of ATTRIBUTE_NONNULL specifications
>> g> for some functions later on, which in turn might cause problems with
>>> backports and from my point of view it just causes mess and unnecessary
>>> time spent on it. What's worse, if you decide to compile with the
>>> static analysis turned on, you don't get a check for the fact that all
>>> devices are handled in virDomainDefCheckABIStabilityFlags() and
>>> virDomainDeviceInfoIterateInternal().
>>
>> I don't see the virDomainDefCheckABIStabilityFlags thing as a real problem. That code is
>> there to check for some silly mistakes at build time, so it is not something that needs to
>> be enable by everyone. It really just needs to be run once by someone/something - IOW as
>> long as our CI triggers that codepath the sanity check is serving its purpose.
>>
>>>
>>>> Some projects might use asserts() against args being non-NULL, but
>>>> libvirt tends to try to return soft errors. Given this, it could be
>>>> better use to 'if (arg == NULL)' checks in general, over nonnull,
>>>> unless we have high confidence in callers.
>>>>
>>>>> However, it is used until today in many places and since it is
>>>>> disabled by default, it just screws up builds with STATIC_ANALYSIS
>>>>> enabled.
>>>>
>>>> Screws them up in what way ?
>>>>
>>>
>>> As said before, the warnings are found out only by some, so it needs to
>>> be fixed in a separate patch and so on.
>>
>> I don't see that as a real problem. It is no different situation to fact that someone writes
>> and patch on Linux and doesn't test Windows or BSD, or a different older version of Linux,
>> etc. We never expect developers to test all situations. The key is to ensure that we have
>> CI coverage of the option. I thought that John still had a nightly coverity job running that
>> would trigger the -DSTATIC_ANALYSIS codepaths. If that's not the case, then we'd wnat to look
>> at enabling that in one of the centos CI jobs.
>>
>
>I still have a run of Coverity every night although I have been less
>diligent about checking errors lately. Mainly because generally things
>that are considered a false positive were being rejected when I posted
>patches. I keep about 20 patches in a local branch.
>
>There was a point quite a few months ago where my nightly build started
>failing because either I changed the Coverity version or the compiler
>version on my laptop - cannot recall exactly. That resulted in a bunch
>more local patches until I finally had too many and posted that pile
>late last month. Enabling static analysis in CI builds was something I
>suggested in my cover - although now I've done it for my every day work
>environment so I will see the problems much sooner.
>
Yeah, but my points were: a) why only CI? b) we need not to enable
static_analysis flag, but rather not define ATTRIBUTE_NONNULL to nothing
if STATIC_ANALYSIS is set. The STATIC_ANALYSIS macro is used to disable
some code that we want to be using in both CI and local builds.
>John
>
>>>
>>>>> Remove that attribute and all its usages.
>>>>
>>>> Do we not use '-DSTATIC_ANLYSIS' when running through coverity, so
>>>> that coverity sees the nonnull annotations and thus is able to do
>>>> more advanced checks for NULL args ? If so, removing it would make
>>>> coverity miss bugs.
>>>>
>>>
>>> STATIC_ANALYSIS is automatically set if configure realizes it's running
>>> under coverity. However we don't run coverity that often. More often
>>> we run some build with STATIC_ANALYSIS turned on explicitly.
>>>
>>>>> Signed-off-by: Martin Kletzander <mkletzan at redhat.com>
>>>>
>>>>
>>>>> diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c
>>>>> index 891238bcbe0d..5cd3fa4ebccb 100644
>>>>> --- a/daemon/libvirtd.c
>>>>> +++ b/daemon/libvirtd.c
>>>>> @@ -410,7 +410,7 @@ static void daemonInitialize(void)
>>>>> #undef VIR_DAEMON_LOAD_MODULE
>>>>>
>>>>>
>>>>> -static int ATTRIBUTE_NONNULL(3)
>>>>> +static int
>>>>> daemonSetupNetworking(virNetServerPtr srv,
>>>>> virNetServerPtr srvAdm,
>>>>> struct daemonConfig *config,
>>>>
>>>> If we do decide to remove ATTRIBUTE_NONNULL annotations, then we need to
>>>> make sure the method impls have suitable 'if (args == NULL) ....' checks
>>>> that handle this safely.
>>>>
>>>
>>> As said above, I believe there are many functions that do not use
>>> ATTRIBUTE_NONNULL and would segfault on a NULL argument. Let's see how
>>> long it takes me to find one.
>>>
>>> ... (10 seconds later)
>>>
>>> Look, the one I mentioned (virDomainDefCheckABIStabilityFlags) is one of
>>> them. It dereferences both pointers immediately. I bet there are lot
>>> of those. It's good that most of them would be caught in tests if it
>>> was obvious.
>>
>> Sure, and adding / removing ATTRIBUTE_NONNULL doesn't really make any
>> difference to whether that is a bug or not. ie if we do have some code
>> somewhere that could cause NULL to be passed, then we have a bug regardless
>> of whether we add ATTRIBUTE_NONNULL annotation to that method or not. If we
>> did add the annotation though, we might get a notification of the bug from
>> coverity. So from this POV, ATTRIBUTE_NONNULL feels beneficial to me and
>> rather than removing it, we should instead make an effort to look for any
>> methods which defererence pointer args and add more ATTRIBUTE_NONNULL
>> annotations to them.
>>
>> In fact we could go as far to say that every single method which takes a
>> pointer arg should have ATTRIBUTE_NONNULL unless there's a clear valid
>> use case for it to accept NULL.
>>
>>> So the other thing to do would be to ditch commit eefb881d4683 and the
>>> whole STATIC_ANALYSIS and just add a comment for making coverity happy
>>> on those two aforementioned occasions.
>>
>>
>>
>> Regards,
>> Daniel
>>
>
>--
>libvir-list mailing list
>libvir-list at redhat.com
>https://www.redhat.com/mailman/listinfo/libvir-list
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: Digital signature
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20170405/d00e799c/attachment-0001.sig>
More information about the libvir-list
mailing list