| Summary: | kernel panic after too many socket freed | ||
|---|---|---|---|
| Product: | Base System | Reporter: | wyb <wyb> |
| Component: | i386 | Assignee: | freebsd-bugs (Nobody) <bugs> |
| Status: | Closed FIXED | ||
| Severity: | Affects Only Me | ||
| Priority: | Normal | ||
| Version: | 4.0-STABLE | ||
| Hardware: | Any | ||
| OS: | Any | ||
State Changed From-To: open->feedback Does this problem still occur in newer versions of FreeBSD, such as 4.3-RELEASE? 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. |
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; }