Skip to content

Commit 688c96b

Browse files
committed
scratch: minimal cppgc MakeGarbageCollected addon repro (arm64 macOS)
1 parent e7c4d5c commit 688c96b

5 files changed

Lines changed: 90 additions & 0 deletions

File tree

.github/workflows/cppgc-repro.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
name: cppgc-repro
2+
3+
on:
4+
push:
5+
branches: [scratch/cppgc-arm64-repro]
6+
7+
jobs:
8+
repro:
9+
strategy:
10+
fail-fast: false
11+
matrix:
12+
os: [ubuntu-latest, macos-latest, windows-latest]
13+
runs-on: ${{ matrix.os }}
14+
defaults:
15+
run:
16+
working-directory: cppgc-repro
17+
steps:
18+
- uses: actions/checkout@v4
19+
- uses: actions/setup-node@v4
20+
with:
21+
node-version: 22
22+
- name: build
23+
run: npx node-gyp configure build
24+
- name: run
25+
run: node test.js
26+
- name: lldb backtrace (macOS)
27+
if: always() && runner.os == 'macOS'
28+
run: |
29+
lldb --batch -o run -k "thread backtrace" -k "quit" -- "$(command -v node)" test.js || true

cppgc-repro/binding.cc

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Minimal reproduction: cppgc::MakeGarbageCollected crashes inside an addon on
2+
// arm64 macOS. Build with node-gyp; call `make()` from JS.
3+
#include <cstdio>
4+
#include <node.h>
5+
#include <v8.h>
6+
7+
#include "cppgc/allocation.h"
8+
#include "cppgc/garbage-collected.h"
9+
#include "cppgc/visitor.h"
10+
#include "v8-cppgc.h"
11+
12+
class Wrappable final : public cppgc::GarbageCollected<Wrappable> {
13+
public:
14+
void Trace(cppgc::Visitor*) const {}
15+
};
16+
17+
static void Make(const v8::FunctionCallbackInfo<v8::Value>& info) {
18+
v8::Isolate* isolate = info.GetIsolate();
19+
20+
v8::CppHeap* heap = isolate->GetCppHeap();
21+
fprintf(stderr, "[repro] isolate->GetCppHeap() = %p\n", (void*)heap);
22+
fflush(stderr);
23+
if (heap == nullptr) {
24+
fprintf(stderr, "[repro] CppHeap is null\n");
25+
fflush(stderr);
26+
return;
27+
}
28+
29+
cppgc::AllocationHandle& handle = heap->GetAllocationHandle();
30+
fprintf(stderr, "[repro] &GetAllocationHandle() = %p\n", (void*)&handle);
31+
fflush(stderr);
32+
33+
// Crashes here (EXC_BAD_ACCESS) on arm64 macOS; works on x64 Linux/Windows.
34+
Wrappable* w = cppgc::MakeGarbageCollected<Wrappable>(handle);
35+
fprintf(stderr, "[repro] MakeGarbageCollected = %p\n", (void*)w);
36+
fflush(stderr);
37+
}
38+
39+
static void Init(v8::Local<v8::Object> exports) {
40+
NODE_SET_METHOD(exports, "make", Make);
41+
}
42+
43+
NODE_MODULE(NODE_GYP_MODULE_NAME, Init)

cppgc-repro/binding.gyp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"targets": [
3+
{
4+
"target_name": "cppgc_repro",
5+
"sources": [ "binding.cc" ]
6+
}
7+
]
8+
}

cppgc-repro/package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"name": "cppgc-repro",
3+
"version": "1.0.0",
4+
"private": true,
5+
"gypfile": true
6+
}

cppgc-repro/test.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
const addon = require('./build/Release/cppgc_repro.node')
2+
console.log('node', process.versions.node, 'arch', process.arch, 'platform', process.platform)
3+
addon.make()
4+
console.log('OK: no crash')

0 commit comments

Comments
 (0)