diff options
| author | Elliot Saba | 2013-10-31 01:20:28 -0700 |
|---|---|---|
| committer | Mike McQuaid | 2013-10-31 17:12:36 -0700 |
| commit | c20f6395bbadef014f78e774e1526fecf2c12bfc (patch) | |
| tree | a718c702be6a2a8efdebfc4d7723cb3f8f32fbb4 | |
| parent | d311fe666c12eecad972f9d79d558147371feb3e (diff) | |
| download | brew-c20f6395bbadef014f78e774e1526fecf2c12bfc.tar.bz2 | |
bottle: improve relocatable debugging.
* When Homebrew developer mode is enabled, if a bottle is not found to
be relocatable attempt to explain why
* Print out paths of each file that still contains the string search for
* If the string searched for was found in an executable, check to see
if `otool` can explain the string's appearance
* If otool can't explain, see if `strings` can explain
Closes Homebrew/homebrew#23824.
Signed-off-by: Mike McQuaid <mike@mikemcquaid.com>
| -rw-r--r-- | Library/Homebrew/cmd/bottle.rb | 43 |
1 files changed, 42 insertions, 1 deletions
diff --git a/Library/Homebrew/cmd/bottle.rb b/Library/Homebrew/cmd/bottle.rb index 0fe7fb836..04f2fb3ef 100644 --- a/Library/Homebrew/cmd/bottle.rb +++ b/Library/Homebrew/cmd/bottle.rb @@ -5,6 +5,8 @@ require 'keg' require 'cmd/versions' require 'utils/inreplace' require 'erb' +require 'open3' +require 'extend/pathname' class BottleMerger < Formula # This provides a URL and Version which are the only needed properties of @@ -42,7 +44,46 @@ module Homebrew extend self end def keg_contains string, keg - quiet_system 'fgrep', '--recursive', '--quiet', '--max-count=1', string, keg + if not ARGV.homebrew_developer? + return quiet_system 'fgrep', '--recursive', '--quiet', '--max-count=1', string, keg + end + + # Find all files that still reference the keg via a string search + keg_ref_files = `/usr/bin/fgrep --files-with-matches --recursive "#{string}" "#{keg}" 2>/dev/null` + keg_ref_files = (keg_ref_files.map{ |file| Pathname.new(file.strip) }).reject(&:symlink?) + + # If there are no files with that string found, return immediately + return false if keg_ref_files.empty? + + # Start printing out each file and any extra information we can find + opoo "String '#{string}' still exists in these files:" + keg_ref_files.each do |file| + puts "#{Tty.red}#{file}#{Tty.reset}" + + # If we can't use otool on this file, just skip to the next file + next if not file.mach_o_executable? and not file.mach_o_bundle? and not file.dylib? and not file.extname == '.a' + + # Get all libraries this file links to, then display only links to libraries that contain string in the path + linked_libraries = `otool -L "#{file}"`.split("\n").drop(1) + linked_libraries.map!{ |lib| lib.strip.split()[0] } + linked_libraries = linked_libraries.select{ |lib| lib.include? string } + + linked_libraries.each do |lib| + puts " #{Tty.gray}-->#{Tty.reset} links to #{lib}" + end + + # Use strings to search through the file for each string + strings = `strings -t x - "#{file}"`.select{ |str| str.include? string }.map{ |s| s.strip } + + # Don't bother reporting a string if it was found by otool + strings.reject!{ |str| linked_libraries.include? str.split[1] } + strings.each do |str| + offset, match = str.split + puts " #{Tty.gray}-->#{Tty.reset} match '#{match}' at offset #{Tty.em}0x#{offset}#{Tty.reset}" + end + end + puts + true end def bottle_output bottle |
