From: Jeremy Fitzhardinge Date: Thu, 18 Dec 2003 02:39:22 +0000 (+0000) Subject: Patch from Tom Hughes: set VG_(max_fd) based on the current file X-Git-Tag: svn/VALGRIND_2_1_1~175 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ebe35cedb9a1ac99d40d238762c053e79c013299;p=thirdparty%2Fvalgrind.git Patch from Tom Hughes: set VG_(max_fd) based on the current file descriptor limit rather than assuming 1024. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@2127 --- diff --git a/coregrind/vg_include.h b/coregrind/vg_include.h index 179e41fd41..0ce9b13748 100644 --- a/coregrind/vg_include.h +++ b/coregrind/vg_include.h @@ -108,14 +108,9 @@ give finer interleaving but much increased scheduling overheads. */ #define VG_SCHEDULING_QUANTUM 50000 -/* Maximum FD Valgrind can use for its internal file descriptors. */ -#define VG_MAX_SAFE_FD 1024 /* usual ulimit */ - -/* Maximum allowed application-visible file descriptor. Valgrind's - internal fds hide above this (starting at VG_MAX_FD+1). This is - derived from the default fd limit (1024) minus the 2 fds per thread - and a small number of extra fds. */ -#define VG_MAX_FD (VG_MAX_SAFE_FD - (VG_N_THREADS*2 + 4)) +/* Number of file descriptors that Valgrind tries to reserve for + it's own use - two per thread plues a small number of extras. */ +#define VG_N_RESERVED_FDS (VG_N_THREADS*2 + 4) /* Stack size for a thread. We try and check that they do not go beyond it. */ @@ -182,6 +177,9 @@ extern Int VG_(main_pid); /* pgrp of process (global to all threads) */ extern Int VG_(main_pgrp); +/* Maximum allowed application-visible file descriptor */ +extern Int VG_(max_fd); + /* Should we stop collecting errors if too many appear? default: YES */ extern Bool VG_(clo_error_limit); /* Enquire about whether to attach to GDB at errors? default: NO */ diff --git a/coregrind/vg_main.c b/coregrind/vg_main.c index 9222f2e47e..f007714e9b 100644 --- a/coregrind/vg_main.c +++ b/coregrind/vg_main.c @@ -153,6 +153,9 @@ Int VG_(main_pid); /* PGRP of process */ Int VG_(main_pgrp); +/* Maximum allowed application-visible file descriptor */ +Int VG_(max_fd); + /* Words. */ static Int baB_off = 0; @@ -1109,7 +1112,7 @@ static void process_cmd_line_options ( const KickstartParams *kp ) } /* Move logfile_fd into the safe range, so it doesn't conflict with any app fds */ - eventually_logfile_fd = VG_(fcntl)(VG_(clo_logfile_fd), VKI_F_DUPFD, VG_MAX_FD+1); + eventually_logfile_fd = VG_(fcntl)(VG_(clo_logfile_fd), VKI_F_DUPFD, VG_(max_fd)+1); if (eventually_logfile_fd < 0) VG_(message)(Vg_UserMsg, "valgrind: failed to move logfile fd into safe range"); else { @@ -1364,6 +1367,7 @@ static void newpid(ThreadId unused) void VG_(main) ( const KickstartParams *kp, void (*tool_init)(void), void *tool_dlhandle ) { VgSchedReturnCode src; + struct vki_rlimit rl; /* initial state */ if (0) @@ -1414,6 +1418,25 @@ void VG_(main) ( const KickstartParams *kp, void (*tool_init)(void), void *tool_ VG_(atfork)(NULL, NULL, newpid); newpid(VG_INVALID_THREADID); + /* Get the current file descriptor limits. */ + if (VG_(getrlimit)(VKI_RLIMIT_NOFILE, &rl) < 0) { + rl.rlim_cur = 1024; + rl.rlim_max = 1024; + } + + /* Work out where to move the soft limit to. */ + if (rl.rlim_cur + VG_N_RESERVED_FDS <= rl.rlim_max) { + rl.rlim_cur = rl.rlim_cur + VG_N_RESERVED_FDS; + } else { + rl.rlim_cur = rl.rlim_max; + } + + /* Reserve some file descriptors for our use. */ + VG_(max_fd) = rl.rlim_cur - VG_N_RESERVED_FDS; + + /* Update the soft limit. */ + VG_(setrlimit)(VKI_RLIMIT_NOFILE, &rl); + /* Read /proc/self/maps into a buffer. Must be before: - SK_(pre_clo_init)(): so that if it calls VG_(malloc)(), any mmap'd superblocks are not erroneously identified as being owned by the diff --git a/coregrind/vg_mylibc.c b/coregrind/vg_mylibc.c index dbf78ebdeb..850e1785b7 100644 --- a/coregrind/vg_mylibc.c +++ b/coregrind/vg_mylibc.c @@ -1203,13 +1203,13 @@ Int VG_(safe_fd)(Int oldfd) { Int newfd; - newfd = VG_(fcntl)(oldfd, VKI_F_DUPFD, VG_MAX_FD+1); + newfd = VG_(fcntl)(oldfd, VKI_F_DUPFD, VG_(max_fd)+1); if (newfd != -1) VG_(close)(oldfd); VG_(fcntl)(newfd, VKI_F_SETFD, VKI_FD_CLOEXEC); - vg_assert(newfd > VG_MAX_FD); + vg_assert(newfd > VG_(max_fd)); return newfd; } @@ -1429,6 +1429,17 @@ Int VG_(getrlimit) (Int resource, struct vki_rlimit *rlim) } +/* Support for setrlimit. */ +Int VG_(setrlimit) (Int resource, struct vki_rlimit *rlim) +{ + Int res; + /* res = setrlimit( resource, rlim ); */ + res = VG_(do_syscall)(__NR_setrlimit, (UInt)resource, (UInt)rlim); + if(VG_(is_kerror)(res)) res = -1; + return res; +} + + /* Support for getdents. */ Int VG_(getdents) (UInt fd, struct vki_dirent *dirp, UInt count) { diff --git a/coregrind/vg_syscalls.c b/coregrind/vg_syscalls.c index 0e5ffb0ee8..a213adc319 100644 --- a/coregrind/vg_syscalls.c +++ b/coregrind/vg_syscalls.c @@ -311,7 +311,7 @@ void record_fd_close(Int tid, Int fd) { OpenFd *i = allocated_fds; - if (fd > VG_MAX_FD) + if (fd > VG_(max_fd)) return; /* Valgrind internal */ while(i) { @@ -344,7 +344,7 @@ void record_fd_open(Int tid, Int fd, char *pathname) { OpenFd *i; - if (fd > VG_MAX_FD) + if (fd > VG_(max_fd)) return; /* Valgrind internal */ /* Check to see if this fd is already open. */ @@ -889,7 +889,7 @@ static Bool valid_client_addr(Addr start, UInt size, ThreadId tid, const Char *s /* Return true if we're allowed to use or create this fd */ static Bool fd_allowed(Int fd, const Char *syscall, ThreadId tid) { - if (fd < 0 || fd > VG_MAX_FD || fd == VG_(clo_logfile_fd)) { + if (fd < 0 || fd > VG_(max_fd) || fd == VG_(clo_logfile_fd)) { VG_(message)(Vg_UserMsg, "Warning: invalid file descriptor %d in syscall %s()", fd, syscall); @@ -4155,7 +4155,7 @@ POST(socketcall) switch (arg1 /* request */) { case SYS_SOCKETPAIR: - /* XXX TODO: check return fd against VG_MAX_FD */ + /* XXX TODO: check return fd against VG_(max_fd) */ VG_TRACK( post_mem_write, ((UInt*)arg2)[3], 2*sizeof(int) ); if(VG_(clo_track_fds)) { record_fd_open(tid, ((UInt*)((UInt*)arg2)[3])[0], NULL); diff --git a/include/vg_skin.h.base b/include/vg_skin.h.base index cfee479e58..e7ca38fad2 100644 --- a/include/vg_skin.h.base +++ b/include/vg_skin.h.base @@ -396,6 +396,9 @@ extern Char* VG_(getenv) ( Char* name ); /* Get client resource limit*/ extern Int VG_(getrlimit) ( Int resource, struct vki_rlimit *rlim ); +/* Set client resource limit*/ +extern Int VG_(setrlimit) ( Int resource, struct vki_rlimit *rlim ); + /* Crude stand-in for the glibc system() call. */ extern Int VG_(system) ( Char* cmd );