Skip to content

Add prebuilt-binary for armv7l#51

Open
ignatiusreza wants to merge 1 commit into
WonderInventions:developfrom
ignatiusreza:chore/prebuild-arm
Open

Add prebuilt-binary for armv7l#51
ignatiusreza wants to merge 1 commit into
WonderInventions:developfrom
ignatiusreza:chore/prebuild-arm

Conversation

@ignatiusreza

@ignatiusreza ignatiusreza commented Jul 7, 2026

Copy link
Copy Markdown

Description

Thank you for reviving this project. We noticed that the prebuilt binary for armv7l (32 bit), which used to be available is now missing. It would be great if this can be added back, as we would like to still use it for our Raspberry PI 3b+ deployment. The PI in question are still running with Raspberry PI OS Bookworm 32 bit. Upgrade to 64 bit OS is planned, but are very tricky and problematic to do cleanly across fleet.

We would be happy to be assigned as the maintainer and tester of the armv7l build.

This was made with assistance from Claude, build confirmed to be completed successfully and validated in a smoke test via QEMU. We've also tested this running correctly in a Raspberry PI 3b+ Running Bookworm 32 bit.

Test

I also tried to run test/all.js with the prebuilt binary through QEmu, and all test were successful, except the 3 in custom-settings.js.. according to Claude, this is because SimplePeer provided the following default iceServers, and a stun server with ?transport is invalid.. and it claim the same test would fail also with the other M114 build..

iceServers: [
  { urls: 'stun:stun.l.google.com:19302' },
  { urls: 'stun:global.stun.twilio.com:3478?transport=udp' }
]

NOTE: I also noticed that there's already a PR (#49) for fixing the build/test in M114. I'll rebase this branch once the other PR is merged. locally test/all.js passed with the arm prebuilt binary post-rebase.

Additional smoke test

cd /home/ignatiusreza/Work/repo/node-webrtc
export QEMU=/nix/store/ljrgkqh0myarydz1arxzaqy32wlf08mf-qemu-11.0.1/bin/qemu-arm
export ARMSYSROOT=/nix/store/1kc9bq82z4m6i250gs9ap324yrxnxb86-glibc-armv7l-unknown-linux-gnueabihf-2.40-66
export GCCLIB=/nix/store/phbybsb7jijyr0pllwhqmhmmlnan15ci-armv7l-unknown-linux-gnueabihf-gcc-14.3.0-lib/armv7l-unknown-linux-gnueabihf/lib
NODE_BIN=/tmp/armtest/node-v20.18.0-linux-armv7l/bin/node
timeout 60 "$QEMU" -L "$ARMSYSROOT" -E LD_LIBRARY_PATH="$GCCLIB" "$NODE_BIN" --expose-gc arm-smoke-test.js 2>&1

dc1 open, sending message
pc2 received: hello from pc1
ALL GOOD - full connection established

// arm-smoke-test.js
const wrtc = require("./lib/index.js");

const pc1 = new wrtc.RTCPeerConnection();
const pc2 = new wrtc.RTCPeerConnection();

pc1.onicecandidate = (e) => {
  if (e.candidate) pc2.addIceCandidate(e.candidate);
};
pc2.onicecandidate = (e) => {
  if (e.candidate) pc1.addIceCandidate(e.candidate);
};

const dc1 = pc1.createDataChannel("test");
dc1.onopen = () => {
  console.log("dc1 open, sending message");
  dc1.send("hello from pc1");
};

pc2.ondatachannel = (e) => {
  const dc2 = e.channel;
  dc2.onmessage = (msg) => {
    console.log("pc2 received:", msg.data);
    console.log("ALL GOOD - full connection established");
    process.exit(0);
  };
};

setTimeout(() => {
  console.log("TIMEOUT - connection did not establish");
  process.exit(1);
}, 20000);

pc1.createOffer()
  .then((offer) => pc1.setLocalDescription(offer))
  .then(() => pc2.setRemoteDescription(pc1.localDescription))
  .then(() => pc2.createAnswer())
  .then((answer) => pc2.setLocalDescription(answer))
  .then(() => pc1.setRemoteDescription(pc2.localDescription))
  .catch((e) => {
    console.log("FAILED", e);
    process.exit(1);
  });

@ignatiusreza

ignatiusreza commented Jul 8, 2026

Copy link
Copy Markdown
Author

This is now rebased on top of the v0.10.0, which provide a clean baseline for people who want to run their own arm built, while waiting for an official release..

You can pull from this branch, run nix develop followed by TARGET_ARCH=arm npm run build..

Interesting to note.. test/all.js via QEMU passed successfully without any issue.. clean build.. clean test..

When built on top of #49 with M114, test/all.js via QEMU crashed on several places.. summary by Claude:

Still broken, unchanged root cause (crashes):**

  • mediastream, destructor: still abort with the identical pthread_mutex_lock.c:94: assertion failed: mutex->__data.__owner == 0
  • rtcrtpreceiver, rtcrtpsender: still abort, but now with a different glibc assertion — tpp.c:83 (__pthread_tpp_change_priority): assertion failed: new_prio == -1 || (...). That's a different internal glibc consistency check (priority-inheritance/priority-ceiling bookkeeping) than the mutex-ownership one, which is actually informative: a genuine deterministic bug in our own compiled code would fail the same way every time, not trip two distinct glibc internal assertions across different tests. This is stronger evidence the crashes are QEMU's atomic/futex/priority emulation getting confused under real thread contention, not a bug the M114 network-thread refactor could have addressed.

Still broken, changed symptom:

  • rollback: previously crashed immediately on "local rollback"; now gets further (2 more assertions pass) before hanging on "remote rollback" instead of crashing. Different failure shape, still not fixed.

Still hanging, unchanged:

  • get-settings, rtcaudiosink, rtcvideosink, rtcvideosource — all still hang identically inside getUserMedia()'s synthetic-device path.

Bottom line: the network-thread separation work fixed the things it targeted (link order, close race, STUN URLs) but didn't touch the remaining crash/hang cluster, and the crash signature diversifying between runs/tests (mutex-ownership vs. priority-ceiling assertions) makes the "QEMU emulation artifact" explanation more credible than a fixable code bug.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant