summaryrefslogtreecommitdiff
path: root/missing/setproctitle.c
diff options
context:
space:
mode:
authorPeter Zhu <peter@peterzhu.ca>2024-01-09 13:17:17 -0500
committerPeter Zhu <peter@peterzhu.ca>2024-01-11 10:09:53 -0500
commit057df4379f856a868f588cdc769f397f5739983d (patch)
tree2cc451d9af23b2c69a8804383ee754922ddff6c5 /missing/setproctitle.c
parent4e0c2f05efc9415b52b50ee65401c5b511d269e7 (diff)
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
Diffstat (limited to 'missing/setproctitle.c')
-rw-r--r--missing/setproctitle.c42
1 files changed, 38 insertions, 4 deletions
diff --git a/missing/setproctitle.c b/missing/setproctitle.c
index 6a85323818..d718123802 100644
--- a/missing/setproctitle.c
+++ b/missing/setproctitle.c
@@ -80,10 +80,20 @@ static char **argv1_addr = NULL;
#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
compat_init_setproctitle(int argc, char *argv[])
{
-#if defined(SPT_TYPE) && SPT_TYPE == SPT_REUSEARGV
+#if ALLOCATE_ENVIRON
extern char **environ;
char *lastargv = NULL;
char *lastenvp = NULL;
@@ -100,9 +110,10 @@ compat_init_setproctitle(int argc, char *argv[])
return;
/* Fail if we can't allocate room for the new environment */
- for (i = 0; envp[i] != NULL; i++)
- ;
- if ((environ = calloc(i + 1, sizeof(*environ))) == NULL) {
+ for (i = 0; envp[i] != NULL; i++);
+
+ orig_environ = environ = xcalloc(i + 1, sizeof(*environ));
+ if (environ == NULL) {
environ = envp; /* put it back */
return;
}
@@ -134,6 +145,29 @@ compat_init_setproctitle(int argc, char *argv[])
#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
void