home bbs files messages ]

Just a sample of the Echomail archive

<< oldest | < older | list | newer > | newest >> ]

 Message 32968 
 Jonathan Gould to GitLab note in main/sbbs 
 sbbs binary: Debian Linux AARCH64 sigfau 
 01 Jan 26 21:25:45 
 
TZUTC: -0800
MSGID: 59109.sync_sys@1:103/705 2dbd73be
PID: Synchronet 3.21a-Linux master/48922a15c Dec 17 2025 GCC 12.2.0
TID: SBBSecho 3.34-Linux master/8bb133aa7 Dec 30 2025 GCC 12.2.0
BBSID: VERT
CHRS: ASCII 1
FORMAT: flowed
https://gitlab.synchro.net/main/sbbs/-/issues/685#note_8067

@Deuce here's an update from my further debugging...

# Synchronet ARM64 Crash Report - SpiderMonkey js_GetClassPrototype Segfault

## Summary
Synchronet BBS crashes with a segmentation fault on ARM64 (aarch64) when
JavaScript initializes during the events thread startup. The crash occurs in
`js_GetClassPrototype()` within SpiderMonkey.

## ROOT CAUSE IDENTIFIED: 47-bit Pointer Limitation in SpiderMonkey NaN-boxing

**The crash is caused by SpiderMonkey 1.8.5's NaN-boxing scheme only
supporting 47-bit pointers, but ARM64 Linux allocates memory at addresses
requiring 48+ bits.**

### Evidence from GDB:

```
(gdb) print /x 0xffffd2c04100 >> 47
$2 = 0x1
```

The address `0xffffd2c04100` has bit 47 set. When SpiderMonkey masks it to 47
bits:
- Original: `0xffffd2c04100`
- After 47-bit mask: `0x7fffd2c04100` (WRONG - high bit lost!)

Register dump showing the problem:
```
x0             0x7fffd2c04100      (invalid - masked to 47 bits)
x1             0xfffbffffd2c04100  (NaN-boxed value containing original
pointer)
```

## SOLUTION FOUND

**Run sbbs with `setarch --addr-compat-layout` to force memory allocations
into the lower 47-bit address space:**

```bash
setarch $(uname -m) --addr-compat-layout /sbbs/exec/sbbs
```

This works because `--addr-compat-layout` tells the kernel to use the legacy
memory layout which keeps allocations in the lower address range where
SpiderMonkey's 47-bit pointers work correctly.

### For Docker deployment, update the entrypoint:

```bash
#!/bin/bash
exec setarch $(uname -m) --addr-compat-layout /sbbs/exec/sbbs "$@"
```

## Environment

**System:**
- OS: Kali GNU/Linux Rolling 2025.2
- Kernel: 6.12.33+kali-arm64 #1 SMP
- Architecture: aarch64 (ARM64)
- Hardware: Parallels VM on Apple Silicon Mac
- Page Size: 4096 bytes

**Synchronet:**
- Version: 3.21b Debug
- Build: master/4089fb4 Jan 02 2026 02:23 with GCC 12.2.0
- Built from: Native ARM64 build (not QEMU emulated)

## Why Developer's RPi 500 Works

The Raspberry Pi 500 likely works because:
1. Raspberry Pi OS may use a memory layout that keeps allocations below the
47-bit boundary
2. Different kernel configuration for virtual address space
3. Possibly running 32-bit userspace (armhf) instead of 64-bit (aarch64)

## Technical Details

SpiderMonkey 1.8.5 uses NaN-boxing to store JavaScript values. In this scheme,
64-bit values are encoded as NaN floats, with pointers stored in the lower 47
bits of the mantissa. This works on x86_64 because Linux traditionally kept
user-space addresses below 0x7fffffffffff (47 bits).

However, ARM64 Linux can use a larger virtual address space, allocating memory
at addresses like `0xffffd2c04100` which requires 48 bits. When SpiderMonkey
extracts the pointer using a 47-bit mask, it corrupts the address.

## Debug Backtrace

```
Thread 12 "sbbs/events" received signal SIGSEGV, Segmentation fault.
0x0000fffff6d06060 in JSObject::getClass (this=0x7fffd2c04100) at jsobj.h:427

#0  JSObject::getClass (this=0x7fffd2c04100)  <- INVALID pointer (should be
0xffffd2c04100)
#1  JSObject::isFunction (this=0x7fffd2c04100)
#2  js::IsFunctionObject (v=...)
#3  js::FindClassPrototype (...)
    v = {data = {debugView = {payload47 = 140736796311808, tag =
JSVAL_TAG_OBJECT}}}
...
#14 js_InitFunctionClass (...)
#15 js_InitFunctionAndObjectClasses (...)
#16 JS_InitStandardClasses (...)
#17 js_CreateGlobalObject (...)
#18 js_CreateCommonObjects (...)
#19 sbbs_t::js_init (...)
#20 event_thread (...)
```

## Alternative Solutions

1. **Use `setarch --addr-compat-layout`** (RECOMMENDED - works now)
2. **Update to newer SpiderMonkey** - Newer versions handle 48+ bit pointers
correctly
3. **Patch SpiderMonkey** - Modify the NaN-boxing code to use proper 48-bit
pointer handling for ARM64
4. **Use 32-bit build** - armhf build would avoid the issue entirely

## Previous Theories (Ruled Out)

- **Pointer Authentication Code (PAC)**: Tested with `arm64.nopauth` kernel
parameter - crash still occurred
- **Docker networking**: Crash occurs both inside and outside Docker
- **Library path issues**: RPATH verified correct, all libraries loading
properly


Dockerfile used for debug build:
```
FROM debian:bookworm-slim

ENV DEBIAN_FRONTEND=noninteractive
ENV SBBSCTRL=/sbbs/ctrl
ENV SBBSEXEC=/sbbs/exec
ENV TERM=xterm

RUN apt-get update && apt-get install -y \
    build-essential \
    git \
    libncurses-dev \
    libnspr4-dev \
    libcap-dev \
    libarchive-dev \
    pkg-config \
    zip \
    unzip \
    perl \
    python3 \
    && rm -rf /var/lib/apt/lists/*

# Clone Synchronet
RUN git clone --depth 1 https://gitlab.synchro.net/main/sbbs.git /sbbs

# Build main Synchronet (DEBUG build for better backtraces)
WORKDIR /sbbs/src/sbbs3
ENV SBBSDIR=/sbbs
RUN make SBBSDIR=/sbbs 2>&1 && \
    echo "=== Main build completed (DEBUG) ===" && \
    echo "=== Finding build directories ===" && \
    ls -la /sbbs/src/sbbs3/ | grep gcc

# Copy executables from the MAIN build directory (not subdirectories)
# Debug builds may use different suffix - find the actual directory
RUN ARCH=$(uname -m | sed 's/x86_64/x64/' | sed 's/aarch64/aarch64/') && \
    echo "Architecture: $ARCH" && \
    echo "Looking for exe directories:" && \
    find /sbbs/src/sbbs3 -maxdepth 1 -type d -name "gcc.linux.${ARCH}.*" && \
    MAIN_EXE_DIR=$(find /sbbs/src/sbbs3 -maxdepth 1 -type d -name
"gcc.linux.${ARCH}.exe.*" | head -1) && \
    MAIN_LIB_DIR=$(find /sbbs/src/sbbs3 -maxdepth 1 -type d -name
"gcc.linux.${ARCH}.lib.*" | head -1) && \
    echo "Main exe dir: $MAIN_EXE_DIR" && \
    echo "Main lib dir: $MAIN_LIB_DIR" && \
    if [ -d "$MAIN_EXE_DIR" ]; then \
        echo "Copying from main exe dir:" && \
        ls -la "$MAIN_EXE_DIR" && \
        cp -v "$MAIN_EXE_DIR"/* /sbbs/exec/; \
    fi && \
    if [ -d "$MAIN_LIB_DIR" ]; then \
        echo "Copying from main lib dir:" && \
        ls -la "$MAIN_LIB_DIR" && \
        cp -v "$MAIN_LIB_DIR"/*.so /sbbs/exec/; \
    fi

# Copy executables from subdirectory builds (scfg, uedit, umonitor, etc.)
RUN ARCH=$(uname -m | sed 's/x86_64/x64/' | sed 's/aarch64/aarch64/') && \
    for subdir in scfg uedit umonitor; do \
        EXE_DIR=$(find /sbbs/src/sbbs3/${subdir} -maxdepth 1 -type d -name
"gcc.linux.${ARCH}.exe.*" 2>/dev/null | head -1); \
        if [ -d "$EXE_DIR" ]; then \
            echo "Copying from $EXE_DIR:" && \
            cp -v "$EXE_DIR"/* /sbbs/exec/ 2>/dev/null || true; \
        fi; \
    done

# Verify key files exist
RUN echo "=== Contents of /sbbs/exec ===" && \
    ls -la /sbbs/exec/sbbs /sbbs/exec/scfg /sbbs/exec/baja && \
    echo "=== Checking rpath ===" && \
    objdump -x /sbbs/exec/sbbs | grep -E 'R.*PATH' || echo "No RPATH found" &&
\
    echo "=== Checking ldd ===" && \
    ldd /sbbs/exec/sbbs

# Build doors/external programs (DEBUG)
WORKDIR /sbbs/src/doors
RUN for dir in */; do \
        if [ -f "$dir/Makefile" ] || [ -f "$dir/GNUmakefile" ]; then \
            echo "Building door: $dir"; \
            make -C "$dir" 2>&1 || true; \
        fi; \
    done && \
    echo "=== Doors build completed ==="

# Copy built door executables
RUN find /sbbs/src/doors -type f -executable -newer /sbbs/src/doors -exec file
{} \; 2>/dev/null | \
    grep "ELF" | cut -d: -f1 | while read f; do \
        name=$(basename "$f"); \
        dest_dir="/sbbs/xtrn/$name"; \
        mkdir -p "$dest_dir" 2>/dev/null || true; \
        cp "$f" "$dest_dir/" 2>/dev/null || cp "$f" /sbbs/xtrn/ 2>/dev/null ||
true; \
    done

# Copy default config files
RUN cp -r /sbbs/ctrl.new/* /sbbs/ctrl/ 2>/dev/null || true
RUN cp -r /sbbs/text.new/* /sbbs/text/ 2>/dev/null || true

# Create required directories
RUN mkdir -p /sbbs/data /sbbs/ctrl /sbbs/text \
    /sbbs/node1 /sbbs/node2 /sbbs/node3 /sbbs/node4 \
    /sbbs/xtrn /sbbs/mods

# Add entrypoint
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh

EXPOSE 513 23 22 80 443 21

WORKDIR /sbbs
ENTRYPOINT ["/entrypoint.sh"]
CMD ["/sbbs/exec/sbbs"]
```
--- SBBSecho 3.34-Linux
 * Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)
SEEN-BY: 103/13 705 105/81 106/201 124/5016 128/187 129/14 153/757
SEEN-BY: 153/7715 154/10 30 110 203/0 218/700 221/0 226/30 227/114
SEEN-BY: 229/110 112 134 206 275 317 400 426 428 470 700 705 240/1120
SEEN-BY: 240/5832 263/1 266/512 280/464 5003 5006 291/111 292/8125
SEEN-BY: 301/1 320/219 322/757 341/66 234 342/200 396/45 423/120 460/58
SEEN-BY: 460/256 1124 633/280 712/848 770/1 902/26 5020/400 8912 5054/30
SEEN-BY: 5075/35
PATH: 103/705 280/464 460/58 229/426


<< oldest | < older | list | newer > | newest >> ]

(c) 1994,  bbs@darkrealms.ca