Re: SIGSEGV on fclose

From: Andi Kleen (ak@suse.de)
Date: Thu Jul 13 2000 - 13:03:18 EDT

  • Next message: Jes Sorensen: "Re: Object Oriented Linux"

    On Thu, Jul 13, 2000 at 10:51:41AM -0600, William Astle wrote:
    > On Thu, 13 Jul 2000, Andi Kleen wrote:
    >
    > > The original poster passed it a NULL pointer though, not a random pointer.
    > > It would be certainly reasonable to check for NULL pointer in fclose,
    > > similar to free()
    >
    > It seems to me that the argument is about
    >
    > fclose(fp);
    > fclose(fp);

    No it wasn't. The original example was:

    /*--------------------------------------------*/
    #include <stdio.h>

    FILE *new;

    main () {

       fclose (new); /* <---- SIGSEGV on linux only */
    }
    /*--------------------------------------------*/

    There is a common and useful[1] programming style where you try to close
    all resources in case of an error in a common function. It is useful to
    not have to write if (ptr != NULL) closeit(ptr) all the time to handle
    the case where you bombed out in the middle.

    The alternative is the error prone and ugly:

    if (a = alloca()) {
            if (b = allocb()) {
                    if (c = allocc()) {
                            if (d =allocd()) {
                                    do_real_work();
                                    freed(d);
                            }
                            freec(c);
                    }
                    freeb(b);
            }
            freea(a);
    }

    which is IMHO just asking for obscure bugs in error paths.

    /* a b c d are NULL */
    a = alloca();
    b = allocb();
    c = allocc();
    d = allocd();
    if (a && b && c && d)
            do_real_work();
    freea(a);
    freeb(b);
    freec(c);
    freed(d);

    Which one do you prefer ?
    So handling NULL in the low level library free routine makes it much
    less likely that you screw up during resource cleanups. Writing
    if (ptr != NULL) before free all the time is just redundant and can
    be easily forgotten.

    About the only argument I see is to make one undefined behaviour in ISO
    C crash instead of behave sanely to point out a potential portability
    problem to some hosts (e.g. most Unixes seem to get this correct) early.
    I prefer a sane behaviour instead though.

    -Andi

    [1] It simplifies error handling and makes it more likely to be correct.

    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.rutgers.edu
    Please read the FAQ at http://www.tux.org/lkml/



    This archive was generated by hypermail 2b29 : Thu Jul 13 2000 - 13:08:32 EDT