Bug 432508 - Valgrind does not honor setrlimit RLIMIT_NOFILE changes
Summary: Valgrind does not honor setrlimit RLIMIT_NOFILE changes
Status: RESOLVED NOT A BUG
Alias: None
Product: valgrind
Classification: Developer tools
Component: general (other bugs)
Version First Reported In: 3.15 SVN
Platform: Other Linux
: NOR normal
Target Milestone: ---
Assignee: Julian Seward
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-02-04 14:34 UTC by Balint Reczey
Modified: 2023-01-13 08:41 UTC (History)
2 users (show)

See Also:
Latest Commit:
Version Fixed/Implemented In:
Sentry Crash Report:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Balint Reczey 2021-02-04 14:34:22 UTC
SUMMARY

Valgrind uses open file limits in effect when valgrind starts, ignoring the changes made my the debugged program.

STEPS TO REPRODUCE

$ cat many-files.c
#include <assert.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/resource.h>

int main (int argc, char ** argv) {
  int i;
  struct rlimit rlim;
  getrlimit(RLIMIT_NOFILE, &rlim);
  assert(rlim.rlim_cur <= 1024);

  rlim.rlim_cur = 2048;
  setrlimit(RLIMIT_NOFILE, &rlim);

  for (i = 4; i < 1028; i++) {
    dup2(1, i);
  }
  for (i = 4; i < 1028; i++) {
    close(i);
  }
  return 1;
}
$ gcc many-files.c
$ valgrind ./a.out

OBSERVED RESULT
 
==3814075== Memcheck, a memory error detector
==3814075== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==3814075== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==3814075== Command: ./a.out
==3814075== 
==3814075== Warning: invalid file descriptor 1024 in syscall dup2()
==3814075== Warning: invalid file descriptor 1025 in syscall dup2()
==3814075== Warning: invalid file descriptor 1026 in syscall dup2()
==3814075== Warning: invalid file descriptor 1027 in syscall dup2()
==3814075==    Use --log-fd=<number> to select an alternative log fd.
==3814075== Warning: invalid file descriptor 1024 in syscall close()
==3814075== Warning: invalid file descriptor 1025 in syscall close()
==3814075== Warning: invalid file descriptor 1026 in syscall close()
==3814075== Warning: invalid file descriptor 1027 in syscall close()
==3814075==    Use --log-fd=<number> to select an alternative log fd.
==3814075== 
==3814075== HEAP SUMMARY:
==3814075==     in use at exit: 0 bytes in 0 blocks
==3814075==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==3814075== 
==3814075== All heap blocks were freed -- no leaks are possible
==3814075== 
==3814075== For lists of detected and suppressed errors, rerun with: -s
==3814075== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)


EXPECTED RESULT

Valgrind notices RLIMIT_NOFILE changes and uses the new limit in fd validity check.

SOFTWARE/OS VERSIONS
Linux/KDE Plasma: Ubuntu 20.04
Valgrind: valgrind-3.15.0
Comment 1 Tom Hughes 2021-02-04 14:49:34 UTC
Because valgrind has to reserve some file descriptors for it's own use at the top of the range it is not able to honour all requests to increase limits.

What were the soft and hard limits when your program started?
Comment 2 Balint Reczey 2021-02-04 15:42:22 UTC
$ ulimit -S -n
1024
$ ulimit -H -n
1048576
Comment 3 Tom Hughes 2021-02-04 16:02:59 UTC
Right to basically what valgrind does is that it increases the soft limit by the number of descriptors it wants to reserve for itself, and then lowers the emulated soft and hard limits to the soft limit.

So you should find that your first getrlimit actually reports a hard limit of 1024 as well as a soft limit of 1024 and that your setrlimit fails.

So basically this is one place where the emulated environment is not quite the same as the host environment, but if you pay attention to system call results you should get results which match the emulated environment.

If you need more descriptors when running under valgrind then you will need to raise the soft limit before starting it.
Comment 4 Paul Floyd 2023-01-13 08:41:46 UTC
I don't see a problem here - it's the way that Valgrind works.