kjd@icxn.UUCP (Kevin J. Dunlap) (05/17/91)
I am having a problem with memory and using AT&T's TLI running on Interactive 386/ix System V 3.2.2. I have the updates to TCP/IP installed (SSU.4a). The problem is that it looks like t_free() is not freeing up the memory allocated by t_alloc(). As the process runs, it calls t_alloc to allocate the T_UNITDATA and then calls t_free to free the data. Unfortunately, the process keeps growing in size and then the system crashes when it can't get anymore memory. Attached is a code sigment that show the the problem. All it does is open up /dev/udp, bind()'s to it and then loops doing a t_alloc() and t_free(). If you keep doing a ps(1) of the process, you will see that it keeps growing. Does anyone know if this is a known bug in Interactive? Do other vendor's System V have this bug? or am I messing something fundimental? -Kevin ------------------------------------------------------------------------ Kevin J. Dunlap kjd@icxn.icxn.com InterConnections, Inc. uunet!icxn!kjd 14711 NE 29th Place, Bellevue, WA 98007 206/881-5773 ------------------ remove this line and everything above ------- /* * Test program to show problem with using TLI t_free() * * Compile: cc -o test test.c -lnsl_s -lmalloc */ /* TLI Related Header Files */ #include <sys/tiuser.h> #include <fcntl.h> #include <stropts.h> #include <sys/types.h> #include <sys/bsdtypes.h> #include <sys/socket.h> #include <sys/stream.h> #include <netinet/in.h> #include <net/if.h> #include <stdio.h> #include <errno.h> struct packet { u_char type; u_char seq; char version; char req; }; int fd; struct t_unitdata *unitdata; extern int errno; extern int t_errno; main(argc, argv, envp) int argc; char *argv[], *envp[]; { int x; struct t_bind *tes_bind; struct t_bind *bind; struct t_unitdata *tes_unitdata; struct sockaddr_in address; struct packet *data; /* * Create the transport endpoint. */ if ((fd = t_open("/dev/udp", O_RDWR, NULL)) < 0) { perror("t_open can not open device"); exit(1); } if ((bind = (struct t_bind *)t_alloc(fd, T_BIND, T_ALL)) == NULL) { t_error("t_alloc failed"); exit(1); } bind->qlen = 0; bind->addr.len = sizeof(address); address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = 61761; bind->addr.buf = (char *) &address; if (t_bind(fd, bind, bind) < 0) { t_error("t_bind for TES failed"); exit(2); } for (x=0; x < 100000; x++) { if ((unitdata =(struct t_unitdata *)t_alloc(fd,T_UNITDATA,T_ALL))==NULL) { t_error("t_alloc failed"); exit(2); } if ((data = (struct packet *) malloc(sizeof(struct packet))) == NULL) { perror("malloc failed"); exit(2); } unitdata->opt.len = 0; unitdata->opt.buf = (char *)NULL; unitdata->udata.len = sizeof(*data); unitdata->udata.buf = (char *)data; /* the t_free() man page says next line isn't needed */ free(unitdata->udata.buf);/* the t_free() if (t_free(unitdata, T_UNITDATA) < 0) { t_error("t_free failed"); exit(2); } } } -- ------------------------------------------------------------------------ Kevin J. Dunlap kjd@icxn.icxn.com InterConnections, Inc. uunet!icxn!kjd 14711 NE 29th Place, Bellevue, WA 98007 206/881-5773
marc@dumbcat.sf.ca.us (Marco S Hyman) (05/20/91)
In article <142@icxn.UUCP> kjd@icxn.UUCP (Kevin J. Dunlap) writes: > I am having a problem with memory and using AT&T's TLI running on > Interactive 386/ix System V 3.2.2. I have the updates to TCP/IP > installed (SSU.4a). I see your problem. Look at the man page for t_alloc again. I quote: "This function will allocate memory for the specified structure, and will also allocate memory for buffers referenced by the structure." Your t_alloc call if ((unitdata =(struct t_unitdata *)t_alloc(fd,T_UNITDATA,T_ALL))==NULL) { allocates both the t_unitdata structure but also all (T_ALL) fields in the structure. The maxlen field will be initialized for each buffer. Later when you do unitdata->opt.len = 0; unitdata->opt.buf = (char *)NULL; unitdata->udata.len = sizeof(*data); unitdata->udata.buf = (char *)data; You overwrite the pointers that t_alloc built. That memory is lost forever. t_open and t_getinfo will give you the various lengths. If you want to set your own lengths use T_ADDR instead of T_ALL in the t_alloc call. That's all you wanted to allocate in your example. // marc -- // home: marc@dumbcat.sf.ca.us pacbell!dumbcat!marc // work: marc@ascend.com uunet!aria!marc