зеркало из https://github.com/github/ruby.git
Free environ when RUBY_FREE_AT_EXIT
The environ is malloc'd, so it gets reported as a memory leak. This commit adds ruby_free_proctitle which frees it during shutdown when RUBY_FREE_AT_EXIT is set. STACK OF 1 INSTANCE OF 'ROOT LEAK: <calloc in ruby_init_setproctitle>': 5 dyld 0x18b7090e0 start + 2360 4 ruby 0x10000e3a8 main + 100 main.c:58 3 ruby 0x1000b4dfc ruby_options + 180 eval.c:121 2 ruby 0x1001c5f70 ruby_process_options + 200 ruby.c:3014 1 ruby 0x10035c9fc ruby_init_setproctitle + 76 setproctitle.c:105 0 libsystem_malloc.dylib 0x18b8c7b78 _malloc_zone_calloc_instrumented_or_legacy + 100
This commit is contained in:
Родитель
4e0c2f05ef
Коммит
057df4379f
|
@ -19320,6 +19320,7 @@ vm.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
vm.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
vm.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
||||||
vm.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
vm.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
vm.$(OBJEXT): $(top_srcdir)/internal/inits.h
|
vm.$(OBJEXT): $(top_srcdir)/internal/inits.h
|
||||||
|
vm.$(OBJEXT): $(top_srcdir)/internal/missing.h
|
||||||
vm.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
vm.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
||||||
vm.$(OBJEXT): $(top_srcdir)/internal/object.h
|
vm.$(OBJEXT): $(top_srcdir)/internal/object.h
|
||||||
vm.$(OBJEXT): $(top_srcdir)/internal/parse.h
|
vm.$(OBJEXT): $(top_srcdir)/internal/parse.h
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
/* missing/setproctitle.c */
|
/* missing/setproctitle.c */
|
||||||
#ifndef HAVE_SETPROCTITLE
|
#ifndef HAVE_SETPROCTITLE
|
||||||
extern void ruby_init_setproctitle(int argc, char *argv[]);
|
extern void ruby_init_setproctitle(int argc, char *argv[]);
|
||||||
|
extern void ruby_free_proctitle(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* INTERNAL_MISSING_H */
|
#endif /* INTERNAL_MISSING_H */
|
||||||
|
|
|
@ -80,10 +80,20 @@ static char **argv1_addr = NULL;
|
||||||
|
|
||||||
#endif /* HAVE_SETPROCTITLE */
|
#endif /* HAVE_SETPROCTITLE */
|
||||||
|
|
||||||
|
#if defined(SPT_TYPE) && SPT_TYPE == SPT_REUSEARGV
|
||||||
|
# define ALLOCATE_ENVIRON 1
|
||||||
|
#else
|
||||||
|
# define ALLOCATE_ENVIRON 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ALLOCATE_ENVIRON
|
||||||
|
static char **orig_environ = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
compat_init_setproctitle(int argc, char *argv[])
|
compat_init_setproctitle(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
#if defined(SPT_TYPE) && SPT_TYPE == SPT_REUSEARGV
|
#if ALLOCATE_ENVIRON
|
||||||
extern char **environ;
|
extern char **environ;
|
||||||
char *lastargv = NULL;
|
char *lastargv = NULL;
|
||||||
char *lastenvp = NULL;
|
char *lastenvp = NULL;
|
||||||
|
@ -100,9 +110,10 @@ compat_init_setproctitle(int argc, char *argv[])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Fail if we can't allocate room for the new environment */
|
/* Fail if we can't allocate room for the new environment */
|
||||||
for (i = 0; envp[i] != NULL; i++)
|
for (i = 0; envp[i] != NULL; i++);
|
||||||
;
|
|
||||||
if ((environ = calloc(i + 1, sizeof(*environ))) == NULL) {
|
orig_environ = environ = xcalloc(i + 1, sizeof(*environ));
|
||||||
|
if (environ == NULL) {
|
||||||
environ = envp; /* put it back */
|
environ = envp; /* put it back */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -134,6 +145,29 @@ compat_init_setproctitle(int argc, char *argv[])
|
||||||
#endif /* SPT_REUSEARGV */
|
#endif /* SPT_REUSEARGV */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ruby_free_proctitle(void)
|
||||||
|
{
|
||||||
|
#if ALLOCATE_ENVIRON
|
||||||
|
extern char **environ;
|
||||||
|
|
||||||
|
if (!orig_environ) return; /* environ is allocated by OS */
|
||||||
|
|
||||||
|
for (int i = 0; environ[i] != NULL; i++) {
|
||||||
|
xfree(environ[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ruby_setenv could allocate a new environ, so we need to free both environ
|
||||||
|
* orig_environ in that case. */
|
||||||
|
if (environ != orig_environ) {
|
||||||
|
xfree(orig_environ);
|
||||||
|
orig_environ = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
xfree(environ);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef HAVE_SETPROCTITLE
|
#ifndef HAVE_SETPROCTITLE
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
5
vm.c
5
vm.c
|
@ -20,6 +20,7 @@
|
||||||
#include "internal/eval.h"
|
#include "internal/eval.h"
|
||||||
#include "internal/gc.h"
|
#include "internal/gc.h"
|
||||||
#include "internal/inits.h"
|
#include "internal/inits.h"
|
||||||
|
#include "internal/missing.h"
|
||||||
#include "internal/object.h"
|
#include "internal/object.h"
|
||||||
#include "internal/proc.h"
|
#include "internal/proc.h"
|
||||||
#include "internal/re.h"
|
#include "internal/re.h"
|
||||||
|
@ -3034,6 +3035,10 @@ ruby_vm_destruct(rb_vm_t *vm)
|
||||||
xfree(th->nt);
|
xfree(th->nt);
|
||||||
th->nt = NULL;
|
th->nt = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef HAVE_SETPROCTITLE
|
||||||
|
ruby_free_proctitle();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (th) {
|
if (th) {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче