perf_hooks.performance.timerify() with histogram: RangeError [ERR_OUT_OF_RANGE] on arm64
まだ誰も着手していません。
- 主要言語
- JavaScript
- スター
- 122k
- フォーク
- 37.3k
- 平均マージ
- 4日 2時間
- マージ済み PR(30日)
- 283
説明
Version
v14, v16, v17, v18
Platform
macOS v12.4 (21F79).
Darwin 21.5.0 Darwin Kernel Version 21.5.0: Tue Apr 26 21:08:37 PDT 2022; root:xnu-8020.121.3~4/RELEASE_ARM64_T6000 arm64
Subsystem
perf_hooks
What steps will reproduce the bug?
Run this snippet:
import {createHistogram, performance} from 'node:perf_hooks';
const fn = () => {};
const timerified = performance.timerify(fn, {histogram: createHistogram()});
for (let i = 0; i < 100_000; i++) {
try {
timerified();
} catch (error) {
console.error('Crashed on iteration', i);
throw error;
}
}
How often does it reproduce? Is there a required condition?
100% consistent reproduction, requires arm64, maybe requires macOS.
What is the expected behavior?
Calling the timerified function returned from perf_hooks.performance.timerify() should successfully record to the histogram.
What do you see instead?
node:internal/errors:466
ErrorCaptureStackTrace(err);
^
RangeError [ERR_OUT_OF_RANGE]: The value of "val" is out of range. It must be a safe integer greater than 0. Received 0
at new NodeError (node:internal/errors:377:5)
at RecordableHistogram.record (node:internal/histogram:290:13)
at processComplete (node:internal/perf/timerify:40:15)
at timerified fn (node:internal/perf/timerify:88:5)
at file:///Users/jonah/programming/benchmark/index.mjs:9:3
at ModuleJob.run (node:internal/modules/esm/module_job:198:25)
at async Promise.all (index 0)
at async ESMLoader.import (node:internal/modules/esm/loader:409:24)
at async loadESM (node:internal/process/esm_loader:85:5)
at async handleMainPromise (node:internal/modules/run_main:61:12) {
code: 'ERR_OUT_OF_RANGE'
}
Node.js v18.1.0
Additional information
Originally reported here: https://github.com/sindresorhus/yoctocolors/pull/9#issuecomment-1019033882
The bug appears to be from the implementation of perf_hooks.performance.timerify() with a histogram, when calling the returned timerified function. The error comes from the input validation of RecordableHistogram#record(), attempting to record a value x < 1 will throw. For whatever reason timerify() seems to be recording an execution duration of 0 and trying to record that. See the error stacktrace for more info.
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
調査の方向性
まず arm64 で snippet を再現し、次に stack trace に示されているとおり、internal/perf/timerify と internal/histogram、特に processComplete と RecordableHistogram.record を調査します。timerify() が ERR_OUT_OF_RANGE をスローせずに実行を記録し、その動作が適切なリグレッションテストでカバーされれば完了です。
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- javascript, nodejs
- 領域
- backend, performance
- issue の種類
- バグ
- 難易度
- 3/5
- 見積もり時間
- 1〜2日
- 活発さ
- 静か
- 明瞭さ
- おおむね明確
- 初心者へのやさしさ
- 48/100