From: Eric Wong Date: 2011-03-15T04:39:17+09:00 Subject: [ruby-core:35496] Re: /proc/$PID/environ in Linux KOSAKI Motohiro wrote: > > @@ -1810,6 +1822,14 @@ set_arg0(VALUE val, ID id) > > �� �� setproctitle("%.*s", (int)i, s); > > ��#else > > > > +# ifdef USE_ENVSPACE_FOR_ARG0 > > + �� ��if (envspace_capa > 0 && (size_t)i > origarg.len - origarg.argc) { > > + �� �� �� move_environ(); > > + �� �� �� origarg.len += envspace_capa; > > + �� �� �� envspace_capa = 0; > > + �� ��} > > +# endif > > No. this is thread unsafe. therefore it is MVM unsafe. > I don't want to increase MVM unsafe code anymore. > > Please simply do lazy zero fill, not environemt moving itself. Checking origarg.len/envspace_capa and modifying them wouldn't be thread-safe without a lock, either, wouldn't it? I think the entire hunk that cares for origarg.len will need a lock around it for MVM. Here's an updated patch without locks for now: From 3074f19907648e25fd5d3a6162e355a5b7073d84 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Sun, 13 Mar 2011 08:39:15 +0000 Subject: [PATCH] ruby.c: avoid clobbering environ for $0 changes This allows /proc//environ on Linux to remain useful for minor $0 modifications. This is especially useful for Ruby because argv storage space is inflated from shebang usage so there's less need for environ space. I've only tested this on Linux 2.6 --- ruby.c | 11 +++++++++++ 1 files changed, 11 insertions(+), 0 deletions(-) diff --git a/ruby.c b/ruby.c index c5d46ed..16640b6 100644 --- a/ruby.c +++ b/ruby.c @@ -1733,6 +1733,7 @@ rb_load_file(const char *fname) #ifdef USE_ENVSPACE_FOR_ARG0 extern char **environ; +static size_t envspace_capa; #endif static size_t @@ -1755,6 +1756,7 @@ get_arglen(int argc, char **argv) } #if defined(USE_ENVSPACE_FOR_ARG0) if (environ && (s+1 == environ[0])) { + char *pre_env = s; s++; s += strlen(s); for (i = 1; environ[i]; i++) { @@ -1776,6 +1778,8 @@ get_arglen(int argc, char **argv) # else ruby_setenv("", NULL); /* duplicate environ vars */ # endif + envspace_capa = s - pre_env; + s = pre_env; } #endif return s - argv[0]; @@ -1810,6 +1814,13 @@ set_arg0(VALUE val, ID id) setproctitle("%.*s", (int)i, s); #else +# ifdef USE_ENVSPACE_FOR_ARG0 + if (envspace_capa > 0 && (size_t)i > origarg.len - origarg.argc) { + origarg.len += envspace_capa; + envspace_capa = 0; + } +# endif + if ((size_t)i > origarg.len - origarg.argc) { i = (long)(origarg.len - origarg.argc); } -- Eric Wong