Use syscall(2) rather than {open,read,close}(2) during boot.

Some applications wrap various system calls, and if they call the
allocator in their wrappers, unexpected reentry can result.  This is not
a general solution (many other syscalls are spread throughout the code),
but this resolves a bootstrapping issue that is apparently common.

This resolves #443.
This commit is contained in:
Jason Evans 2016-10-29 22:41:04 -07:00
parent af0e28fd94
commit d87037a62c

View File

@ -207,6 +207,11 @@ os_overcommits_sysctl(void)
#endif #endif
#ifdef JEMALLOC_PROC_SYS_VM_OVERCOMMIT_MEMORY #ifdef JEMALLOC_PROC_SYS_VM_OVERCOMMIT_MEMORY
/*
* Use syscall(2) rather than {open,read,close}(2) when possible to avoid
* reentry during bootstrapping if another library has interposed system call
* wrappers.
*/
static bool static bool
os_overcommits_proc(void) os_overcommits_proc(void)
{ {
@ -214,12 +219,26 @@ os_overcommits_proc(void)
char buf[1]; char buf[1];
ssize_t nread; ssize_t nread;
#ifdef SYS_open
fd = (int)syscall(SYS_open, "/proc/sys/vm/overcommit_memory", O_RDONLY);
#else
fd = open("/proc/sys/vm/overcommit_memory", O_RDONLY); fd = open("/proc/sys/vm/overcommit_memory", O_RDONLY);
#endif
if (fd == -1) if (fd == -1)
return (false); /* Error. */ return (false); /* Error. */
#ifdef SYS_read
nread = (ssize_t)syscall(SYS_read, fd, &buf, sizeof(buf));
#else
nread = read(fd, &buf, sizeof(buf)); nread = read(fd, &buf, sizeof(buf));
#endif
#ifdef SYS_close
syscall(SYS_close, fd);
#else
close(fd); close(fd);
#endif
if (nread < 1) if (nread < 1)
return (false); /* Error. */ return (false); /* Error. */
/* /*