Files
robobun 2dd997c4b5 fix(node): support duplicate dlopen calls with DLHandleMap (#24404)
## Summary

Fixes an issue where loading the same native module
(NODE_MODULE_CONTEXT_AWARE) multiple times would fail with:
```
symbol 'napi_register_module_v1' not found in native module
```

Fixes https://github.com/oven-sh/bun/issues/23136
Fixes https://github.com/oven-sh/bun/issues/21432

## Root Cause

When a native module is loaded for the first time:
1. `dlopen()` loads the shared library
2. Static constructors run and call `node_module_register()`
3. The module registers successfully

On subsequent loads of the same module:
1. `dlopen()` returns the same handle (library already loaded)
2. Static constructors **do not run again**
3. No registration occurs, leading to the "symbol not found" error

## Solution

Implemented a thread-safe `DLHandleMap` to cache and replay module
registrations:

1. **Thread-local storage** captures the `node_module*` during static
constructor execution
2. **After successful first load**, save the registration to the global
map
3. **On subsequent loads**, look up the cached registration and replay
it

This approach matches Node.js's `global_handle_map` implementation.

## Changes

- Created `src/bun.js/bindings/DLHandleMap.h` - thread-safe singleton
cache
- Added thread-local storage in `src/bun.js/bindings/v8/node.cpp`
- Modified `src/bun.js/bindings/BunProcess.cpp` to save/lookup cached
modules
- Also includes the exports fix (using `toObject()` to match Node.js
behavior)

## Test Plan

Added `test/js/node/process/dlopen-duplicate-load.test.ts` with tests
that:
- Build a native addon using node-gyp
- Load it twice with `process.dlopen`
- Verify both loads succeed
- Test with different exports objects

All tests pass.

## Related Issue

Fixes the second bug discovered in the segfault investigation.

---------

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
2025-12-15 18:35:26 -08:00
..
2024-11-11 19:23:58 -08:00