fix: reset errno before strtol in v8 builtin_hash PGO parser (#51063)

The builtin_hash branch in v8's profile-data-reader.cc checks errno
after strtol but never resets it to 0 first. On 32-bit linux-arm
release builds, a stale errno=EINVAL from earlier in mksnapshot init
survives across the ~68k block_count/builtin_count profile lines that
v8 14.4's reader skips, causing CHECK(errno == 0 && ...) to crash
mksnapshot with SIGTRAP during run_mksnapshot_default.

Regressed in #50575 when builtins PGO was enabled; first failed in
v40.8.6. The latent bug also exists on v8 main (only masked by
BUILTIN_BLOCK_POSITION resetting errno in an adjacent handler) and
should be upstreamed.
This commit is contained in:
Samuel Attard
2026-04-15 02:17:11 -04:00
committed by GitHub
parent 0686cceb7a
commit 0564aa64db
2 changed files with 33 additions and 0 deletions

View File

@@ -7,3 +7,4 @@ inspector_use_std_shared_ptr_for_inspectedcontext.patch
merged_maglev_avoid_eliding_smi_checks_too_aggressively.patch
merged_compiler_arm64_force_explicit_zero-extension_of_load_index.patch
merged_maglev_account_for_phi_smi_type_widening_in.patch
fix_reset_errno_before_strtol_in_builtin_hash_profile_parser.patch

View File

@@ -0,0 +1,32 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Sam Attard <sattard@anthropic.com>
Date: Wed, 15 Apr 2026 05:12:38 +0000
Subject: fix: reset errno before strtol in builtin_hash profile parser
The builtin_hash branch in EnsureInitProfileData() checks errno after
strtol but never resets it to 0 first, so a stale errno from any prior
operation causes CHECK(errno == 0 && ...) to crash mksnapshot with
SIGTRAP. Observed on 32-bit linux-arm release builds where v8 init
leaves errno=EINVAL before profile parsing. The block_hint branch
already resets errno; this brings builtin_hash to parity.
diff --git a/src/builtins/profile-data-reader.cc b/src/builtins/profile-data-reader.cc
index 22c5c6c0f4539c16d4ecdc3ab40be5a723a8d61d..cdc31cb8d15f630cd0ecd5fef6946d75588c8199 100644
--- a/src/builtins/profile-data-reader.cc
+++ b/src/builtins/profile-data-reader.cc
@@ -93,6 +93,7 @@ EnsureInitProfileData() {
std::getline(line_stream, token, '\t');
CHECK(line_stream.eof());
char* end = nullptr;
+ errno = 0;
int hash = static_cast<int>(strtol(token.c_str(), &end, 0));
CHECK(errno == 0 && end != token.c_str());
ProfileDataFromFileInternal& block_count = (*data.get())[builtin_name];
@@ -142,6 +143,7 @@ EnsureInitProfileData() {
std::getline(line_stream, token, ',');
CHECK(line_stream.eof());
char* end = nullptr;
+ errno = 0;
int hash = static_cast<int>(strtol(token.c_str(), &end, 0));
CHECK(errno == 0 && end != token.c_str());
ProfileDataFromFileInternal& hints_and_hash = (*data.get())[builtin_name];