I submitted this as a pull request for shyouhei's ruby git repo, via github.
I want to document this here too.
The environ manipulations that are done in the fall-back code in hash.c (the code that runs if !WIN32 and !HAVE_SETENV) causes crashes in Solaris some times. In addition, it fails hard if you use the binary on a newer version of Solaris.
The code I wrote works on Solaris 8 (all tests pass) and works when the binary is copied to a Solaris 10 system and some simple test code that sets and unsets lots of environment variable is run.
With a clean ruby, the test cases pass in Solaris 8 (usually) but my test code would not run at all when the binary is copied to Solaris 10.
If there is anything else I should do, please don't hesitant to tell me.
At Wed, 11 Nov 2009 04:50:33 +0900,
Christian Höltje wrote in [ruby-core:26668]:
The environ manipulations that are done in the fall-back code
in hash.c (the code that runs if !WIN32 and !HAVE_SETENV)
causes crashes in Solaris some times. In addition, it fails
hard if you use the binary on a newer version of Solaris.
What does this note mean?
* Note: This does leak memory and there isn't anything we can do
* about it.
putenv()ed string is stored in environ but isn't freed?
=begin
Because new variables are allocated by ALLOC_N() but the unsetenv code cannot de-allocate the memory: we don't know if it is initially allocated memory by the kernel (which I think is stack memory and absolutely cannot be free()d) or if it is something we did a putenv() on (which we cannot free() either, depending on the platform).
At Wed, 11 Nov 2009 11:32:37 +0900,
Christian Höltje wrote in [ruby-core:26675]:
Because new variables are allocated by ALLOC_N() but the
unsetenv code cannot de-allocate the memory: we don't know if
it is initially allocated memory by the kernel (which I think
is stack memory and absolutely cannot be free()d) or if it is
something we did a putenv() on (which we cannot free()
either, depending on the platform).
=begin
I'm not sure the reclaiming is actually working. I ran some tests and it at least appears that it may not be reclaiming much or any. I'm not entirely sure how to test that.
I think I would recommend using the original style unsetenv code I used and just live with the memory leak. It's not usually that much and is usually done right before an exec()...
=begin
This issue was solved with changeset r25766.
Christian, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.