[comp.soft-sys.andrew] WP bug on SPARC, new release version?

salzman%gaucho@RAND.ORG (Isaac Salzman) (11/16/89)

[this was part of one long message - i decided to split it into several
smaller messages]

hi there. the following is in reference to Andrew R4 Beta release, patch
level 5 running on a Sparcstation-1 (SunOS 4.0.3c). 

i've discovered a bug in the wp code on SPARC. actually, it's a bug in
Sun's SPARC C compiler that's exercised by wp. it's in wp_DeAllocate()
in overhead/util/lib/wpbase.c, which is declared as follows:

wp_ErrorCode wp_DeAllocate(StrPtr)
union { wp_PrimeKeySet *PKSet; struct wp_SrchToken *ST; wp_SearchToken
XX;} StrPtr;
{
	/* stuff */
}

Sun's C compiler doesn't like the union. it compiles ok, but gets a bus
error when you try to run it (when called from wpq for instance). this
works ok on a Sun3, or a Sun4 with the GNU C Compiler (gcc). i'm going
to send a bug report to sun. i don't suspect a fixed compiler will happen
anytime soon, so i've hacked the code to pass StrPtr as a char *, and then
cast it to the apropriately (e.g. ((struct xxx *)StrPtr)->yyy). context
diff's enclosed.

i've noticed a new .tar.Z file and emsworth. i gather that's the "release"
version? i've grabbed patch06 but haven't applied it (it doesn't fix the wp
problem - i checked). ciao!

* Isaac J. Salzman                                            ----     
* The RAND Corporation - Information Sciences Dept.          /o o/  /  
* 1700 Main St., PO Box 2138, Santa Monica, CA 90406-2138    | v |  |  
* AT&T      : +1 213-393-0411 x6421 or x7923 (ISL lab)      _|   |_/   
* Internet  : salzman@rand.org                             / |   |
* UUCP      : !uunet!rand.org!salzman                      | |   |     
* CompuServe: 76167,1046

---- Enclosure ----
*** Orig/wpbase.c	Wed Nov 15 08:03:12 1989
--- wpbase.c	Wed Nov 15 08:14:07 1989
***************
*** 363,408 ****
    Clean up after the client is done with malloc'ed storage.
  						 */
  wp_ErrorCode wp_DeAllocate(StrPtr)
! union { wp_PrimeKeySet *PKSet; struct wp_SrchToken *ST; wp_SearchToken
XX;} StrPtr;
  {
      int ctr;
      struct wp_Constraint *CPtr;
  
!     if (StrPtr.PKSet == NULL) return wperr_NoError;
  
  #if Logs
      Log(700, "wp_DeAllocate(0x%x) called", StrPtr);
  #endif /* Logs */
!     if (StrPtr.PKSet->KeyCount >= 0) {		/* it's a pointer to
PrimeKeySetStr */
  	if (wp_Debugging) {fprintf(stderr,
  				   "wp_DeAllocate(%#x) releasing a %d-key PrimeKeySet.\n",
! 				   StrPtr.PKSet, StrPtr.PKSet->KeyCount);
  	}
! 	if (StrPtr.PKSet->Keys != NULL) {
  	    if (wp_Debugging) fprintf(stderr, "PrimeKeySet has keys at %#x.\n",
! 				      StrPtr.PKSet->Keys);
! 	    for (ctr = StrPtr.PKSet->KeyCount - 1; ctr >= 0; --ctr) {
! 		if (StrPtr.PKSet->Keys[ctr] != NULL) {
  		    if (wp_Debugging) fprintf(stderr,
! 					      "Releasing PKset key[%d]=%#x.\n",
! 					      ctr, StrPtr.PKSet->Keys[ctr]);
! 		    free(StrPtr.PKSet->Keys[ctr]);
  		}
  	    }
! 	    free(StrPtr.PKSet->Keys);
  	}
! 	free(StrPtr.PKSet);
!     } else if (StrPtr.ST->Tag == SrchTokenTag) {
! 	CPtr = StrPtr.ST->Constraints;
  	while (CPtr != NULL) {
! 	    StrPtr.ST->Constraints = CPtr->Next;
  	    if (CPtr->Tag != ConstraintTag) return wperr_TokenMalformed;
  	    free(CPtr->FieldContent);
  	    free(CPtr);
! 	    CPtr = StrPtr.ST->Constraints;
  	}
! 	free(StrPtr.ST->Probe);
! 	free(StrPtr.ST);
      } else return wperr_NoSuchTokenKind;
      if (wp_Debugging) fprintf(stderr, "wp_DeAllocate returning.\n");
  #if Logs
--- 363,415 ----
    Clean up after the client is done with malloc'ed storage.
  						 */
  wp_ErrorCode wp_DeAllocate(StrPtr)
!     char *StrPtr;
! 
! /* union { wp_PrimeKeySet *PKSet; struct wp_SrchToken *ST; 
!    wp_SearchToken XX;} StrPtr;
! */
! 
  {
      int ctr;
      struct wp_Constraint *CPtr;
  
!     if (StrPtr == NULL) return wperr_NoError;
  
  #if Logs
      Log(700, "wp_DeAllocate(0x%x) called", StrPtr);
  #endif /* Logs */
!     if ( ((wp_PrimeKeySet *)StrPtr)->KeyCount >= 0) { /* it's a
pointer to PrimeKeySetStr */
  	if (wp_Debugging) {fprintf(stderr,
  				   "wp_DeAllocate(%#x) releasing a %d-key PrimeKeySet.\n",
! 				   (wp_PrimeKeySet *)StrPtr,
! 				   ((wp_PrimeKeySet *)StrPtr)->KeyCount);
  	}
! 	if (((wp_PrimeKeySet *)StrPtr)->Keys != NULL) {
  	    if (wp_Debugging) fprintf(stderr, "PrimeKeySet has keys at %#x.\n",
! 				      ((wp_PrimeKeySet *)StrPtr)->Keys);
! 	    for (ctr = ((wp_PrimeKeySet *)StrPtr)->KeyCount - 1; ctr >= 0;
! 		 --ctr) {
! 		if (((wp_PrimeKeySet *)StrPtr)->Keys[ctr] != NULL) {
  		    if (wp_Debugging) fprintf(stderr,
! 				      "Releasing PKset key[%d]=%#x.\n", ctr, 
! 				      ((wp_PrimeKeySet *)StrPtr)->Keys[ctr]);
! 		    free(((wp_PrimeKeySet *)StrPtr)->Keys[ctr]);
  		}
  	    }
! 	    free(((wp_PrimeKeySet *)StrPtr)->Keys);
  	}
! 	free((wp_PrimeKeySet *)StrPtr);
!     } else if (((struct wp_SrchToken *)StrPtr)->Tag == SrchTokenTag) {
! 	CPtr = ((struct wp_SrchToken *)StrPtr)->Constraints;
  	while (CPtr != NULL) {
! 	    ((struct wp_SrchToken *)StrPtr)->Constraints = CPtr->Next;
  	    if (CPtr->Tag != ConstraintTag) return wperr_TokenMalformed;
  	    free(CPtr->FieldContent);
  	    free(CPtr);
! 	    CPtr = ((struct wp_SrchToken *)StrPtr)->Constraints;
  	}
! 	free(((struct wp_SrchToken *)StrPtr)->Probe);
! 	free(((struct wp_SrchToken *)StrPtr));
      } else return wperr_NoSuchTokenKind;
      if (wp_Debugging) fprintf(stderr, "wp_DeAllocate returning.\n");
  #if Logs

---- Enclosure ----

guy@auspex.auspex.com (Guy Harris) (11/22/89)

>i've discovered a bug in the wp code on SPARC. actually, it's a bug in
>Sun's SPARC C compiler that's exercised by wp.

(Actually, it's a bug in the WP code, which happens not to prevent it
from doing what you want on many C implementations, but the SPARC and
perhaps Pyramid C implementations are not among them; passing an object
of type "foo" to a routine expecting an object of a union type that
includes type "foo" is not valid C.)

Is it ever the case that somebody passes something to "wp_DeAllocate"
and doesn't know which of the N flavors of things that "wp_DeAllocate"
can deallocate it is?  If not, perhaps the best long-term fix is to
replace "wp_DeAllocate" with multiple deallocaters and call the correct
one in each instance, passing it a pointer to a "wp_PrimeKeySet" or to a
"struct wp_SrchToken".  (I.e., does all the code that calls it passing
it a "struct wp_SrchToken *" really truly pass it a pointer to a
"wp_SrchToken", not a pointer to a "wp_PrimeKeySet" in disguise, and
*vice versa*?)

salzman%iris@RAND.ORG (Isaac Salzman) (11/22/89)

>(Actually, it's a bug in the WP code, which happens not to prevent it
>from doing what you want on many C implementations, but the SPARC and
>perhaps Pyramid C implementations are not among them; passing an object
>of type "foo" to a routine expecting an object of a union type that
>includes type "foo" is not valid C.)

i didn't think it was valid C. defeinitely not code that i would write :-)
(especially declaring the union as part of the paramater dec's - yech)!  but
since it worked under GCC on SPARC and both Sun's CC and GCC on the sun3....

>Is it ever the case that somebody passes something to "wp_DeAllocate"
>and doesn't know which of the N flavors of things that "wp_DeAllocate"
>can deallocate it is?  If not, perhaps the best long-term fix is to
>replace "wp_DeAllocate" with multiple deallocaters and call the correct
>one in each instance, passing it a pointer to a "wp_PrimeKeySet" or to a
>"struct wp_SrchToken".  (I.e., does all the code that calls it passing
>it a "struct wp_SrchToken *" really truly pass it a pointer to a
>"wp_SrchToken", not a pointer to a "wp_PrimeKeySet" in disguise, and
>*vice versa*?)

i haven't explored the andrew code a whole lot. i do know that andrew uses
(in some places) a classing mechanism. i guess it does not implement any
sort of dynamic binding (aka virtual functions in C++). here's a good case
for using an object system with dynamic binding. you wouldn't need to know
which of the N flavors of an object something is. it's determined at
runtime. just send the DeAllocate message (actually, just "delete" the object
in C++ and the destructors get called automatically)....

		-isaac (salzman@rand.org)

bader+@ANDREW.CMU.EDU (Miles Bader) (11/22/89)

Isaac Salzman <salzman%iris@rand.org> writes:
> i haven't explored the andrew code a whole lot. i do know that andrew uses
> (in some places) a classing mechanism. i guess it does not implement any
> sort of dynamic binding (aka virtual functions in C++). here's a good case
> for using an object system with dynamic binding. you wouldn't need to know
> which of the N flavors of an object something is. it's determined at
> runtime. just send the DeAllocate message (actually, just "delete" the object
> in C++ and the destructors get called automatically)....

The "classing mechanism" used by atk ("class") implements ONLY dynamic
binding of methods.  However, the white pages doesn't use class.

-Miles

cfe+@ANDREW.CMU.EDU ("Craig F. Everhart") (11/22/89)

I have to agree with Guy Harris that the correct thing to do would be to
revoke the idea that wp_DeAllocate should take any of several different
types.  The only thing I can say in defense of the way that it currently
works is that I wrote it long ago, when a relative novice to C and
didn't understand the HC compiler's warnings.  That being said, I've
absorbed Isaac Salzman's change to flush the ``union'' from the
parameter list to make the thing work moderately correctly, but it's a
little late (tape going out this morning) to ``do the right thing'',
implementing wp_DeAllocateSrch/wp_DeAllocatePKs, changing all the calls
everywhere in all andrew code, and updating the documentation.  That
should be done, and maybe if we ever generate another version...

		Craig