rice 4.11.4 → 4.11.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '07196451c8152b8110d5a2aa17d9d1073c846139a8e08d3fe71217095c3386d6'
4
- data.tar.gz: d0a84860a008461a29396679953abe8377f24b92ee9085ed84820dd946065390
3
+ metadata.gz: ad1a2f20f3096248c8bc064f5c091f3d70b326b41bbf3664fdab408f646a8fd3
4
+ data.tar.gz: ed6fe5f0813e2cfee4082ddb7604e7c8f0aba9c808c0b746e6c4c801e74dda19
5
5
  SHA512:
6
- metadata.gz: 1d560e79db1a4645bd6d1084e0df00a44d79795b14d963292e731912c1bcabf29578846ff18a2bf8f8cdb171419c1b13be66b358582328ff5e4d18c61aee8731
7
- data.tar.gz: bfa6478914622bf559db804f3ccb10fd51c39973ff7032a07d2ced37c7d5fbbacd3b9417ed4399499f97f209ec115daecabd7e9ab75a145dfaba9c6c2d94478e
6
+ metadata.gz: 98346333fe05760e510b0485be685c55e4866e7d79412c53dcb3226796bcb6b2f42a5dcbc748263d65566fb2bf545c3a7faae408b5f9db59b37c4c0784ad15f6
7
+ data.tar.gz: aabd681ffe8bc092303857466baddec01efea860e42a801e56d49137feb360229a243c1adcb2770fd5be4ffc791505e20bb84e55af867a3c765be8b847b92d8e
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 4.11.5 (2026-03-23)
4
+
5
+ ### Bug Fixes
6
+
7
+ * Fix Valgrind invalid reads caused by stale GC root addresses. This was caused by an unforunate interaction with minitest when registering exit blocks via rb_set_end_proc. Fixed by switching to ruby_vm_at_exit.
8
+ * Add -Wno-array-bounds for g++ 15 false positive in Ruby's RSTRING macro to avoid g++15 false positive warning when inlining through Ruby's RSTRING macro (ruby/internal/core/rstring.h)
9
+ * Document g++ 15.2.1 / binutils 2.45.1 issue where LTO triggers an internal assembler segfault. This is not something Rice can fix, but the workaround (-fno-lto) is documented in build_settings.md.
10
+
3
11
  ## 4.11.4 (2026-03-13)
4
12
 
5
13
  ### Bug Fixes
data/CMakePresets.json CHANGED
@@ -9,7 +9,7 @@
9
9
  "installDir": "${sourceDir}/install/${presetName}",
10
10
  "cacheVariables": {
11
11
  "CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
12
- "CMAKE_CXX_FLAGS": "-Wall -ftemplate-backtrace-limit=0 -fvisibility=hidden -fvisibility-inlines-hidden"
12
+ "CMAKE_CXX_FLAGS": "-Wall -Wno-array-bounds -ftemplate-backtrace-limit=0 -fvisibility=hidden -fvisibility-inlines-hidden"
13
13
  }
14
14
  },
15
15
  {
@@ -81,7 +81,7 @@
81
81
  "cacheVariables": {
82
82
  "CMAKE_BUILD_TYPE": "Debug",
83
83
  "CMAKE_CXX_COMPILER": "g++.exe",
84
- "CMAKE_CXX_FLAGS": "-Wall -ftemplate-backtrace-limit=0 -Wa,-mbig-obj -fvisibility=hidden -fvisibility-inlines-hidden",
84
+ "CMAKE_CXX_FLAGS": "-Wall -Wno-array-bounds -ftemplate-backtrace-limit=0 -Wa,-mbig-obj -fvisibility=hidden -fvisibility-inlines-hidden",
85
85
  "CMAKE_CXX_FLAGS_DEBUG": "-g3 -Og -fno-omit-frame-pointer -fno-inline -gsplit-dwarf"
86
86
  },
87
87
  "condition": {
@@ -97,7 +97,7 @@
97
97
  "cacheVariables": {
98
98
  "CMAKE_BUILD_TYPE": "Release",
99
99
  "CMAKE_CXX_COMPILER": "g++.exe",
100
- "CMAKE_CXX_FLAGS": "-Wall -ftemplate-backtrace-limit=0 -Wa,-mbig-obj -fvisibility=hidden -fvisibility-inlines-hidden",
100
+ "CMAKE_CXX_FLAGS": "-Wall -Wno-array-bounds -ftemplate-backtrace-limit=0 -Wa,-mbig-obj -fvisibility=hidden -fvisibility-inlines-hidden",
101
101
  "CMAKE_CXX_FLAGS_RELEASE": "-O3 -DNDEBUG",
102
102
  "CMAKE_SHARED_LINKER_FLAGS_RELEASE": "-Wl,--exclude-all-symbols"
103
103
  },
data/bin/rice-doc.rb CHANGED
@@ -1,3 +1,5 @@
1
+ #! /usr/bin/env ruby
2
+
1
3
  require 'libxml-ruby'
2
4
 
3
5
  # Require rice
@@ -859,6 +859,7 @@ namespace Rice::detail
859
859
  // ========= Anchor.hpp =========
860
860
 
861
861
  #include <ruby.h>
862
+ #include <ruby/vm.h>
862
863
 
863
864
  namespace Rice
864
865
  {
@@ -893,7 +894,6 @@ namespace Rice
893
894
  VALUE get() const;
894
895
 
895
896
  private:
896
- static void disable(VALUE);
897
897
  static void registerExitHandler();
898
898
 
899
899
  inline static bool enabled_ = true;
@@ -1667,23 +1667,28 @@ namespace Rice
1667
1667
  {
1668
1668
  namespace detail
1669
1669
  {
1670
- inline Anchor::Anchor(VALUE value) : value_(value)
1670
+ inline Anchor::Anchor(VALUE value)
1671
1671
  {
1672
+ // rb_gc_register_address() can trigger GC, so we must register the
1673
+ // empty this->value_ slot before storing a heap VALUE in it.
1674
+ // RB_GC_GUARD(value) keeps the ctor argument alive through the end of
1675
+ // this method until the registered slot has been updated.
1672
1676
  if (!RB_SPECIAL_CONST_P(value))
1673
1677
  {
1674
1678
  Anchor::registerExitHandler();
1675
1679
  detail::protect(rb_gc_register_address, &this->value_);
1676
1680
  this->registered_ = true;
1677
1681
  }
1682
+ this->value_ = value;
1683
+ RB_GC_GUARD(value);
1678
1684
  }
1679
1685
 
1680
1686
  inline Anchor::~Anchor()
1681
1687
  {
1682
1688
  if (Anchor::enabled_ && this->registered_)
1683
1689
  {
1684
- detail::protect(rb_gc_unregister_address, &this->value_);
1690
+ rb_gc_unregister_address(&this->value_);
1685
1691
  }
1686
- // Ruby auto detects VALUEs in the stack, so make sure up in case this object is on the stack
1687
1692
  this->registered_ = false;
1688
1693
  this->value_ = Qnil;
1689
1694
  }
@@ -1693,17 +1698,18 @@ namespace Rice
1693
1698
  return this->value_;
1694
1699
  }
1695
1700
 
1696
- // This will be called by ruby at exit - we want to disable further unregistering
1697
- inline void Anchor::disable(VALUE)
1698
- {
1699
- Anchor::enabled_ = false;
1700
- }
1701
-
1702
1701
  inline void Anchor::registerExitHandler()
1703
1702
  {
1704
1703
  if (!Anchor::exitHandlerRegistered_)
1705
1704
  {
1706
- detail::protect(rb_set_end_proc, &Anchor::disable, Qnil);
1705
+ // Use ruby_vm_at_exit which fires AFTER the VM is destroyed,
1706
+ // not rb_set_end_proc which fires BEFORE. rb_set_end_proc
1707
+ // runs as an end_proc in LIFO order alongside at_exit blocks,
1708
+ // so its timing depends on require order — if the extension
1709
+ // loads after minitest/autorun, the disable callback runs
1710
+ // before tests execute, causing Anchor destructors to skip
1711
+ // rb_gc_unregister_address and leave dangling root pointers.
1712
+ ruby_vm_at_exit([](ruby_vm_t*) { Anchor::enabled_ = false; });
1707
1713
  Anchor::exitHandlerRegistered_ = true;
1708
1714
  }
1709
1715
  }
data/lib/mkmf-rice.rb CHANGED
@@ -31,9 +31,9 @@ if IS_MSWIN
31
31
  $CXXFLAGS += " /std:c++#{std} /EHs /permissive- /bigobj /utf-8 /Zc:__cplusplus"
32
32
  $CPPFLAGS += " -D_ALLOW_KEYWORD_MACROS -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE"
33
33
  elsif IS_MINGW
34
- $CXXFLAGS += " -std=c++#{std} -Wa,-mbig-obj"
34
+ $CXXFLAGS += " -std=c++#{std} -Wa,-mbig-obj -Wno-array-bounds"
35
35
  else
36
- $CXXFLAGS += " -std=c++#{std}"
36
+ $CXXFLAGS += " -std=c++#{std} -Wno-array-bounds"
37
37
  end
38
38
 
39
39
  # Rice needs to include its header. Let's setup the include path
data/lib/rice/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Rice
2
- VERSION = "4.11.4"
2
+ VERSION = "4.11.5"
3
3
  end
@@ -2,6 +2,7 @@
2
2
  #define Rice__detail__Anchor__hpp_
3
3
 
4
4
  #include <ruby.h>
5
+ #include <ruby/vm.h>
5
6
 
6
7
  namespace Rice
7
8
  {
@@ -36,7 +37,6 @@ namespace Rice
36
37
  VALUE get() const;
37
38
 
38
39
  private:
39
- static void disable(VALUE);
40
40
  static void registerExitHandler();
41
41
 
42
42
  inline static bool enabled_ = true;
@@ -2,23 +2,28 @@ namespace Rice
2
2
  {
3
3
  namespace detail
4
4
  {
5
- inline Anchor::Anchor(VALUE value) : value_(value)
5
+ inline Anchor::Anchor(VALUE value)
6
6
  {
7
+ // rb_gc_register_address() can trigger GC, so we must register the
8
+ // empty this->value_ slot before storing a heap VALUE in it.
9
+ // RB_GC_GUARD(value) keeps the ctor argument alive through the end of
10
+ // this method until the registered slot has been updated.
7
11
  if (!RB_SPECIAL_CONST_P(value))
8
12
  {
9
13
  Anchor::registerExitHandler();
10
14
  detail::protect(rb_gc_register_address, &this->value_);
11
15
  this->registered_ = true;
12
16
  }
17
+ this->value_ = value;
18
+ RB_GC_GUARD(value);
13
19
  }
14
20
 
15
21
  inline Anchor::~Anchor()
16
22
  {
17
23
  if (Anchor::enabled_ && this->registered_)
18
24
  {
19
- detail::protect(rb_gc_unregister_address, &this->value_);
25
+ rb_gc_unregister_address(&this->value_);
20
26
  }
21
- // Ruby auto detects VALUEs in the stack, so make sure up in case this object is on the stack
22
27
  this->registered_ = false;
23
28
  this->value_ = Qnil;
24
29
  }
@@ -28,17 +33,18 @@ namespace Rice
28
33
  return this->value_;
29
34
  }
30
35
 
31
- // This will be called by ruby at exit - we want to disable further unregistering
32
- inline void Anchor::disable(VALUE)
33
- {
34
- Anchor::enabled_ = false;
35
- }
36
-
37
36
  inline void Anchor::registerExitHandler()
38
37
  {
39
38
  if (!Anchor::exitHandlerRegistered_)
40
39
  {
41
- detail::protect(rb_set_end_proc, &Anchor::disable, Qnil);
40
+ // Use ruby_vm_at_exit which fires AFTER the VM is destroyed,
41
+ // not rb_set_end_proc which fires BEFORE. rb_set_end_proc
42
+ // runs as an end_proc in LIFO order alongside at_exit blocks,
43
+ // so its timing depends on require order — if the extension
44
+ // loads after minitest/autorun, the disable callback runs
45
+ // before tests execute, causing Anchor destructors to skip
46
+ // rb_gc_unregister_address and leave dangling root pointers.
47
+ ruby_vm_at_exit([](ruby_vm_t*) { Anchor::enabled_ = false; });
42
48
  Anchor::exitHandlerRegistered_ = true;
43
49
  }
44
50
  }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rice
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.11.4
4
+ version: 4.11.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Brannan