From 2604d4febe4269f2118eee6bc072f30865663202 Mon Sep 17 00:00:00 2001 From: tebako-ci Date: Wed, 19 Aug 2026 09:13:33 +0800 Subject: [PATCH] ci/spec22-gems: bisect the sassc closure through ffi on LoadError (incident 13 round 6) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Run 32188296332 attempt 2 (round-5 fix live, traces on) proves the closure walk COMPLETE: libsass.so's 15 imports parse (whole-image PE), both vendored siblings (libgcc_s_seh-1.dll, libwinpthread-1.dll) materialize beside the importer, every other import is KERNEL32 / ADVAPI32 / api-ms-win-crt-* host surface — and the ffi load still fails the OS bind with error 126. The walk, the placement, the ffi flags (0x8 ALTERED on every route), and the shim's errno discipline all check out; the failing link is only measurable on the windows loader itself. On the sassc require's LoadError, bisect the closure from inside through the same ffi path: two host-surface controls by bare name (ADVAPI32.dll; an api-ms-win-crt contract — both proven by the runtime's own boot), then each vendored sibling individually, then libsass.so again. The verdict matrix discriminates every remaining hypothesis: control failure = the host surface is broken in the scrubbed env; sibling failure = the extracted file is bad on disk (truncation, lock, quarantine); siblings ok + libsass retry ok = a transient race on the first load, not the closure; siblings ok + libsass retry 126 = an import the walk cannot see (delay-load excluded by design — would not 126 the base load — so this outcome reopens the parser). Never gates: the original LoadError re-raises after the verdicts. POSIX legs never fire it (green there). --- ci/spec22-gems/fixtures/probe.rb | 39 ++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/ci/spec22-gems/fixtures/probe.rb b/ci/spec22-gems/fixtures/probe.rb index bb2e437..b88bdb0 100644 --- a/ci/spec22-gems/fixtures/probe.rb +++ b/ci/spec22-gems/fixtures/probe.rb @@ -176,6 +176,41 @@ def sassc_partial(styles) ).render end +# Incident 13 round 6 diagnostics: ffi's load of the vendored +# libsass.so fails the OS bind (error 126) with the closure walk +# provably complete — both vendored siblings parse and materialize +# beside the importer, and the api-ms-* host surface is proven by the +# runtime's own boot. The failing link is only measurable on the +# windows loader itself, so on LoadError bisect the closure from +# inside through the same ffi path: two host-surface controls by bare +# name (a stock OS module; an api-ms-win-crt contract), then each +# vendored sibling individually, then the top module again. The +# per-module verdicts name the missing piece; a retry success names a +# host-side transient (a lock race), not the closure. Never gates: the +# original LoadError re-raises after the verdicts. +def require_sassc_with_bisect + require "sassc" +rescue LoadError => e + bisect = { "ADVAPI32.dll" => "ADVAPI32.dll", + "api-ms-win-crt-runtime-l1-1-0.dll" => "api-ms-win-crt-runtime-l1-1-0.dll" } + spec = Gem.loaded_specs["sassc"] + if spec.nil? + puts "PROBE-DIAG dep-load skipped (the sassc spec never activated)" + else + native_dir = File.join(spec.gem_dir, "lib", "sassc") + %w[libwinpthread-1.dll libgcc_s_seh-1.dll libsass.so].each do |mod| + bisect[mod] = File.join(native_dir, mod) + end + end + bisect.each do |label, spell| + FFI::DynamicLibrary.load_library(spell, FFI::DynamicLibrary::RTLD_LAZY) + puts "PROBE-DIAG dep-load #{label} ok" + rescue LoadError => le + puts "PROBE-DIAG dep-load #{label} fail #{le.message.lines.first.to_s.strip}" + end + raise e +end + case ARGV[0] when "sinatra-fixed", "sinatra-unfixed" fixed = ARGV[0] == "sinatra-fixed" @@ -200,7 +235,7 @@ def sassc_partial(styles) exit 1 end when "sassc" - require "sassc" + require_sassc_with_bisect puts "PROBE sassc-version #{SassC::VERSION}" css = SassC::Engine.new(File.read(File.join(PROBE_DIR, "styles/plain.scss"))).render if css.include?(".spec22-gems") && css.include?("color: #1d2d3c") @@ -226,7 +261,7 @@ def sassc_partial(styles) exit 1 end when "sassc-unmaterialized" - require "sassc" + require_sassc_with_bisect puts "PROBE sassc-version #{SassC::VERSION}" begin # The SAME import against the image pressed WITHOUT materialize: —