Merged r9657 (fdleak fixes) from the DARWIN branch.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@9658
This commit is contained in:
Nicholas Nethercote 2009-04-28 05:35:53 +00:00
parent c601f8a1e4
commit fcb90ff490
22 changed files with 169 additions and 230 deletions

View File

@ -74,15 +74,20 @@ Int VG_(safe_fd)(Int oldfd)
or if it doesn't exist, we return False. */
Bool VG_(resolve_filename) ( Int fd, HChar* buf, Int n_buf )
{
# if defined(VGO_linux)
HChar tmp[64];
VG_(sprintf)(tmp, "/proc/self/fd/%d", fd);
VG_(memset)(buf, 0, n_buf);
if (VG_(readlink)(tmp, buf, n_buf) > 0 && buf[0] == '/')
return True;
else
return False;
# elif defined(VGO_aix5)
I_die_here; /* maybe just return False? */
return False;
# else
# error "need fd-to-filename for this OS"
# endif
}
SysRes VG_(open) ( const Char* pathname, Int flags, Int mode )

View File

@ -704,13 +704,12 @@ void VG_(show_open_fds) (void)
VG_(message)(Vg_UserMsg, "");
}
/* If /proc/self/fd doesn't exist for some weird reason (like you've
got a kernel that doesn't have /proc support compiled in), then we
need to find out what file descriptors we inherited from our parent
process the hard way - by checking each fd in turn. */
/* If /proc/self/fd doesn't exist (e.g. you've got a Linux kernel that doesn't
have /proc support compiled in, or a non-Linux kernel), then we need to
find out what file descriptors we inherited from our parent process the
hard way - by checking each fd in turn. */
static
void do_hacky_preopened(void)
void init_preopened_fds_without_proc_self_fd(void)
{
struct vki_rlimit lim;
UInt count;
@ -719,15 +718,15 @@ void do_hacky_preopened(void)
if (VG_(getrlimit) (VKI_RLIMIT_NOFILE, &lim) == -1) {
/* Hmm. getrlimit() failed. Now we're screwed, so just choose
an arbitrarily high number. 1024 happens to be the limit in
the 2.4 kernels. */
the 2.4 Linux kernels. */
count = 1024;
} else {
count = lim.rlim_cur;
}
for (i = 0; i < count; i++)
if(VG_(fcntl)(i, VKI_F_GETFL, 0) != -1)
ML_(record_fd_open_nameless)(-1, i);
if (VG_(fcntl)(i, VKI_F_GETFL, 0) != -1)
ML_(record_fd_open_named)(-1, i);
}
/* Initialize the list of open file descriptors with the file descriptors
@ -735,13 +734,15 @@ void do_hacky_preopened(void)
void VG_(init_preopened_fds)(void)
{
// Nb: AIX5 is handled in syswrap-aix5.c.
#if defined(VGO_linux)
Int ret;
struct vki_dirent d;
SysRes f;
f = VG_(open)("/proc/self/fd", VKI_O_RDONLY, 0);
if (f.isError) {
do_hacky_preopened();
init_preopened_fds_without_proc_self_fd();
return;
}
@ -767,6 +768,10 @@ void VG_(init_preopened_fds)(void)
out:
VG_(close)(f.res);
#else
# error Unknown OS
#endif
}
static
@ -1989,6 +1994,7 @@ PRE(sys_exit)
PRE(sys_ni_syscall)
{
// Nb: AIX5 is handled in syswrap-aix5.c.
PRINT("non-existent syscall! (ni_syscall)");
PRE_REG_READ0(long, "ni_syscall");
SET_STATUS_Failure( VKI_ENOSYS );

View File

@ -1,6 +1,19 @@
#ifndef _FDLEAK_H_
#define _FDLEAK_H_
#include <stdlib.h>
#include <stdio.h>
#define DO(op) \
({ \
long res = op; \
if (res < 0) { \
perror(#op); \
exit(1); \
}; \
res; \
})
/*
* The macro below closes file descriptors inherited from the process
* that forked the current process. Close these file descriptors right

View File

@ -33,44 +33,22 @@ char filea[24];
char fileb[24];
char sock[24];
void
server (void)
void server (void)
{
int s, fd1, fd2;
struct sockaddr_un addr;
fd1 = open(filea, O_RDWR | O_CREAT | O_TRUNC, 0750);
if(fd1 == -1) {
perror("open");
exit(1);
}
fd2 = open(fileb, O_RDWR | O_CREAT | O_TRUNC, 0750);
if(fd2 == -1) {
perror("open");
exit(1);
}
s = socket(PF_UNIX, SOCK_STREAM, 0);
if(s == -1) {
perror("socket");
exit(1);
}
fd1 = DO( open(filea, O_RDWR | O_CREAT | O_TRUNC, 0750) );
fd2 = DO( open(fileb, O_RDWR | O_CREAT | O_TRUNC, 0750) );
s = DO( socket(PF_UNIX, SOCK_STREAM, 0) );
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
sprintf(addr.sun_path, "%s", sock);
unlink(addr.sun_path);
if(bind(s, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
perror("bind");
exit(1);
}
if(listen(s, 5) == -1) {
perror("listen");
exit(1);
}
unlink(sock);
DO( bind(s, (struct sockaddr *)&addr, sizeof(addr)) );
DO( listen(s, 5) );
{
int x;
@ -82,11 +60,7 @@ server (void)
struct iovec iov[1];
memset(&baddr, 0, sizeof(baddr));
x = accept(s, (struct sockaddr *)&baddr, &baddrsize);
if(x == -1) {
perror("accept");
exit(1);
}
x = DO( accept(s, (struct sockaddr *)&baddr, &baddrsize) );
msg.msg_control = buf;
msg.msg_controllen = sizeof(buf);
@ -103,15 +77,11 @@ server (void)
msg.msg_iov = iov;
msg.msg_iovlen = 1;
if(sendmsg(x, &msg, 0) == -1) {
perror("sendmsg");
exit(1);
}
DO( sendmsg(x, &msg, 0) );
}
}
void
client (void)
void client (void)
{
int s, fd1 = -1, fd2 = -1, size, count = 0, ret;
struct sockaddr_un addr;
@ -129,7 +99,7 @@ client (void)
iov[0].iov_len = sizeof(buf);
s = socket(PF_UNIX, SOCK_STREAM, 0);
if(s == -1) {
if (s == -1) {
perror("socket");
exit(1);
}
@ -140,16 +110,16 @@ client (void)
do {
count++;
ret = connect(s, (struct sockaddr *)&addr, sizeof(addr));
if(ret == -1) sleep(1);
if (ret == -1) sleep(1);
} while (count < 10 && ret == -1);
if(ret == -1) {
if (ret == -1) {
perror("connect");
exit(1);
}
again:
if((size = recvmsg(s, &msg, 0)) == -1) {
if ((size = recvmsg(s, &msg, 0)) == -1) {
if (errno == EINTR)
goto again; /* SIGCHLD from server exiting could interrupt */
perror("recvmsg");
@ -158,8 +128,8 @@ client (void)
cmsg = CMSG_FIRSTHDR(&msg);
while(cmsg) {
if(cmsg->cmsg_level == SOL_SOCKET &&
while (cmsg) {
if (cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SCM_RIGHTS &&
cmsg->cmsg_len == CMSG_LEN(sizeof(int) * 2)) {
fd1 = ((int *)CMSG_DATA(cmsg))[0];
@ -169,21 +139,15 @@ client (void)
cmsg = CMSG_NXTHDR(&msg, cmsg);
}
if(fd1 != -1) write(fd1, "Yeah 1\n", 8);
if(fd2 != -1) write(fd2, "Yeah 2\n", 8);
if (fd1 != -1) write(fd1, "Yeah 1\n", 8);
if (fd2 != -1) write(fd2, "Yeah 2\n", 8);
}
int
main (int argc, char **argv)
int main (int argc, char **argv)
{
int pid, status;
CLOSE_INHERITED_FDS;
pid = getpid();
@ -191,7 +155,7 @@ main (int argc, char **argv)
sprintf(fileb, "/tmp/data2.%d", pid);
sprintf(sock, "/tmp/sock.%d", pid);
if((pid = fork()) == 0) {
if ((pid = fork()) == 0) {
server();
return 0;
}
@ -200,8 +164,8 @@ main (int argc, char **argv)
wait(&status);
unlink(filea);
unlink(fileb);
unlink(sock);
DO( unlink(filea) );
DO( unlink(fileb) );
DO( unlink(sock) );
return 0;
}

View File

@ -1,46 +1,46 @@
FILE DESCRIPTORS: 7 open at exit.
Open AF_UNIX socket .: /tmp/sock
Open AF_UNIX socket ...: /tmp/sock
...
Open AF_UNIX socket .: /tmp/sock
Open AF_UNIX socket ...: /tmp/sock
...
Open file descriptor .: /tmp/data2
Open file descriptor ...: /tmp/data2
...
Open file descriptor .: /tmp/data1
Open file descriptor ...: /tmp/data1
...
Open file descriptor .: .
Open file descriptor ...: ...
<inherited from parent>
Open file descriptor .: .
Open file descriptor ...: ...
<inherited from parent>
Open file descriptor .: /dev/null
Open file descriptor ...: /dev/null
<inherited from parent>
FILE DESCRIPTORS: 6 open at exit.
Open file descriptor .: /tmp/data2
Open file descriptor ...: /tmp/data2
...
Open file descriptor .: /tmp/data1
Open file descriptor ...: /tmp/data1
...
Open AF_UNIX socket .: <unknown>
Open AF_UNIX socket ...: <unknown>
...
Open file descriptor .: .
Open file descriptor ...: ...
<inherited from parent>
Open file descriptor .: .
Open file descriptor ...: ...
<inherited from parent>
Open file descriptor .: /dev/null
Open file descriptor ...: /dev/null
<inherited from parent>

View File

@ -2,20 +2,15 @@
#include <stdio.h>
#include <fcntl.h>
#include "fdleak.h"
int
main (int argc, char **argv)
int main (int argc, char **argv)
{
char filename[24];
CLOSE_INHERITED_FDS;
sprintf(filename, "/tmp/file.%d", getpid());
creat(filename, 0);
unlink(filename);
DO( creat(filename, 0) );
DO( unlink(filename) );
return 0;
}

View File

@ -1,16 +1,16 @@
FILE DESCRIPTORS: 4 open at exit.
Open file descriptor .: /tmp/file
Open file descriptor ...: /tmp/file
...
Open file descriptor .: .
Open file descriptor ...: ...
<inherited from parent>
Open file descriptor .: .
Open file descriptor ...: ...
<inherited from parent>
Open file descriptor .: /dev/null
Open file descriptor ...: /dev/null
<inherited from parent>

View File

@ -1,19 +1,15 @@
#include <unistd.h>
#include <fcntl.h>
#include "fdleak.h"
int
main (int argc, char **argv)
int main (int argc, char **argv)
{
int s;
CLOSE_INHERITED_FDS;
s = open("/dev/null", O_RDONLY);
dup(s);
s = DO( open("/dev/null", O_RDONLY) );
DO( dup(s) );
return 0;
}

View File

@ -1,19 +1,19 @@
FILE DESCRIPTORS: 5 open at exit.
Open file descriptor .: /dev/null
Open file descriptor ...: /dev/null
...
Open file descriptor .: /dev/null
Open file descriptor ...: /dev/null
...
Open file descriptor .: .
Open file descriptor ...: ...
<inherited from parent>
Open file descriptor .: .
Open file descriptor ...: ...
<inherited from parent>
Open file descriptor .: /dev/null
Open file descriptor ...: /dev/null
<inherited from parent>

View File

@ -1,23 +1,19 @@
#include <unistd.h>
#include <fcntl.h>
#include "fdleak.h"
int
main (int argc, char **argv)
int main (int argc, char **argv)
{
int s1;
int s2;
CLOSE_INHERITED_FDS;
s1 = open("/dev/null", O_RDONLY);
s2 = open("/dev/null", O_RDONLY);
s1 = DO( open("/dev/null", O_RDONLY) );
s2 = DO( open("/dev/null", O_RDONLY) );
DO( dup2(s1, 20) ); // dup s1 as fd 20
DO( dup2(s1, s2) ); // dup s1 as fd s2, which closes existing s2 fd
dup2(s1, 20);
dup2(s1, s2);
return 0;
}

View File

@ -1,22 +1,22 @@
FILE DESCRIPTORS: 6 open at exit.
Open file descriptor .: /dev/null
Open file descriptor ...: /dev/null
...
Open file descriptor .: /dev/null
Open file descriptor ...: /dev/null
...
Open file descriptor .: /dev/null
Open file descriptor ...: /dev/null
...
Open file descriptor .: .
Open file descriptor ...: ...
<inherited from parent>
Open file descriptor .: .
Open file descriptor ...: ...
<inherited from parent>
Open file descriptor .: /dev/null
Open file descriptor ...: /dev/null
<inherited from parent>

View File

@ -2,19 +2,15 @@
#include <stdio.h>
#include <fcntl.h>
#include "fdleak.h"
int
main (int argc, char **argv)
int main (int argc, char **argv)
{
int s1;
CLOSE_INHERITED_FDS;
s1 = open("/dev/null", O_RDONLY);
if(fcntl(s1, F_DUPFD, s1) == -1) perror("fcntl");
s1 = DO( open("/dev/null", O_RDONLY) );
DO( fcntl(s1, F_DUPFD, s1) );
return 0;
}

View File

@ -1,19 +1,19 @@
FILE DESCRIPTORS: 5 open at exit.
Open file descriptor .: /dev/null
Open file descriptor ...: /dev/null
...
Open file descriptor .: /dev/null
Open file descriptor ...: /dev/null
...
Open file descriptor .: .
Open file descriptor ...: ...
<inherited from parent>
Open file descriptor .: .
Open file descriptor ...: ...
<inherited from parent>
Open file descriptor .: /dev/null
Open file descriptor ...: /dev/null
<inherited from parent>

View File

@ -9,59 +9,40 @@
#include <stdlib.h>
#include <string.h>
#include "fdleak.h"
void
server ()
void server ()
{
int s, x;
struct sockaddr_in baddr;
struct sockaddr_in addr;
int baddrsize = sizeof(baddr);
socklen_t baddrsize = sizeof(baddr);
int one = 1;
s = socket(PF_INET, SOCK_STREAM, 0);
if(s == -1) {
perror("socket");
exit(1);
}
s = DO( socket(PF_INET, SOCK_STREAM, 0) );
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(int));
DO( setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(int)) );
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_port = 12321;
if(bind(s, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
perror("bind");
exit(1);
}
DO( bind(s, (struct sockaddr *)&addr, sizeof(addr)) );
if(listen(s, 5) == -1) {
perror("listen");
exit(1);
}
DO( listen(s, 5) );
memset(&baddr, 0, sizeof(baddr));
x = accept(s, (struct sockaddr *)&baddr, &baddrsize);
if(x == -1) {
perror("accept");
exit(1);
}
x = DO( accept(s, (struct sockaddr *)&baddr, &baddrsize) );
write(x, "hello", 6);
DO( write(x, "hello", 6) );
}
void
client ()
void client ()
{
int s, count = 0, ret;
struct sockaddr_in addr;
char buf[1024];
s = socket(PF_INET, SOCK_STREAM, 0);
if(s == -1) {
perror("socket");
exit(1);
}
s = DO( socket(PF_INET, SOCK_STREAM, 0) );
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
@ -70,33 +51,27 @@ client ()
do {
count++;
ret = connect(s, (struct sockaddr *)&addr, sizeof(addr));
if(ret == -1) sleep(1);
if (ret == -1) sleep(1);
} while (count < 10 && ret == -1);
if(ret == -1) {
if (ret == -1) {
perror("connect");
exit(1);
}
read(s, buf, sizeof(buf));
DO( read(s, buf, sizeof(buf)) );
printf("%s\n", buf);
}
int
main (int argc, char **argv)
int main (int argc, char **argv)
{
int pid, status;
CLOSE_INHERITED_FDS;
if((pid = fork()) == 0) {
if ((pid = fork()) == 0) {
server();
return 0;
}

View File

@ -7,13 +7,13 @@ Open AF_INET socket 4: 127.0.0.1:... <-> 127.0.0.1:...
Open AF_INET socket 3: 127.0.0.1:... <-> unbound
...
Open file descriptor .: .
Open file descriptor ...: ...
<inherited from parent>
Open file descriptor .: .
Open file descriptor ...: ...
<inherited from parent>
Open file descriptor .: /dev/null
Open file descriptor ...: /dev/null
<inherited from parent>
@ -22,13 +22,13 @@ FILE DESCRIPTORS: 4 open at exit.
Open AF_INET socket 3: 127.0.0.1:... <-> 127.0.0.1:...
...
Open file descriptor .: .
Open file descriptor ...: ...
<inherited from parent>
Open file descriptor .: .
Open file descriptor ...: ...
<inherited from parent>
Open file descriptor .: /dev/null
Open file descriptor ...: /dev/null
<inherited from parent>

View File

@ -2,14 +2,11 @@
#include <unistd.h>
#include "fdleak.h"
int
main (int argc, char **argv)
int main (int argc, char **argv)
{
CLOSE_INHERITED_FDS;
open("/dev/null", O_RDONLY);
DO( open("/dev/null", O_RDONLY) );
return 0;
}

View File

@ -1,16 +1,16 @@
FILE DESCRIPTORS: 4 open at exit.
Open file descriptor .: /dev/null
Open file descriptor ...: /dev/null
...
Open file descriptor .: .
Open file descriptor ...: ...
<inherited from parent>
Open file descriptor .: .
Open file descriptor ...: ...
<inherited from parent>
Open file descriptor .: /dev/null
Open file descriptor ...: /dev/null
<inherited from parent>

View File

@ -1,17 +1,13 @@
#include <unistd.h>
#include "fdleak.h"
int
main (int argc, char **argv)
int main (int argc, char **argv)
{
int fds[2];
CLOSE_INHERITED_FDS;
pipe(fds);
DO( pipe(fds) );
return 0;
}

View File

@ -1,19 +1,19 @@
FILE DESCRIPTORS: 5 open at exit.
Open file descriptor .:
Open file descriptor ...:
...
Open file descriptor .:
Open file descriptor ...:
...
Open file descriptor .: .
Open file descriptor ...: ...
<inherited from parent>
Open file descriptor .: .
Open file descriptor ...: ...
<inherited from parent>
Open file descriptor .: /dev/null
Open file descriptor ...: /dev/null
<inherited from parent>

View File

@ -1,17 +1,15 @@
#include <sys/socket.h>
#include <unistd.h>
#include "fdleak.h"
#include <sys/errno.h>
int
main (int argc, char **argv)
int main (int argc, char **argv)
{
int fds[2];
CLOSE_INHERITED_FDS;
socketpair(AF_UNIX, SOCK_STREAM, PF_UNIX, fds);
DO( socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, fds) );
return 0;
}

View File

@ -1,19 +1,19 @@
FILE DESCRIPTORS: 5 open at exit.
Open AF_UNIX socket .: <unknown>
Open AF_UNIX socket ...: <unknown>
...
Open AF_UNIX socket .: <unknown>
Open AF_UNIX socket ...: <unknown>
...
Open file descriptor .: .
Open file descriptor ...: ...
<inherited from parent>
Open file descriptor .: .
Open file descriptor ...: ...
<inherited from parent>
Open file descriptor .: /dev/null
Open file descriptor ...: /dev/null
<inherited from parent>

View File

@ -2,14 +2,16 @@
dir=`dirname $0`
./filter_stderr |
./filter_stderr |
sed s/"^Open AF_UNIX socket [0-9]*: <unknown>/Open AF_UNIX socket .: <unknown>/" |
sed s/"^Open \(AF_UNIX socket\|file descriptor\) [0-9]*: \/dev\/null/Open \\1 .: \/dev\/null/" |
sed s/"^Open \(AF_UNIX socket\|file descriptor\) [0-9]*: \/tmp\/\(sock\|data1\|data2\|file\)\.[0-9]*/Open \\1 .: \/tmp\/\\2/" |
sed s/"^Open file descriptor [0-9]*: .*/Open file descriptor .: ./" |
sed s/"^Open file descriptor [0-9]*:$/Open file descriptor .:/" |
sed s/"127.0.0.1:[0-9]*/127.0.0.1:.../g" |
perl -p -e 's/^Open AF_UNIX socket [0-9]*: <unknown>/Open AF_UNIX socket ...: <unknown>/' |
perl -p -e 's/^Open (AF_UNIX socket|file descriptor) [0-9]*: \/dev\/null/Open $1 ...: \/dev\/null/' |
# Nb: on Darwin, /tmp is a symlink to /private/tmp, so sometimes it's
# necessary to filter out the "/private" part.
perl -p -e 's/^Open (AF_UNIX socket|file descriptor) [0-9]*: (\/private)?\/tmp\/(sock|data1|data2|file)\.[0-9]*/Open $1 ...: \/tmp\/$3/' |
perl -p -e 's/^Open file descriptor [0-9]*: .*/Open file descriptor ...: .../' |
perl -p -e 's/^Open file descriptor [0-9]*:$/Open file descriptor ...:/' |
perl -p -e 's/127.0.0.1:[0-9]*/127.0.0.1:.../g' |
# Stack traces showing where fds were created have lots of variations:
# different numbers of entries, line numbers or not depending on whether