From bb20b3c720e59d5ef6b2a86c8e98a8d6e828b07a Mon Sep 17 00:00:00 2001 From: Carlo Cabrera <30379873+carlocab@users.noreply.github.com> Date: Mon, 16 Sep 2024 12:44:11 +0800 Subject: [PATCH] os/linux/ld: harden `brewed_ld_so_diagnostics` against `TypeError` I think this is a bug in Ruby, but I've no idea how to track it down. I can reproduce it intermittently in a codespace when `brew install`ing a large number of formulae. To work around this: - cache the return value of `brewed_ld_so_diagnostics` so that we can limit the number of calls to `IO.popen` - retry once when we see a `TypeError` Closes #17828. --- Library/Homebrew/os/linux/ld.rb | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/Library/Homebrew/os/linux/ld.rb b/Library/Homebrew/os/linux/ld.rb index 3dc85cb23e..f9c782bf50 100644 --- a/Library/Homebrew/os/linux/ld.rb +++ b/Library/Homebrew/os/linux/ld.rb @@ -7,13 +7,28 @@ module OS module Ld sig { returns(String) } def self.brewed_ld_so_diagnostics + @brewed_ld_so_diagnostics ||= T.let({}, T.nilable(T::Hash[Pathname, T.nilable(String)])) + brewed_ld_so = HOMEBREW_PREFIX/"lib/ld.so" return "" unless brewed_ld_so.exist? - ld_so_output = Utils.popen_read(brewed_ld_so, "--list-diagnostics") - return "" unless $CHILD_STATUS.success? + brewed_ld_so_target = brewed_ld_so.readlink + @brewed_ld_so_diagnostics[brewed_ld_so_target] ||= begin + ld_so_output = Utils.popen_read(brewed_ld_so, "--list-diagnostics") + ld_so_output if $CHILD_STATUS.success? + end - ld_so_output + @brewed_ld_so_diagnostics[brewed_ld_so_target].to_s + rescue TypeError + # Workaround for intermittent `Error: no implicit conversion of false into String` + unless @retried_brewed_ld_so_diagnostics&.fetch(brewed_ld_so_target, false) + @retried_brewed_ld_so_diagnostics ||= T.let({}, T.nilable(T::Hash[Pathname, T::Boolean])) + @retried_brewed_ld_so_diagnostics[brewed_ld_so_target] = true + sleep 0.5 + retry + end + + raise end sig { returns(String) }