
Security News
/Research
Fake Corepack Site Distributes Infostealer and Proxyware to Developers
A fake corepack.org site is impersonating the Node.js tool and delivers an infostealer and proxyware to developers who download it.
@sentry-internal/node-native-stacktrace
Advanced tools
A native Node.js module that can capture JavaScript stack traces from main and worker threads, even with blocked event loops.
@sentry-internal/node-native-stacktraceA native Node.js module that can capture JavaScript stack traces for registered main or worker threads from any other thread, even if event loops are blocked.
The module also provides a means to create a watchdog system to track event loop blocking via periodic heartbeats. When the time from the last heartbeat crosses a threshold, JavaScript stack traces can be captured.
For Node.js >= v24, this module can also capture state from AsyncLocalStorage
at the time of stack trace capture, which can help provide context on what the
thread was working on when it became blocked.
This native module is used for Sentry's Event Loop Blocked Detection feature.
In your main thread or worker threads:
import { registerThread } from "@sentry-internal/node-native-stacktrace";
// Register this thread for monitoring
registerThread();
import { captureStackTrace } from "@sentry-internal/node-native-stacktrace";
// Capture stack traces from all registered threads
const stacks = captureStackTrace();
console.log(stacks);
Stack traces show where each thread is currently executing:
{
'0': { // Main thread has ID '0'
frames: [
{
function: 'from',
filename: 'node:buffer',
lineno: 298,
colno: 28
},
{
function: 'pbkdf2Sync',
filename: 'node:internal/crypto/pbkdf2',
lineno: 78,
colno: 17
},
{
function: 'longWork',
filename: '/app/test.js',
lineno: 20,
colno: 29
},
{
function: '?',
filename: '/app/test.js',
lineno: 24,
colno: 1
}
]
},
'2': { // Worker thread
frames: [
{
function: 'from',
filename: 'node:buffer',
lineno: 298,
colno: 28
},
{
function: 'pbkdf2Sync',
filename: 'node:internal/crypto/pbkdf2',
lineno: 78,
colno: 17
},
{
function: 'longWork',
filename: '/app/worker.js',
lineno: 10,
colno: 29
},
{
function: '?',
filename: '/app/worker.js',
lineno: 14,
colno: 1
}
]
}
}
Set up automatic detection of blocked event loops:
AsyncLocalStorage state tracking and heartbeatsSend regular heartbeats:
import {
registerThread,
threadPoll,
} from "@sentry-internal/node-native-stacktrace";
import { AsyncLocalStorage } from "node:async_hooks";
// Create async local storage for state tracking
const asyncLocalStorage = new AsyncLocalStorage();
// Set some state in the async local storage
asyncLocalStorage.enterWith({ someState: "value" });
// Register this thread with async local storage
registerThread({ asyncLocalStorage });
// Send heartbeats every 200ms
setInterval(() => {
threadPoll();
}, 200);
Monitor all registered threads from a dedicated thread:
import {
captureStackTrace,
getThreadsLastSeen,
} from "@sentry-internal/node-native-stacktrace";
const THRESHOLD = 1000; // 1 second
setInterval(() => {
const threadsLastSeen = getThreadsLastSeen();
for (const [threadId, timeSinceLastSeen] of Object.entries(threadsLastSeen)) {
if (timeSinceLastSeen > THRESHOLD) {
// Thread appears to be blocked - capture diagnostics
const stackTraces = captureStackTrace();
const blockedThread = stackTraces[threadId];
console.error(`🚨 Thread ${threadId} blocked for ${timeSinceLastSeen}ms`);
console.error("Stack trace:", blockedThread.frames);
console.error("Async state:", blockedThread.asyncState);
}
}
}, 500); // Check every 500ms
registerThread(threadName?: string): voidregisterThread(asyncStorage: AsyncStorageArgs, threadName?: string): voidRegisters the current thread for stack trace capture. Must be called from each thread you want to capture stack traces from.
threadName (optional): Name for the thread. Defaults to the current thread
ID.asyncStorage (optional): AsyncStorageArgs to fetch state from
AsyncLocalStorage on stack trace capture.type AsyncStorageArgs = {
/** AsyncLocalStorage instance to fetch state from */
asyncLocalStorage: AsyncLocalStorage<unknown>;
/**
* Optional array of keys to pick a specific property from the store.
* Key will be traversed in order through Objects/Maps to reach the desired property.
*
* This is useful if you want to capture Open Telemetry context values as state.
*
* To get this value:
* context.getValue(MY_UNIQUE_SYMBOL_REF)
*
* You would set:
* stateLookup: ['_currentContext', MY_UNIQUE_SYMBOL_REF]
*/
stateLookup?: Array<string | symbol>;
};
captureStackTrace<State>(): Record<string, Thread<A, P>>Captures stack traces from all registered threads. Can be called from any thread but will not capture a stack trace for the calling thread itself.
type Thread<A = unknown, P = unknown> = {
frames: StackFrame[];
/** State captured from the AsyncLocalStorage */
asyncState?: A;
/** Optional state provided when calling threadPoll */
pollState?: P;
};
type StackFrame = {
function: string;
filename: string;
lineno: number;
colno: number;
};
threadPoll<State>(disableLastSeen?: boolean, pollState?: object): voidSends a heartbeat from the current thread.
disableLastSeen (optional): If true, disables the tracking of the last
seen time for this thread.pollState (optional): An object containing state to include with the next
stack trace capture. This can be used instead of or in addition to
AsyncLocalStorage based state tracking.getThreadsLastSeen(): Record<string, number>Returns the time in milliseconds since each registered thread called
threadPoll().
FAQs
A native Node.js module that can capture JavaScript stack traces from main and worker threads, even with blocked event loops.
The npm package @sentry-internal/node-native-stacktrace receives a total of 86,167 weekly downloads. As such, @sentry-internal/node-native-stacktrace popularity was classified as popular.
We found that @sentry-internal/node-native-stacktrace demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
/Research
A fake corepack.org site is impersonating the Node.js tool and delivers an infostealer and proxyware to developers who download it.

Research
/Security News
A large-scale campaign abused GitHub Actions in compromised repositories to exploit CVE-2026-41940 in cPanel and WHM and steal server credentials.

Security News
Five frontier LLMs generated the same nonexistent package names, leaving 53 available for potential slopsquatting across PyPI and npm.