Bug 19662

Summary: kernel panic after too many socket freed
Product: Base System Reporter: wyb <wyb>
Component: i386Assignee: freebsd-bugs (Nobody) <bugs>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: 4.0-STABLE   
Hardware: Any   
OS: Any   

Description wyb 2000-07-03 10:40:03 UTC
I create a program to test how many connection can freebsd accepted,
it runs upto 32000 connections simultaneity. but when the program finished, the system crashed(or after a while). the error was :

panic : malloc : wrong bucket

(sometimes another message happened, e.g. 'trap 12' or 'cpu0: boot()')

Fix: 

limit the connections in 4096.
How-To-Repeat: // compile and run this program : "./so & ./so c"
// notice you must update NMBCLUSTERS and kern.maxfilesperproc 
// at first :

(compile kernel with NMBCLUSTERS > 65000, install, reboot )
sysctl -w kern.maxfiles=65500
sysctl -w kern.maxfilesperproc=60000
sysctl -w net.inet.ip.portrange.last=65000
sysctl -w net.inet.ip.portrange.hifirst=65001

/*
    prog : Test Socket Max (so.c)
    usage :
    
    $ cc -o so so.c
    $ ./so & ./so c

    function address_end_point() from idonix.
*/

#define MAX_CONN    32000
#define HOST        "127.0.0.1"
#define PORT        "65510"

//#include <prelude.h>
#   include <fcntl.h>
#   include <netdb.h>
#   include <unistd.h>
#   include <dirent.h>
#   include <sys/types.h>
#   include <sys/param.h>
#   include <sys/socket.h>
#   include <sys/time.h>
#   include <sys/stat.h>
#   include <sys/ioctl.h>
#   include <sys/file.h>
#   include <sys/wait.h>
#   include <netinet/in.h>              /*  Must come before arpa/inet.h     */
#   include <arpa/inet.h>


int address_end_point (const char *host, const char *service, 
    const char *protocol, struct sockaddr_in *sin)
{
    struct hostent *phe; 
    struct servent *pse;
    int feedback = 0;

    memset ((void *) sin, 0, sizeof (*sin));
    sin-> sin_family = AF_INET;

    /*  Map service name to a port number                                    */
    pse = getservbyname (service, protocol);
    if (pse)
        sin-> sin_port = htons ((short) (ntohs (pse-> s_port)));
    else
        sin-> sin_port = htons ((short) (atoi (service)));

    /*  Check if it's a valid IP address first                               */
    sin-> sin_addr.s_addr = inet_addr (host);
    if (sin-> sin_addr.s_addr == INADDR_NONE)
      {
        /*  Not a dotted address -- try to translate the name                */
        phe = gethostbyname (host);
        if (phe)
            memcpy ((void *) &sin-> sin_addr, phe-> h_addr, phe-> h_length);
        else
          {                             /*  Cannot map to host               */
            feedback = (int) -1;
          }
      }
    return (feedback);
}



int lis;

void client_link()
{
    int i, r;
    int sd;
    char buf[100];
    
	struct sockaddr_in sin;
	r = address_end_point(HOST, PORT, "tcp", &sin);
    
    for (i = 0; i < MAX_CONN; i ++) {
        sd = socket(AF_INET, SOCK_STREAM, 0);
        printf("<%d:%d>\n", i, sd);
        if (sd < 0) {
            puts("ERROR connect()");
            exit(3);
        }

        r = connect(sd, (struct sockaddr *)&sin, sizeof(sin));
        
        write(sd, "H", 1);
        r = read(sd, buf, sizeof(buf));
        if (r != 1) {
            puts("ERROR read()");
            exit(2);
        }
    }
}

void server_link()
{
    int i, r;
    int sd;
    char buf[100];
	struct sockaddr_in sin;
	int len = sizeof(sin);
    
    for (i = 0; i < MAX_CONN; i ++) {
        sd = accept(lis, (struct sockaddr *)&sin, &len);
        printf("<%d:%d>\n", i, sd);
        if (sd < 0 ) 
            puts("ERROR accept()");

        r = read(sd, buf, sizeof(buf));
        if (r <= 0) puts("ERROR read()");
        write(sd, buf, r);
    }
}

int main(int argc, char** argv)
{
    int r;
    int is_client = (argc == 2 && *argv[1] == 'c');

	struct sockaddr_in sin;
    
    printf("Test Socket Max on %s [%s]\n", 
        "Front", is_client?"c->s":"s->c");
    if (is_client) {
        client_link();
    }
    else {
    	r = address_end_point(HOST, PORT, "tcp", &sin);
    	lis = socket(AF_INET, SOCK_STREAM, 0);
    	r = bind(lis, (struct sockaddr *)&sin, sizeof(sin));
        r = listen(lis, 5);
        server_link();
    }
    puts("Over.");

    return 0;
}
Comment 1 Mike Barcroft freebsd_committer freebsd_triage 2001-07-22 05:44:40 UTC
State Changed
From-To: open->feedback


Does this problem still occur in newer versions of FreeBSD, 
such as 4.3-RELEASE?
Comment 2 Sheldon Hearn freebsd_committer freebsd_triage 2002-01-18 16:14:39 UTC
State Changed
From-To: feedback->closed

Automatic feedback timeout.  If additional feedback that warrants 
the re-opening of this PR is available but not included in the 
audit trail, please include the feedback in a reply to this message 
(preserving the Subject line) and ask that the PR be re-opened.