From jin@pesto.lbl.gov  Sun Sep 15 21:42:55 2002
Return-Path: <jin@pesto.lbl.gov>
Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 7EF9137B400
	for <FreeBSD-gnats-submit@freebsd.org>; Sun, 15 Sep 2002 21:42:55 -0700 (PDT)
Received: from pesto.lbl.gov (pesto.lbl.gov [131.243.2.55])
	by mx1.FreeBSD.org (Postfix) with ESMTP id E962243E3B
	for <FreeBSD-gnats-submit@freebsd.org>; Sun, 15 Sep 2002 21:42:54 -0700 (PDT)
	(envelope-from jin@pesto.lbl.gov)
Received: from pesto.lbl.gov (localhost [127.0.0.1])
	by pesto.lbl.gov (8.12.3/8.12.3) with ESMTP id g8G4gs7P012463
	for <FreeBSD-gnats-submit@freebsd.org>; Sun, 15 Sep 2002 21:42:54 -0700 (PDT)
	(envelope-from jin@pesto.lbl.gov)
Received: (from jin@localhost)
	by pesto.lbl.gov (8.12.3/8.12.3/Submit) id g8G4gr5p012462;
	Sun, 15 Sep 2002 21:42:53 -0700 (PDT)
Message-Id: <200209160442.g8G4gr5p012462@pesto.lbl.gov>
Date: Sun, 15 Sep 2002 21:42:53 -0700 (PDT)
From: Jin Guojun (DSD staff) <jin@pesto.lbl.gov>
Reply-To: j_guojun@lbl.gov
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: qsort can only sort up to 6 element for structure
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         42818
>Category:       kern
>Synopsis:       qsort can only sort up to 6 element for structure
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun Sep 15 21:50:01 PDT 2002
>Closed-Date:    Mon Sep 16 03:40:09 PDT 2002
>Last-Modified:  Mon Sep 16 11:30:02 PDT 2002
>Originator:     Jin Guojun (DSD staff)
>Release:        FreeBSD 4.6.2-RELEASE i386
>Organization:
>Environment:


	FreeBSD 4.x

>Description:
	The code included in "How-To-Repeat" section works on Linux, Solaris,
	but fails on FreeBSD when array size is greater than 6.

solaris/linux:
./qsort-app
orig:   2  3  0  1  4  5  6  7  8  9 22 23 45 56 10 11
sort:   0  1  2  3  4  5  6  7  8  9 10 11 22 23 45 56  OK 

orig:   0  1  2  3  4  5  6  7  8  9 10 11 22 23
sort:   0  1  2  3  4  5  6  7  8  9 10 11 22 23        OK 

orig:   0  1  2  3  4  5  6  7  8  9
sort:   0  1  2  3  4  5  6  7  8  9    OK 

orig:   2  3  0  1  4  5  6  7  8  9 12 13
sort:   0  1  2  3  4  5  6  7  8  9 12 13      OK 

orig:   0  1  2  3  4  5  6  7  8  9 12 13 15 16 10 11
sort:   0  1  2  3  4  5  6  7  8  9 10 11 12 13 15 16  OK 


FreeBSD:
orig:   2  3  0  1  4  5  6  7  8  9 22 23 45 56 10 11
sort:  10 11  0  1  4  5  6  7  8  9  2  3 22 23 45 56  FAILED 

orig:  10 11  0  1  4  5  6  7  8  9  2  3 22 23
sort:   6  7  0  1  4  5  2  3  8  9 10 11 22 23        FAILED 

orig:   6  7  0  1  4  5  2  3  8  9
sort:   0  1  2  3  4  5  6  7  8  9    OK 

orig:   2  3  0  1  4  5  6  7  8  9 12 13
sort:   0  1  2  3  4  5  6  7  8  9 12 13      OK 

orig:   0  1  2  3  4  5  6  7  8  9 12 13 15 16 10 11
sort:  10 11  2  3  4  5  6  7  8  9  0  1 12 13 15 16  FAILED 


>How-To-Repeat:

	make qsort-app
	./qsort-app

% cat qsort-app.c

#include <stdlib.h>

smaller(const void *i1, const void *i2)
{
return  *(int*)i1 > *(int*)i2;
}

#define	N	8

typedef	int	ia_t[2];

main()
{
int	i;
ia_t	d0[N] = {2, 3, 0, 1, 4, 5, 6, 7, 8, 9, 22, 23, 45, 56, 10, 11},
	d1[N] = {2, 3, 0, 1, 4, 5, 6, 7, 8, 9, 12, 13, 15, 16, 10, 11};

#define	test(dx, n)	{	\
	ia_t	*da = dx;	\
	printf("orig: ");	\
	for (i=0; i<n; i++)	\
		printf("%3d %2d", da[i][0], da[i][1]);	\
	qsort(da, n, sizeof(da[0]), smaller);	\
	printf("\nsort: ");	\
	for (i=0; i<n; i++)	\
		printf("%3d %2d", da[i][0], da[i][1]);	\
	printf("	%s \n\n", da[0][0] == 0 ? "OK" : "FAILED");	\
    }

	test(d0, N);
	test(d0, 7);
	test(d0, 5);
	test(d1, 6);
	test(d1, N);
}

>Fix:

>Release-Note:
>Audit-Trail:

From: Gregory Bond <gnb@itga.com.au>
To: j_guojun@lbl.gov
Cc: FreeBSD-gnats-submit@FreeBSD.ORG
Subject: Re: kern/42818: qsort can only sort up to 6 element for structure 
Date: Mon, 16 Sep 2002 16:30:13 +1000

 The bug is in your program.  To quote qsort(3):
 
      The comparison function must return an integer less than, equal to, or
      greater than zero if the first argument is considered to be respectively
      less than, equal to, or greater than the second.
 
 Your comparison function returns 0 or 1 only.  Perhaps you are being confused 
 by the C++/STL comparison objects?
 
 Modifying your comparison fn to the following makes it work:
 	int
 	smaller(const void *i1, const void *i2)
 	{
 		if (*(int*)i1 < *(int*)i2) return -1;
 		return  *(int*)i1 > *(int*)i2;
 	}
 
 The fact that your test program seems to work for these test cases on Solaris
 and Linux is a simple coincidence, and depends on fine internal details of the
 sort algorithm on those systems.  There will probably be other cases where the
 Linux/Solaris qsort() will also fail.
 
 This PR can be closed.
 
 
State-Changed-From-To: open->closed 
State-Changed-By: fanf 
State-Changed-When: Mon Sep 16 03:38:52 PDT 2002 
State-Changed-Why:  
Bug is in the submitter's program, not FreeBSD. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=42818 

From: "Jin Guojun [DSD]" <j_guojun@lbl.gov>
To: Gregory Bond <gnb@itga.com.au>
Cc: FreeBSD-gnats-submit@FreeBSD.ORG
Subject: Re: kern/42818: qsort can only sort up to 6 element for structure
Date: Mon, 16 Sep 2002 11:26:29 -0700

 My fault -- I typed a wrong operator "<". It supposes to be "-". So, the correct
 operation
 is:
 
 int   smaller(const void *i1, const void *i2)
 {
     return    *(int*)i1 - *(int*)i2;
 }
 
 Thanks,
 
     -Jin
 
 Gregory Bond wrote:
 
 > The bug is in your program.  To quote qsort(3):
 >
 >      The comparison function must return an integer less than, equal to, or
 >      greater than zero if the first argument is considered to be respectively
 >      less than, equal to, or greater than the second.
 >
 > Your comparison function returns 0 or 1 only.  Perhaps you are being confused
 > by the C++/STL comparison objects?
 >
 > Modifying your comparison fn to the following makes it work:
 >         int
 >         smaller(const void *i1, const void *i2)
 >         {
 >                 if (*(int*)i1 < *(int*)i2) return -1;
 >                 return  *(int*)i1 > *(int*)i2;
 >         }
 >
 > The fact that your test program seems to work for these test cases on Solaris
 > and Linux is a simple coincidence, and depends on fine internal details of the
 > sort algorithm on those systems.  There will probably be other cases where the
 > Linux/Solaris qsort() will also fail.
 >
 > This PR can be closed.
 
>Unformatted:
