-
Notifications
You must be signed in to change notification settings - Fork 0
Fix Ruby 3.3+ ARM64 segfault during shutdown #19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
phillip-haydon
wants to merge
24
commits into
main
Choose a base branch
from
ph/ruby-3.3-arm64-compatibility-01-01-2026
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
24 commits
Select commit
Hold shift + click to select a range
292fdd5
Fix Ruby 3.3+ ARM64 segfault during shutdown
phillip-haydon 99e6a2a
Remove Ruby 5.x version constraints
phillip-haydon e3a0b38
Update build tooling for Ruby 3.0+ and rake-compiler-dock 1.11.1
phillip-haydon a3707f9
Fix flaky tests for Ruby 3.x compatibility
phillip-haydon 144334d
Fix additional test failures for Ruby 3.x
phillip-haydon a4fee99
Fix Bundler version compatibility for TeamCity
phillip-haydon 6960e91
Fix build script for Ruby 2.7 host compatibility
phillip-haydon c690193
Build script: Install Ruby 3.1 and dependencies if missing
phillip-haydon 717af1a
Fix build script: proper Ruby version check without bc dependency
phillip-haydon fc595dc
Fix build script: avoid eval/source, use direct git clone for rbenv
phillip-haydon cd38a27
Install build dependencies before building Ruby
phillip-haydon 81c366b
Bump required Ruby to 3.2 (multi_xml requires >= 3.1.2)
phillip-haydon 748dd9d
Install debase-ruby_core_source globally in Docker containers
phillip-haydon b350090
Use cross native:PLATFORM to avoid host Ruby 4.0.0 compilation
phillip-haydon 92f7153
Build native only, manually package gem to avoid host Ruby compilation
phillip-haydon 0ed5fef
Run unit tests with Ruby 3.2 after build
phillip-haydon f08fd20
Fix GCC compatibility: old-style function def and clang-only flags
phillip-haydon 8409a3f
Fix C99 old-style function definitions and Ruby warnings
phillip-haydon 127f854
Fix Invalid attribute name error to show symbol name instead of pointer
phillip-haydon 2eec172
Fix GCC 12+ compilation: C99 function definitions, rax.c use-after-fr…
phillip-haydon e86fa65
Bump version to 1.1.15.pre3
phillip-haydon 27f3223
Update darwin build config for Ruby 3.x, add comprehensive README
phillip-haydon a2f706b
Add rake gem:all task to build all 7 platform gems in one command
phillip-haydon 2353c5e
Update Gemfile.lock for Ruby 3.3.7
phillip-haydon File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,98 +1,121 @@ | ||
| PATH | ||
| remote: . | ||
| specs: | ||
| raygun-apm (1.1.15.pre1) | ||
| raygun-apm (1.1.15.pre3) | ||
| debase-ruby_core_source (>= 3.3.6) | ||
|
|
||
| GEM | ||
| remote: https://rubygems.org/ | ||
| specs: | ||
| activemodel (6.1.3.2) | ||
| activesupport (= 6.1.3.2) | ||
| activesupport (6.1.3.2) | ||
| activemodel (6.1.7.10) | ||
| activesupport (= 6.1.7.10) | ||
| activesupport (6.1.7.10) | ||
| concurrent-ruby (~> 1.0, >= 1.0.2) | ||
| i18n (>= 1.6, < 2) | ||
| minitest (>= 5.1) | ||
| tzinfo (~> 2.0) | ||
| zeitwerk (~> 2.3) | ||
| benchmark_driver (0.15.17) | ||
| bson (4.12.1) | ||
| concurrent-ruby (1.1.8) | ||
| debase-ruby_core_source (0.10.14) | ||
| domain_name (0.5.20190701) | ||
| unf (>= 0.0.5, < 1.0.0) | ||
| base64 (0.3.0) | ||
| benchmark_driver (0.15.18) | ||
| bigdecimal (3.3.1) | ||
| bson (5.2.0) | ||
| cgi (0.5.1) | ||
| concurrent-ruby (1.3.6) | ||
| csv (3.3.5) | ||
| date (3.5.1) | ||
| debase-ruby_core_source (3.4.1) | ||
| domain_name (0.6.20240107) | ||
| erb (4.0.4) | ||
| cgi (>= 0.3.3) | ||
| excon (0.73.0) | ||
| faraday (1.0.1) | ||
| multipart-post (>= 1.2, < 3) | ||
| ffi (1.15.5-x64-mingw32) | ||
| http-accept (1.7.0) | ||
| http-cookie (1.0.3) | ||
| http-cookie (1.1.0) | ||
| domain_name (~> 0.5) | ||
| httparty (0.18.1) | ||
| mime-types (~> 3.0) | ||
| multi_xml (>= 0.5.2) | ||
| httpclient (2.8.3) | ||
| i18n (1.8.10) | ||
| i18n (1.14.8) | ||
| concurrent-ruby (~> 1.0) | ||
| io-console (0.5.9) | ||
| irb (1.3.5) | ||
| reline (>= 0.1.5) | ||
| mime-types (3.3.1) | ||
| mime-types-data (~> 3.2015) | ||
| mime-types-data (3.2021.0225) | ||
| minitest (5.14.4) | ||
| mongo (2.14.0) | ||
| bson (>= 4.8.2, < 5.0.0) | ||
| mongoid (7.1.8) | ||
| io-console (0.8.2) | ||
| irb (1.16.0) | ||
| pp (>= 0.6.0) | ||
| rdoc (>= 4.0.0) | ||
| reline (>= 0.4.2) | ||
| logger (1.7.0) | ||
| mime-types (3.7.0) | ||
| logger | ||
| mime-types-data (~> 3.2025, >= 3.2025.0507) | ||
| mime-types-data (3.2025.0924) | ||
| minitest (5.27.0) | ||
| mongo (2.22.0) | ||
| base64 | ||
| bson (>= 4.14.1, < 6.0.0) | ||
| mongoid (7.1.11) | ||
| activemodel (>= 5.1, < 6.2) | ||
| mongo (>= 2.7.0, < 3.0.0) | ||
| multi_xml (0.6.0) | ||
| ruby2_keywords (~> 0.0.5) | ||
| multi_xml (0.7.1) | ||
| bigdecimal (~> 3.1) | ||
| multipart-post (2.1.1) | ||
| mutex_m (0.3.0) | ||
| netrc (0.11.0) | ||
| rake (13.0.3) | ||
| rake-compiler (1.1.1) | ||
| ostruct (0.6.3) | ||
| pp (0.6.3) | ||
| prettyprint | ||
| prettyprint (0.2.0) | ||
| psych (5.3.1) | ||
| date | ||
| stringio | ||
| rake (13.0.6) | ||
| rake-compiler (1.1.9) | ||
| rake | ||
| rake-compiler-dock (1.2.1) | ||
| reline (0.2.5) | ||
| rake-compiler-dock (1.11.1) | ||
| rdoc (7.0.3) | ||
| erb | ||
| psych (>= 4.0.0) | ||
| tsort | ||
| reline (0.6.3) | ||
| io-console (~> 0.5) | ||
| rest-client (2.1.0) | ||
| http-accept (>= 1.7.0, < 2.0) | ||
| http-cookie (>= 1.0.2, < 2.0) | ||
| mime-types (>= 1.16, < 4.0) | ||
| netrc (~> 0.8) | ||
| rest-client (2.1.0-x64-mingw32) | ||
| ffi (~> 1.9) | ||
| http-accept (>= 1.7.0, < 2.0) | ||
| http-cookie (>= 1.0.2, < 2.0) | ||
| mime-types (>= 1.16, < 4.0) | ||
| netrc (~> 0.8) | ||
| tzinfo (2.0.4) | ||
| ruby2_keywords (0.0.5) | ||
| stringio (3.2.0) | ||
| tsort (0.2.0) | ||
| tzinfo (2.0.6) | ||
| concurrent-ruby (~> 1.0) | ||
| unf (0.1.4) | ||
| unf_ext | ||
| unf_ext (0.0.7.7) | ||
| zeitwerk (2.4.2) | ||
| zeitwerk (2.6.18) | ||
|
|
||
| PLATFORMS | ||
| arm64-darwin-25 | ||
| ruby | ||
| x64-mingw32 | ||
| x64-mingw-ucrt | ||
|
|
||
| DEPENDENCIES | ||
| benchmark_driver (~> 0.15.9) | ||
| bundler (~> 2.2.15) | ||
| debase-ruby_core_source (~> 0.10.14) | ||
| bundler (>= 2.2.15) | ||
| csv | ||
| debase-ruby_core_source (>= 3.3.6) | ||
| excon (~> 0.73.0) | ||
| faraday (~> 1.0.1) | ||
| httparty (~> 0.18.0) | ||
| httpclient (~> 2.8.3) | ||
| irb | ||
| minitest (~> 5.14.4) | ||
| minitest (~> 5.16) | ||
| mongoid (~> 7.1.2) | ||
| multipart-post (~> 2.1.1) | ||
| mutex_m | ||
| ostruct | ||
| rake (~> 13.0.3) | ||
| rake-compiler (~> 1.1.1) | ||
| rake-compiler-dock (~> 1.2.1) | ||
| rake-compiler-dock (~> 1.11.0) | ||
| raygun-apm! | ||
| rest-client (~> 2.1.0) | ||
|
|
||
| BUNDLED WITH | ||
| 2.2.33 | ||
| 4.0.3 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1,188 @@ | ||
| # raygun-apm-ruby | ||
| # raygun-apm | ||
|
|
||
| Ruby Profiler for Raygun Application Performance Monitoring. | ||
|
|
||
| This gem contains a C native extension that interfaces with the Ruby VM internals for method-level profiling. It communicates with the Raygun APM Agent over TCP/UDP to send trace data. | ||
|
|
||
| ## Platform Gems | ||
|
|
||
| Each release produces **7 precompiled native gems** plus the source gem: | ||
|
|
||
| | # | Platform | OS | Architecture | Ruby Versions | Build Method | | ||
| |---|----------|----|-------------|---------------|--------------| | ||
| | 1 | `x86-mingw32` | Windows | 32-bit | 3.0 | rake-compiler-dock (Docker) | | ||
| | 2 | `x64-mingw32` | Windows | 64-bit | 3.0 | rake-compiler-dock (Docker) | | ||
| | 3 | `x64-mingw-ucrt` | Windows | 64-bit (UCRT) | 3.1, 3.2 | rake-compiler-dock (Docker) | | ||
| | 4 | `x86-linux` | Linux | 32-bit | 3.0, 3.1, 3.2 | rake-compiler-dock (Docker) | | ||
| | 5 | `x86_64-linux` | Linux | 64-bit | 3.0, 3.1, 3.2 | rake-compiler-dock (Docker) | | ||
| | 6 | `x86_64-darwin` | macOS | Intel | 3.0, 3.1, 3.2 | Native on macOS | | ||
| | 7 | `arm64-darwin` | macOS | Apple Silicon | 3.0, 3.1, 3.2 | Native on macOS | | ||
|
|
||
| **Note:** Windows Ruby 3.0 uses the `mingw32` platform. Ruby 3.1+ on Windows switched to UCRT (`x64-mingw-ucrt`). That's why there are separate Windows gems. | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| ### For development (compile + test on your machine) | ||
|
|
||
| - Ruby 3.0, 3.1, or 3.2 | ||
| - C compiler (GCC 12+ on Linux, Clang/Xcode on macOS) | ||
| - `debase-ruby_core_source` >= 3.3.6 (provides Ruby VM header files) | ||
| - System packages (Linux): `build-essential`, `libssl-dev`, `zlib1g-dev`, `libyaml-dev` | ||
|
|
||
| ### For cross-compilation (building all platform gems) | ||
|
|
||
| - Docker (for rake-compiler-dock containers — builds Linux and Windows gems) | ||
| - macOS machine (for building the two darwin gems natively) | ||
| - Multiple Ruby versions installed via ruby-install, rbenv, or similar (for darwin cross-compile) | ||
|
|
||
| ## Development Setup | ||
|
|
||
| ```bash | ||
| git clone git@github.com:MindscapeHQ/raygun-apm-ruby.git | ||
| cd raygun-apm-ruby | ||
| bundle install | ||
| bundle exec rake compile # Compile native extension for your current Ruby | ||
| bundle exec rake test # Run the test suite | ||
| ``` | ||
|
|
||
| ## Building Platform Gems | ||
|
|
||
| ### Build all 7 platform gems (single command, requires Docker + macOS) | ||
|
|
||
| ```bash | ||
| bundle exec rake gem:all | ||
| ``` | ||
|
|
||
| This runs `gem:native` (Docker) then `gem:native:darwin` (native) and produces all gems in `pkg/`. | ||
|
|
||
| ### Step 1: Build Linux and Windows gems (Docker) | ||
|
|
||
| This uses `rake-compiler-dock` to cross-compile inside Docker containers. No Windows or Linux VM needed. | ||
|
|
||
| ```bash | ||
| bundle exec rake gem:native | ||
| ``` | ||
|
|
||
| This builds all non-darwin platforms: | ||
| - `x86-mingw32` (Windows 32-bit, Ruby 3.0) | ||
| - `x64-mingw32` (Windows 64-bit, Ruby 3.0) | ||
| - `x64-mingw-ucrt` (Windows 64-bit UCRT, Ruby 3.1+) | ||
| - `x86-linux` (Linux 32-bit) | ||
| - `x86_64-linux` (Linux 64-bit) | ||
|
|
||
| Output goes to `pkg/`. | ||
|
|
||
| To build only Linux 64-bit: | ||
| ```bash | ||
| bundle exec rake gem:linux | ||
| ``` | ||
|
|
||
| ### Step 2: Build macOS gems (native, on a Mac) | ||
|
|
||
| Darwin gems **cannot** be cross-compiled in Docker — they must be built on an actual macOS machine. | ||
|
|
||
| **Prerequisite:** Install the target Ruby versions (e.g., via ruby-install): | ||
| ```bash | ||
| ruby-install ruby 3.0.7 | ||
| ruby-install ruby 3.1.7 | ||
| ruby-install ruby 3.2.9 | ||
| ``` | ||
|
|
||
| Then build: | ||
| ```bash | ||
| ./build-native-macos.sh | ||
| # or manually: | ||
| bundle exec rake gem:native:darwin | ||
| ``` | ||
|
|
||
| This produces: | ||
| - `x86_64-darwin` (Intel Mac) | ||
| - `arm64-darwin` (Apple Silicon) | ||
|
|
||
| Output goes to `pkg/`. | ||
|
|
||
| ### Step 3: Verify | ||
|
|
||
| After both steps, `pkg/` should contain all 7 platform `.gem` files plus the source gem: | ||
| ``` | ||
| pkg/ | ||
| raygun-apm-1.1.15.pre3.gem # source gem (compiles on install) | ||
| raygun-apm-1.1.15.pre3-x86-mingw32.gem | ||
| raygun-apm-1.1.15.pre3-x64-mingw32.gem | ||
| raygun-apm-1.1.15.pre3-x64-mingw-ucrt.gem | ||
| raygun-apm-1.1.15.pre3-x86-linux.gem | ||
| raygun-apm-1.1.15.pre3-x86_64-linux.gem | ||
| raygun-apm-1.1.15.pre3-x86_64-darwin.gem | ||
| raygun-apm-1.1.15.pre3-arm64-darwin.gem | ||
| ``` | ||
|
|
||
| ## Running Tests | ||
|
|
||
| ```bash | ||
| bundle exec rake test # Full test suite (requires compiled extension) | ||
| bundle exec rake compile # Just compile (no tests) | ||
| ``` | ||
|
|
||
| Tests require the native extension to be compiled first (`rake test` does this automatically via the `test => compile` dependency). | ||
|
|
||
| **Note:** Some tests (e.g., `apm_test.rb`) attempt to connect to a Raygun APM Agent. Tests that require an agent will raise `FatalError` and are expected to handle this gracefully. | ||
|
|
||
| ## Release Process | ||
|
|
||
| 1. Update version in `lib/raygun/apm/version.rb` | ||
| 2. Build all platform gems (Steps 1 + 2 above) | ||
| 3. Push each gem to RubyGems: | ||
| ```bash | ||
| for gem in pkg/*.gem; do gem push "$gem"; done | ||
| ``` | ||
| 4. Tag the release: | ||
| ```bash | ||
| git tag v1.1.15.pre3 | ||
| git push origin v1.1.15.pre3 | ||
| ``` | ||
|
|
||
| ## Project Structure | ||
|
|
||
| ``` | ||
| raygun-apm-ruby/ | ||
| ├── ext/raygun/ # C native extension source | ||
| │ ├── extconf.rb # Build configuration (mkmf) | ||
| │ ├── raygun_ext.c # Ruby C API entry point | ||
| │ ├── raygun_tracer.c/h # Core tracer (tracepoints, shadow stack) | ||
| │ ├── raygun_encoder.c/h # Binary event encoding | ||
| │ ├── raygun_event.c/h # Event types (HTTP, SQL, method calls) | ||
| │ ├── raygun_platform.c/h # Platform-specific code | ||
| │ ├── raygun_ringbuf.c/h # Lock-free ring buffer | ||
| │ ├── raygun_coercion.c/h # Ruby value coercion | ||
| │ ├── raygun_errors.c/h # Error handling | ||
| │ └── rax.c/h # Third-party radix tree (for blacklist) | ||
| ├── lib/raygun/apm/ | ||
| │ ├── tracer.rb # Ruby-side tracer (config, hooks, sinks) | ||
| │ ├── config.rb # Environment-based configuration | ||
| │ ├── diagnostics.rb # Agent connectivity checks + noop mode | ||
| │ ├── event.rb # Event type definitions | ||
| │ ├── version.rb # VERSION + MINIMUM_AGENT_VERSION | ||
| │ ├── blacklist.rb # Method blacklist filtering | ||
| │ └── hooks/ # Monkey-patches for HTTP clients, Redis, etc. | ||
| ├── test/raygun/ # Minitest unit tests | ||
| ├── Rakefile # Build tasks (compile, test, gem:native, etc.) | ||
| ├── build-native-macos.sh # macOS build shortcut | ||
| ├── build-native-win-linux.sh # Linux/Windows build (used in Vagrant/CI) | ||
| └── Vagrantfile # Ubuntu VM for Linux builds (alternative to Docker) | ||
| ``` | ||
|
|
||
| ## Key Concepts | ||
|
|
||
| ### Noop Mode | ||
|
|
||
| When the Raygun APM Agent is running but its version is below `MINIMUM_AGENT_VERSION` (defined in `version.rb`), the tracer enters **noop mode** via `tracer.noop!`. In this mode, all profiling is disabled to avoid overhead. The `raygun-apm-rails` middleware detects this via `tracer.noop?`. | ||
|
|
||
| ### Native Extension | ||
|
|
||
| The C extension hooks into Ruby's TracePoint API and internal VM structures (via `debase-ruby_core_source` headers) to capture method calls, returns, and thread events with minimal overhead. Events are batched and sent to the Raygun Agent over UDP or TCP. | ||
|
|
||
| ### Compiler Compatibility | ||
|
|
||
| - **GCC 12+**: Required `-Wno-use-after-free` for a false positive in third-party `rax.c`. Old-style C function definitions `()` updated to `(void)` for C99 compliance. | ||
| - **Clang**: Suppresses Clang-specific warnings (`-Wno-shorten-64-to-32`, etc.) that don't apply to GCC. | ||
| - `-Werror` is only enabled when `WERROR=1` or `CI=1` environment variable is set. |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.