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-5773marc@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