Want to read Slashdot from your mobile device? Point it at m.slashdot.org and keep reading!

 



Forgot your password?
typodupeerror
×
Programming Software Apache IT Technology

Software Code Quality Of Apache Analyzed 442

fruey writes "Following Reasoning's February analysis of the Linux TCP/IP stack (putting it ahead of many commercial implementations for it's low error density), they recently pitted Apache 2.1 source code against commercial web server offerings, although they don't say which. Apparently, Apache is close, but no cigar..."
This discussion has been archived. No new comments can be posted.

Software Code Quality Of Apache Analyzed

Comments Filter:
  • by ElectronOfAtom ( 685701 ) on Monday July 07, 2003 @10:29AM (#6382680)
    The difference is that now that someone has found 31 errors in the open source Apache software, they will be fixed fairly quickly whereas closed source software will have to have the company do a cost-benefit analysis, put together a team to do the fixes, probably charge to put out patches or minor upgrades (assuming the product is Microsoft's IIS ;b)...
  • by David McBride ( 183571 ) <david+slashdot@ d w m.me.uk> on Monday July 07, 2003 @10:31AM (#6382697) Homepage
    Umm, Apache 2.1 hasn't been released yet. Current latest stable is 2.0.46 [apache.org].

    I can only assume that they're looking through the current DEVELOPMENT codebase -- finding a higher ``defect density'' in such a development codebase compared with commercial offerings is not exactly unexpected.

    They're also some automated code inspection product; the press release doesn't go into details as to the severity of the defects found or the testing methodology.

    It'll be necessary to read through the full report [reasoning.com] before drawing any sound conclusions.
  • by Anonymous Coward on Monday July 07, 2003 @10:31AM (#6382702)
    AC, thank you for contacting Reasoning!

    Here are the links to the Apache Open Source Inspection Report you requested:

    Apache Defect Report: http://www.reasoning.com/pdf/Apache_Defect_Report. pdf [reasoning.com]
    Apache Metric Report: http://www.reasoning.com/pdf/Apache_Metric_Report. pdf [reasoning.com]

    Reasoning provides the world's leading automated software inspection service. We boost the productivity of development teams by finding software defects faster and at a far lower cost than traditional approaches. Please let me know if you would like additional information. Thank you again for contacting Reasoning!

    Sincerely,
    Reasoning

  • by David McBride ( 183571 ) <david+slashdot@ d w m.me.uk> on Monday July 07, 2003 @10:38AM (#6382751) Homepage
    The above link wants your email address. Bah.

    The direct URLs for the reports are:
    Defect Report [reasoning.com]
    Metric Report [reasoning.com]
  • by phre4k ( 627961 ) <esbenp&cs,aau,dk> on Monday July 07, 2003 @10:39AM (#6382753)
    Prette lame when we are talking server software where apache has the lead. (apache 63% vs IIS 25% netcraft.com)

    /Esben
  • Re:No cigar, my ass. (Score:4, Informative)

    by HowlinMad ( 220943 ) on Monday July 07, 2003 @10:40AM (#6382768) Homepage Journal
    FYI

    5100 != 58,944

    58,944 is the number from the article.
  • by Cancel ( 596312 ) on Monday July 07, 2003 @10:42AM (#6382790)
    That's not what they're saying at all. In fact, Reasoning concluded that there was no statistically significant difference in 'defect density' between Apache and the unnamed commercial product.
    "In our February study that compared the defect density of the Linux TCP/IP stack to the average defect density of commercially developed TCP/IP stacks, we concluded that Open Source had a significantly lower defect density compared to commercial equivalents," said Bill Payne, President & CEO of Reasoning. "We received numerous inquiries about that study and took seriously requests for us to examine defect density rates in a less mature Open Source application and compare it with the commercial equivalent. Taking advantage of our database of automated software code inspection projects, we were able to do exactly that,
    and found the difference in defect density between the two was not significant." (emphasis mine)
  • Re:Defect? (Score:5, Informative)

    by richie2000 ( 159732 ) <rickard.olsson@gmail.com> on Monday July 07, 2003 @10:48AM (#6382816) Homepage Journal
    From the report:
    NULL Pointer Dereference (Expression dereferences a NULL pointer) 29 instances
    Uninitialized Variable (Variable is not initialized prior to use) 2 instances

    They also list the files and code snippets where the errors were found.

    In addition, the comparison is made against an industry average of commercial code they have tested this way, NOT against other webservers.

  • Defect Details (Score:5, Informative)

    by Eustace Tilley ( 23991 ) * on Monday July 07, 2003 @10:51AM (#6382842) Journal
    Interested persons can download the full defect report free of charge. [reasoning.com]

    Some things I found interesting:
    1. Apache 2.1 (dev) is a mere 76,208 LOC.
    2. No memory leaks detected
    3. 29 NULL pointer dereferences
    4. 2 Uninitialized variables
    5. No bounds errors, no bad deallocs
    6. otherchild.c had a rate of 7 NULL pointer dereferences per 1000 KSLC


    7. One of the explanations (given by Reasoning) for a NULL pointer dereference is "can occur in low memory conditions," which I think means the original allocator did not check for malloc failure.

      So you can get a sense of what a defect looks like, here is #21. The orignal uses bold and fonts improve readability, but I don't know how to reproduce that in slashcode:
      DEFECT CLASS: Null Pointer Dereference

      DEFECT ID 21

      LOCATION: httpd-2.1/srclib/apr/misc/unix/otherchild.c : 137

      DESCRIPTION The local pointer variable cur, declared on line 126, and assigned on line 128, may
      be NULL where it is dereferenced on line 137.
      PRECONDITIONS The conditional expression (cur) on line 129 evaluates to false.
      CODE FRAGMENT
      124 APR_DECLARE(void) apr_proc_other_child_unregister(void *data)
      125 {
      126 apr_other_child_rec_t *cur;
      127
      128 cur = other_children;
      129 while (cur) {
      130 if (cur->data == data) {
      131 break;
      132 }
      133 cur = cur->next;
      134 }
      135
      136 /* segfault if this function called with invalid parm */
      137 apr_pool_cleanup_kill(cur->p, cur->data, other_child_cleanup);
      138 other_child_cleanup(data);
      139 }
  • Re:Wrong Math (Score:2, Informative)

    by BigBadDude ( 683684 ) on Monday July 07, 2003 @10:52AM (#6382849)
    yeah, that was actually my point. nice someone got it :)

    The source of most free software [KDE is an exception] tend to be smaller, more readable and more effective. Ever wondred why winword.exe is 10.598.984 bytes?
  • by ByTor-2112 ( 313205 ) on Monday July 07, 2003 @10:53AM (#6382857)
    29 possible "null dereferences" and 2 possible "uninitialized variables". Some of them are simple "fail to check return value of malloc() for null", and others are not bugs in the code but bugs in the logic of the scanner. This is, of course, a precursory review of their document. All in all, these are absolutely minor bugs if they are real at all.
  • by BigBadDude ( 683684 ) on Monday July 07, 2003 @10:59AM (#6382892)

    One of the explanations (given by Reasoning) for a NULL pointer dereference is "can occur in low memory conditions," which I think means the original allocator did not check for malloc failure.


    appache got its own malloc() that kills the child (and closes connection) if it fails to allocate enough bytes.
  • by bofkentucky ( 555107 ) <bofkentucky&gmail,com> on Monday July 07, 2003 @11:05AM (#6382927) Homepage Journal
    now they do, 2.0.x are stable, production releases 2.1.x are testing branches
  • by arrogance ( 590092 ) on Monday July 07, 2003 @11:05AM (#6382930)
    Defect Report [reasoning.com]

    Metric Report [reasoning.com]

    They make you fill out a form that asks for your email and then do an opt out checkbox at the bottom of the form (you have to check it to NOT get spam from them). The site's a bit slashdotted right now though.

  • by Jeremy Erwin ( 2054 ) on Monday July 07, 2003 @11:07AM (#6382942) Journal
    If you download the defect report (available from here* [reasoning.com], it will explain exactly where the bugs are.
    For instance, the first bug is

    DEFECT CLASS: Null Pointer Dereference DEFECT ID 1
    LOCATION: httpd-2.1/modules/aaa/mod_auth_basic.c :291
    DESCRIPTION The local pointer variable current_provider, declared on line 235, and assigned on line 257, may be NULL where it is dereferenced on line 291.
    PRECONDITIONS The conditional expression (res) on line 253 evaluates to false AND
    The conditional expression (!current_provider) on line 264 evaluates to true AND
    The conditional expression (!provider || !provider->check_password) on line 268
    evaluates to false AND
    The conditional expression (auth_result != AUTH_USER_NOT_FOUND) on line
    282 evaluates to false AND
    The conditional expression (!conf->providers) on line 287 evaluates to false.


    Each bug report is followed by the snippet of source code containing the defect.

    The metric report simply reports the statistics. For instance, the most bug ridden file is otherchild.c. The most common bug class is "dereferencing a NULL pointer".

    If the Apache developers simply want to fix the bugs, they can use the Defect Report. If they want conduct a brutal purge of their contributors, they can use the Metric report.

    *Yes, Reasoning wants an email address. They will mail you a URL (a rather simple one at that) to access the reports.
  • This is a dupe (Score:3, Informative)

    by presroi ( 657709 ) <neubau@presroi.de> on Monday July 07, 2003 @11:08AM (#6382950) Homepage
    This Slashdot-Posting [slashdot.org] was featuring the same PR from Reasoning.
  • by Eustace Tilley ( 23991 ) * on Monday July 07, 2003 @11:32AM (#6383130) Journal
    Hmm, Defect 10 is a little trickier:
    DEFECT CLASS: Null Pointer Dereference DEFECT ID 10
    LOCATION: httpd-2.1/modules/mappers/mod_negotiation.c : 2495
    DESCRIPTION The local pointer variable arr, declared on line 2349, and assigned on line 2365, may be NULL where it is dereferenced on line 2495. This NULL pointer dereference only happens in an Out Of Memory context.

    PRECONDITIONS The conditional expression (neg->send_alternates && neg->avail_vars->nelts) on
    line 2364 evaluates to true AND
    The function apr_array_make, called on line 2365, returns NULL AND
    The conditional expression (neg->send_alternates && neg->avail_vars->nelts) on
    line 2494 evaluates to true.

    CODE FRAGMENT
    2336 static void set_neg_headers(request_rec *r, negotiation_state *neg,
    2337 int alg_result)
    2338 {
    ...
    2349 apr_array_header_t *arr;
    ...
    2364 if (neg->send_alternates && neg->avail_vars->nelts)
    2365 arr = apr_array_make(r->pool, max_vlist_array, sizeof(char *));
    2366 else
    2367 arr = NULL;
    ...
    2494 if (neg->send_alternates && neg->avail_vars->nelts) {
    2495 arr->nelts--; /* remove last comma */
    2496 apr_table_mergen(hdrs, "Alternates",
    2497 apr_array_pstrcat(r->pool, arr, '\0'));
    2498 }
    2499
    2500 if (neg->is_transparent || vary_by_type || vary_by_language ||
    2501 vary_by_language || vary_by_charset || vary_by_encoding) {
    2502
    2503 apr_table_mergen(hdrs, "Vary", 2 + apr_pstrcat(r->pool,
    2504 neg->is_transparent ? ", negotiate" : "",
    2505 vary_by_type ? ", accept" : "",
    I traced through the code on lxr.webperf.org and it appears that pool_alloc can return NULL.

    Is the idea that this code will never be executed in an out-of-memory condition, because it is only executed by a child, and the child dies automatically on malloc failure?
  • by tomstdenis ( 446163 ) <tomstdenis@gma[ ]com ['il.' in gap]> on Monday July 07, 2003 @11:39AM (#6383182) Homepage
    Neat, well its been nearly a year since I used splint last. Maybe they just have updated the code.

    Eitherway I prefer

    "--std=c99 -pedantic -Wall -W -Wshadow" as my warnings for GCC. It catches a shit-load of common coding foobars and also ensures the code follows ISO C [definite bonus].

    Tom
  • by coliva ( 311680 ) on Monday July 07, 2003 @11:39AM (#6383187)
    I found it interesting that they used a 1/31/03 version of Apache 2.1-dev. This wasn't mentioned anywhere in the article- either that it was a development version or that their analysis was of a development-level piece of software 5 months ago.

    It would be interesting to see how far 2.1 has progressed since then.
  • by Skjellifetti ( 561341 ) on Monday July 07, 2003 @11:46AM (#6383229) Journal
    None of that bug report is at all useful if there is no logical way for all of those preconditions they listed to actually be met.

    Well, Yes and No. The problem is that there may be no logical way that the pointer may be NULL today. But tomorrow, a new coder will add something that modifies the preconditions and suddenly that pointer can indeed be NULL. Even where you are sure that a condition is impossible, it is usually a good idea to check for NULL in order to avoid future errors.

    And for those who haven't seen this trick before, a nice habit to get into is to write your checks like so:
    if (NULL == myPointer) { ... }
    This lets the compiler catch errors where you meant '==' rather than just '='. As in
    /* Do we really mean this? */
    if (myPointer = NULL) { ... }
  • by Q2Serpent ( 216415 ) on Monday July 07, 2003 @11:47AM (#6383238)
    Obviously they had source code access. That's the way reasoning works - their program reads in and parses the source code, generates a parse tree, and then analyzes that. That's why it's called "static analysis" - no binaries, runtimes, or testcases are needed, and errors can even be found in code that is never excercised.
  • BINGO (Score:3, Informative)

    by Anonymous Coward on Monday July 07, 2003 @12:11PM (#6383393)
    In almost every case they listed the pathway was via a failed malloc.

    Apache has it's own malloc that kills the connection (and the child) if it fails.

    That code can never be reached. Their test is invalid.
  • Actually, I've found that fixing bugs in large projects is about the same whether or not you are familiar with the project, provided that the author was no smoking crack at the time he wrote it.

    For example, I managed to code, test, and patch a "fix" for PostgreSQL this weekend in under 2 hours, having never seen the code before.

    The "fix" wasn't a bug, per se, i't just that the output of pg_dump wasn't optimal in my usage for dumping the schema for CVS revision control. I added two flags, -m -M, which molded the output to my liking.

    If you haven't seen your code in two months, you and an outsider have about the same chance at finding and detecting bugs/misfeatures.
  • by coliva ( 311680 ) on Monday July 07, 2003 @12:37PM (#6383567)
    Correct. The title of the report is clear. However, that info didn't make it into the news release that they put out.
  • by Phronesis ( 175966 ) on Monday July 07, 2003 @12:47PM (#6383633)
    This lets the compiler catch errors where you meant '==' rather than just '='.

    MY compiler (Microsoft C++) does catch this

    if (myPointer = NULL) { ... }
    and issues a warning. Doesn't gcc?
  • by conway ( 536486 ) on Monday July 07, 2003 @12:53PM (#6383676)
    Turning on all warnings in gcc (-Wall) catches this, and many other common errors.
    (In effect it does a lint-like check on the source.)
  • by Anonymous Coward on Monday July 07, 2003 @12:56PM (#6383697)
    Yes, GCC does issue a warning for that. However, it should be noted that this is perfectly valid C.

    GCC does not issue a warning for this, though:
    if( (ptr=NULL) );
    Note parenthesis.
  • by Rasta Prefect ( 250915 ) on Monday July 07, 2003 @12:58PM (#6383705)
    This lets the compiler catch errors where you meant '==' rather than just '='.
    MY compiler (Microsoft C++) does catch this

    if (myPointer = NULL) { ... }
    and issues a warning. Doesn't gcc?


    Yes, it does. So does every other C compiler I've ever used (quite a few). I suspect the original poster may be the sort who ignores warnings....

  • by alder ( 31602 ) on Monday July 07, 2003 @01:26PM (#6383891)
    they checked 58,000 lines - does this seem reasonable?
    It looks reasonable if they checked only the server "core".
    • All *.c files under httpd-2.0.46 - 375K lines
    • APR (i.e. srclib) - 230K lines
    • All modules - 93K lines
    • modules/http - 5K lines
    • modules/loggers - 1.6K lines
    • modules/cache - 0.4K lines
    • some files from modules/mappers - 4K lines
    375 - 230 - 93 + 5 + 1.6 + 0.4 + 4 = 63K in ~ 100 files

    Subtract 53 lines per file on Apache Software Licence and you'll end up with ~58K.

  • by Ed Avis ( 5917 ) <ed@membled.com> on Monday July 07, 2003 @02:38PM (#6384442) Homepage
    The null pointer in C is written as 0, and tests as false when used as a Boolean. It might be stored internally as the bit value 1010101, but still in C source code it is 0, and false. So

    if (pointer) ...

    is perfectly legal, and portable, C.
  • by Anonymous Coward on Monday July 07, 2003 @03:55PM (#6385163)
    IMNSHO: In My Not-So Humble Opinion... ie. a 'nice' way of saying 'I'm smarter than you...'
  • by Anonymous Coward on Monday July 07, 2003 @04:31PM (#6385550)
    Looking at their first "bug", a little manual inspection shows that it's in the "can't happen" category, even without knowing about hidden information. The code looks like this:

    current_provider = conf->providers;
    do {
    {some safe code}
    if (!conf->providers) {
    break;
    }
    current_provider = current_provider->next;
    } while (current_provider);

    and they identify the second-to-last line as the "possible NULL pointer reference". Note that the "break" before that line will be taken if the pointer is NULL, so it can't happen. In fact, the static analysis could have determined this if it were a little better at propagating values.

    First conclusion: subtract at least one "bug" from the 31 defects in Apache. This lowers the rate to 0.51, the same as the "average commercial code" number they quote. Yahoo!

    Second conclusion: their static analysis must identify a lot of false positives, if the very first one in the list is one (I would look at more, but I should really get back to work...)
  • by aborchers ( 471342 ) on Monday July 07, 2003 @05:00PM (#6385903) Homepage Journal

    A chained else-if structure is equivalent to a switch.


    Funny you should point that out: a chained else-if structure without a terminal else is equivalent to a switch without a default which is notoriously vulnerable to the same sort of logic errors.

    if you can use the simpler structure without duplicating code, then you should


    While I agree with that principle, the whole issue of good form (which I won't argue can be inefficient and cumbersome) is that following it slavishly can prevent the coding patterns that lead to hard-to-find bugs. It protects us from our own worst tendencies, one of which is assuming when we write the code that we know exactly what we mean it to do. :-) Optimization is a valuable step to be sure, but optimizing too soon is a route to buggy code.

  • by murr ( 214674 ) on Monday July 07, 2003 @10:53PM (#6388318)
    Interestingly enough, that very first bug report demonstrates a limitation in the logical reasoning of the analysis tool, not a defect in the Apache code:

    current_provider was assigned from conf->providers (line 257), so it cannot possibly be NULL unless conf->providers is NULL, and that condition is tested for on line 287.

    NEXT!

Say "twenty-three-skiddoo" to logout.

Working...