You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@apr.apache.org by "William A. Rowe, Jr." <wr...@covalent.net> on 2002/06/27 06:03:17 UTC

Only ONE back-compat hole discovered.

Well, I did it today.  Plugged in libapr tagged APACHE_2_0_39 into an
APACHE_2_0_35 and APACHE_2_0_36 libaprutil + httpd.  Of course
we changed the bucket semantics and behavior too much to actually bring
libaprutil up to the 2.0.39 rev.  This was a plug-in, binary compatibility
experiment.

And as they were fond of saying on the SCN Celebrety All Star Blowup...

"She Blowed Up Real Good!!!"

There was only -one- major problem, and we reveal, for the first time on
this world-wide circulated devlist, exactly who the guilty party was!

It all comes down to this, if you introduce a transparent type, you have
doomed APR's backwards and forwards compatibility.  No bugs can
be fixed, no hassles resolved.  You stick us, collectively, in the mud.

As it was, I simply had to recompile the original libaprutil code against 
the new 2.0.39 headers.  But after spending a s*load of time getting the
2.0.39 and forward releases compatible back to 2.0.35, this was a pretty
stunning disappointment that we couldn't just drop in a current libapr.
Fortunately, libhttpd did not require any rebuild at all.

So it can be done if we all pull together to maintain binary compatibility.
Platform specific faults can be eliminated by simply replacing the known
good update for that platform.  No longer is an application doomed to
being rebuilt.

Of course, as we macro-enhance things, we tightly couple the app that
uses those dirty macro wrappers to that version of the library.  This should
become an optional feature, wherein the app author agrees that they will
keep distributing apr and apr-foo libraries that their application was rebuilt
against.  It isn't pleasant, but that's the price of faster interop with APR.

So now, as promised, the OGPs [official guilty parties].  This information is
only now being revealed in hopes that the offending coders will pull this
transparent type and illicit sharing of allocation sizes from the public headers, 
and leave future generations with less risky declarations that won't break 
binary compat :-)
 
 85                  apr_memnode_t *next;

 86 striker  1.6     apr_memnode_t **ref;

 87 jwoolley 1.3     apr_uint32_t   index;

 88 striker  1.6     apr_uint32_t   free_index;

 89 jwoolley 1.3     char          *first_avail;
 90                  char          *endp;
 91              };
 92              
 93              #define APR_MEMNODE_T_SIZE APR_ALIGN_DEFAULT(sizeof(apr_memnode_t))





RE: Only ONE back-compat hole discovered.

Posted by "William A. Rowe, Jr." <wr...@rowe-clan.net>.
At 02:42 AM 6/27/2002, Sander Striker wrote:

>The offending file is include/apr_allocator.h, a relative youngster, 
>introduced
>on 15 march 2002.

I ment to back up and retitle the post ... thanks for pointing that out...

> >  85                  apr_memnode_t *next;
> >
> >  86 striker  1.6     apr_memnode_t **ref;
> >
> >  87 jwoolley 1.3     apr_uint32_t   index;
> >
> >  88 striker  1.6     apr_uint32_t   free_index;
> >
> >  89 jwoolley 1.3     char          *first_avail;
> >  90                  char          *endp;
> >  91              };
> >  92
> >  93              #define APR_MEMNODE_T_SIZE 
> APR_ALIGN_DEFAULT(sizeof(apr_memnode_t))
>
>The options on this are:
>
>   1) move the parts of apr-util that are dependent on apr's private types 
> to apr.
>      [bucket allocator, which implies moving buckets to apr]

Nak.  I think we like that segregation.  apr-util is a moving target, while 
apr seems
to have settled into even growth.

>   2) loose the dependency altogether, ending the short life of, the 
> current implementation
>      of, the bucket allocator.

No.  All I'm suggesting is accessor functions.  With accessors, you can add new
ones for new members, and safely return a pointer to an opaque type when a new
memnode is created.  The size is simple too, return it in a function.  I 
had to create
some overhead sizing functions for apr_rmm for exactly that reason.

>   3) I could have appended the new fields at the end of the structure.
>      *slaps self for not having done that*

:-)

>      Then, if we would choose to have a function to return the size of 
> apr_memnode_t,
>      instead of a macro, it would have just worked.  The only fields the 
> bucket allocator,
>      and any other allocator, rely on are first_avail and endp.  If we 
> export that as
>      a public type and have a private type with the rest of the fields, 
> combined with
>      a size function, we won't face this problem again.

Bingo... add to the end if we must, and if it must remain a transparent type.
But the size of the structure better come from a function that knows the 
current
allocator implementation.

>   4) require apr and apr-util to be version dependent.

No, that wouldn't be unreasonable either.  The point of the exercise was to 
decide
that I could replace, say, some broken apr_proc or apr_mutex code, and nobody
would be harmed in the process :-)

But if we presume that they could be disjoint, we will do a better job with 
version
compatibility for 3rd party authors.

>      *puts on asbestos suit...*

The point of the original post is that we are nearly there, we can start 
enforcing
version compatibility.  That is something to cheer, and the allocator 
issues is
just an example of what can bit us as we move forward (and something to mop
up a bit :0)

Bill



Re: Only ONE back-compat hole discovered.

Posted by "William A. Rowe, Jr." <wr...@rowe-clan.net>.
At 07:18 AM 6/27/2002, Thom May wrote:
>* Justin Erenkrantz (jerenkrantz@apache.org) wrote :
> > On Thu, Jun 27, 2002 at 09:42:12AM +0200, Sander Striker wrote:
> > > The options on this are:
> > <snip, snip, snip>
> >
> > 5) Do nothing as APR isn't released yet.
> >
> > Personally, I don't care about backwards compatibility until
> > we hit 1.0 of APR.  However, the fact that so much of APR has
> > stayed the same probably means that we can jump to 1.0.
>
>hrrm. I'm a fairly strong -1 on bumping apr to 1.0 at this point -
>we need to get the API consistent and clean, otherwise we're
>stuck with it for far too long

I agree here.  There are just a few hiccups to work out yet.

WHEN we bump, all old/deprecated symbols and interfaces go kapoof.
That should happen when we are certain we aren't deprecating any others,
for no good reason other than "we can't name things to save our lives."

Sander's goof in not keeping the ordering of fields can't be remedied now.
But we can, at least, put wrappers around such things so that they can't
be hurt by casual coding against apr, such as our own apr-util bucket code.
That includes not using the struct alignment as a macro of the sizeof(),
but rather as a function that returns -this- versions' sizeof().

My objection to the apr_allocator issue isn't that it was borked before 1.0
went out.  My objection is that we may discover ourselves borking it again
post-1.0 which would be badness.  Clean opaque types prevent us from
repeating this mistake.

Bill



Re: Only ONE back-compat hole discovered.

Posted by Thom May <th...@planetarytramp.net>.
* Justin Erenkrantz (jerenkrantz@apache.org) wrote :
> On Thu, Jun 27, 2002 at 09:42:12AM +0200, Sander Striker wrote:
> > The options on this are:
> > 
> <snip, snip, snip>
> > 
> > Thoughts?
> 
> 5) Do nothing as APR isn't released yet.
> 
> Personally, I don't care about backwards compatibility until
> we hit 1.0 of APR.  However, the fact that so much of APR has
> stayed the same probably means that we can jump to 1.0.
> 
> Anyone feel lucky?  httpd-2.0 has gone GA for a bit and SVN
> is about to hit alpha.  Not to mention flood's now been ported
> to Win32.  So, if there's something really wrong with the APR
> API, we haven't seen it yet.  And, if there is something really
> wrong, well, that's what APR 2.0 is for.  -- justin

hrrm. I'm a fairly strong -1 on bumping apr to 1.0 at this point - 
we need to get the API consistent and clean, otherwise we're 
stuck with it for far too long
On the flip side, yes, it would be great to get APR to 1.0 as soon as
possible. 
I just don't think it's there yet.
Cheers,
-Thom
-- 
Thom May -> thom@planetarytramp.net

> > "we can tell that a Debian release is about to happen".  Or
> > something.
> "I sense a disturbance in the force" ?
"As though millions of voices cried out, and ran apt-get."
-dburrows, davidw, aj; Debian 3.0

Re: Only ONE back-compat hole discovered.

Posted by Justin Erenkrantz <je...@apache.org>.
On Thu, Jun 27, 2002 at 09:42:12AM +0200, Sander Striker wrote:
> The options on this are:
> 
<snip, snip, snip>
> 
> Thoughts?

5) Do nothing as APR isn't released yet.

Personally, I don't care about backwards compatibility until
we hit 1.0 of APR.  However, the fact that so much of APR has
stayed the same probably means that we can jump to 1.0.

Anyone feel lucky?  httpd-2.0 has gone GA for a bit and SVN
is about to hit alpha.  Not to mention flood's now been ported
to Win32.  So, if there's something really wrong with the APR
API, we haven't seen it yet.  And, if there is something really
wrong, well, that's what APR 2.0 is for.  -- justin

RE: Only ONE back-compat hole discovered.

Posted by Sander Striker <st...@apache.org>.
> From: William A. Rowe, Jr. [mailto:wrowe@covalent.net]
> Sent: 27 June 2002 06:03

Hi,

> Well, I did it today.  Plugged in libapr tagged APACHE_2_0_39 into an
> APACHE_2_0_35 and APACHE_2_0_36 libaprutil + httpd.  Of course
> we changed the bucket semantics and behavior too much to actually bring
> libaprutil up to the 2.0.39 rev.  This was a plug-in, binary compatibility
> experiment.

Ah... but, you are giving apr-util a different treatment as apr.  Why
should apr-util be allowed not to be back compat, when apr should not?

> And as they were fond of saying on the SCN Celebrety All Star Blowup...
> 
> "She Blowed Up Real Good!!!"
> 
> There was only -one- major problem, and we reveal, for the first time on
> this world-wide circulated devlist, exactly who the guilty party was!

...

> It all comes down to this, if you introduce a transparent type, you have
> doomed APR's backwards and forwards compatibility.  No bugs can
> be fixed, no hassles resolved.  You stick us, collectively, in the mud.
> 
> As it was, I simply had to recompile the original libaprutil code against 
> the new 2.0.39 headers.  But after spending a s*load of time getting the
> 2.0.39 and forward releases compatible back to 2.0.35, this was a pretty
> stunning disappointment that we couldn't just drop in a current libapr.
> Fortunately, libhttpd did not require any rebuild at all.

I can already see where this is going...  It's about a certain dependency
between apr and apr-util, a dependency that httpd doesn't have.

> So it can be done if we all pull together to maintain binary compatibility.
> Platform specific faults can be eliminated by simply replacing the known
> good update for that platform.  No longer is an application doomed to
> being rebuilt.
> 
> Of course, as we macro-enhance things, we tightly couple the app that
> uses those dirty macro wrappers to that version of the library.  This should
> become an optional feature, wherein the app author agrees that they will
> keep distributing apr and apr-foo libraries that their application was rebuilt
> against.  It isn't pleasant, but that's the price of faster interop with APR.

Are you suggesting something like a conditional:
#if !APR_BACK_COMPAT
   ... define macro to use sizeof ...
#else
   ... define macro to be function call that returns size ...
#endif

?

> So now, as promised, the OGPs [official guilty parties].  This information is
> only now being revealed in hopes that the offending coders will pull this
> transparent type and illicit sharing of allocation sizes from the public headers, 
> and leave future generations with less risky declarations that won't break 
> binary compat :-)

The offending file is include/apr_allocator.h, a relative youngster, introduced
on 15 march 2002.

>  85                  apr_memnode_t *next;
> 
>  86 striker  1.6     apr_memnode_t **ref;
> 
>  87 jwoolley 1.3     apr_uint32_t   index;
> 
>  88 striker  1.6     apr_uint32_t   free_index;
> 
>  89 jwoolley 1.3     char          *first_avail;
>  90                  char          *endp;
>  91              };
>  92              
>  93              #define APR_MEMNODE_T_SIZE APR_ALIGN_DEFAULT(sizeof(apr_memnode_t))

The options on this are:

  1) move the parts of apr-util that are dependent on apr's private types to apr.
     [bucket allocator, which implies moving buckets to apr]

  2) loose the dependency altogether, ending the short life of, the current implementation
     of, the bucket allocator.

  3) I could have appended the new fields at the end of the structure.
     *slaps self for not having done that*
     Then, if we would choose to have a function to return the size of apr_memnode_t,
     instead of a macro, it would have just worked.  The only fields the bucket allocator,
     and any other allocator, rely on are first_avail and endp.  If we export that as
     a public type and have a private type with the rest of the fields, combined with
     a size function, we won't face this problem again.

  4) require apr and apr-util to be version dependent.
     *puts on asbestos suit...*

Thoughts?

Sander