We need to keep a pointer to the originally allocated environ because
adding more environment variables can cause it to be changed to something
else.
For example:
100.times do |i|
ENV["FOO#{i}"] = "1"
end
Causes Valgrind to report:
312 bytes in 1 blocks are definitely lost in loss record 9 of 13
at 0x484D444: calloc (vg_replace_malloc.c:1340)
by 0x1884F8: calloc1 (gc.c:1844)
by 0x1884F8: objspace_xcalloc (gc.c:12202)
by 0x1884F8: ruby_xcalloc_body (gc.c:12209)
by 0x4204DD: ruby_init_setproctitle (setproctitle.c:119)
by 0x27DDF4: ruby_process_options (ruby.c:3101)
by 0x160BD1: ruby_options (eval.c:117)
by 0x15B96E: rb_main (main.c:40)
by 0x15B96E: main (main.c:59)
The call to setenv replaces the string in the environ array, which causes
the original string to be reported as a memory leak.
This commit allocates another copy of environ called alloc_environ that
contains the strings allocated by ruby_init_setproctitle. Then in
ruby_free_proctitle it frees all the strings in alloc_environ.
For example:
ENV.each { |k, v| ENV[k] = v.dup }
Valgrind reports:
3,321 bytes in 39 blocks are definitely lost in loss record 3 of 3
at 0x484884F: malloc (vg_replace_malloc.c:393)
by 0x25CB5B: objspace_xmalloc0 (gc.c:11972)
by 0x40344E: ruby_strdup (util.c:540)
by 0x59C854: ruby_init_setproctitle (setproctitle.c:143)
by 0x38CC44: ruby_process_options (ruby.c:3101)
by 0x234DB1: ruby_options (eval.c:117)
by 0x15B92E: rb_main (main.c:40)
by 0x15B92E: main (main.c:59)
It is undefined behaviour to free environ as it is managed by the system.
This caused RUBY_FREE_AT_EXIT to double free on systems like Linux. This
commit changes it to only free orig_environ, which is enough to make
both Valgrind and macOS leaks tools to not detect memory leaks.
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
when the RUBY_FREE_ON_SHUTDOWN environment variable is set, manually free memory at shutdown.
Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org>
Co-authored-by: Peter Zhu <peter@peterzhu.ca>
Fixed the race condition when replacing `freelist` entry with its
chained next element. At acquiring an entry, hold the entry once
with the special value, then release by replacing it with the next
element again after acquired. If another thread is holding the
same entry at that time, spinning until the entry gets released.
Co-Authored-By: Koichi Sasada <ko1@atdot.net>
According to MSVC manual (*1), cl.exe can skip including a header file
when that:
- contains #pragma once, or
- starts with #ifndef, or
- starts with #if ! defined.
GCC has a similar trick (*2), but it acts more stricter (e. g. there
must be _no tokens_ outside of #ifndef...#endif).
Sun C lacked #pragma once for a looong time. Oracle Developer Studio
12.5 finally implemented it, but we cannot assume such recent version.
This changeset modifies header files so that each of them include
strictly one #ifndef...#endif. I believe this is the most portable way
to trigger compiler optimizations. [Bug #16770]
*1: https://docs.microsoft.com/en-us/cpp/preprocessor/once
*2: https://gcc.gnu.org/onlinedocs/cppinternals/Guard-Macros.html
Noticed that internal/stdbool.h and addr2line.c are the only two place
where missing/stdbool.h is included. Why not delete the file so that
we can merge internal/stdbool.h and missing/stdbool.h into one.
If fmt is NULL, ptitle is uninitialized and used.
SETPROCTITLE(3bsd) says "If fmt is NULL, the process title is restored",
but looks like the feature is not implemented in missing/setproctitle.c.
At least the source code of ruby does not pass NULL to the function.
So I assume this function requires non-NULL fmt.
This issue was found by Coverity Scan.
because we had another one in missing/stdbool.h as well.
Assuming that _Bool does not exist when stdbool.h is absent, I'm in
favor of r57462 implementation rather than r61326.
Note that Visual Studio 2013 has stdbool.h and thus r57462's commit
message is somewhat misleading. This missing/stdbool.h is for Visual
Studio 2012 or older, and for Oracle Solaris Studio 12.2 or older because
it's added in 12.3 https://docs.oracle.com/cd/E24457_01/html/E21987/gkeza.html.
missing/stdbool.h: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66739 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
instead of scattering #ifdef HAVE_NANF here and there define our
own nan() unless defined elsewhere.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61971 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* addr2line.c: Because stdbool.h is a C99 feature, compile error
occurs with some old compilers without specifying C99 options.
Fix compile error with Oracle Solaris Studio 12.4 on Solaris 10.
[Bug #14200] [ruby-dev:50366]
* missing/stdbool.h: Alternative of stdbool.h for C89 compilers.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61326 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Use ALLOCV to allocate struct crypt_data for slightly cleaner and less
error-prone code. It is currently possible it leaks when an invalid
argument is passed to String#crypt or rb_str_new_cstr() fails to
allocate memory.
SIZEOF_CRYPT_DATA macro in missing/crypt.h is removed since it is not
used any longer.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60748 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Because NaCl and PNaCl are already sunset status.
see https://bugs.chromium.org/p/chromium/issues/detail?id=239656#c160
configure.ac: Patch for this file was provided by @nobu.
[Feature #14041][ruby-core:83497][fix GH-1726]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60374 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* string.c (rb_str_crypt): struct crypt_data defined in
missing/crypt.h is small enough.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58866 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* configure.in: do not use buggy tgamma() of mingw.
* missing/tgamma.c (tgamma): merge fix for inifity from
ruby_tgamma. since msvcr120.dll and later have tgamma, this
implementation will not be used.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58691 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
It is never used. We don't need it anyway as it's part of C89 which is
our current minimum requirement.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58430 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* missing/crypt.h (B64): use LONG_LONG instead of long long
directly.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55533 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* defs/gmake.mk (missing/des_tables.c): move the recipe from
common.mk. this is less common.
* missing/crypt.c (init_des): if des_tables.c is empty, initialize
DES tables at runtime.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55274 b2dd03c8-39d4-4d8f-98ff-823fe69b080e