【问题标题】:Tool for discovering library dependencies based on missing symbols基于缺失符号发现库依赖关系的工具
【发布时间】:2012-04-20 19:40:01
【问题描述】:

我正在从事一个有 20 年历史的项目,其中有一些......有趣的问题,其中包括:有一些具有循环依赖关系的共享对象。

我正在尝试绘制所有库之间的关系,但如果有一个现有的工具能够搜索库列表以查看哪些可以满足缺失的依赖关系,那将会很有帮助。

作为参考,他们通过以下方式解决了这个问题:

# True list of dependencies:
A: B
B: A
C: A

# Dependencies used in practice:
A:
B: A
C: A B

【问题讨论】:

  • 如果一开始你没有成功……写一个 perl 脚本。我很抱歉,但脚本在一个气隙网络上,所以我无法复制它。如果有人知道现有工具,我会留下问题。

标签: linker shared-libraries symbols


【解决方案1】:

我没有测试过下面的代码,因为我只是试图从内存中重写它,但是我之前写的用来​​解决这个问题的代码(它看起来大致像这个)工作正常:

#!/usr/bin/env perl

using IPC::Open3;

my $queryFile = $ARGV[0];
shift;

my %missingSymbols = getSymbols( "nm -Aau", $queryFile );

my %symtbl;

foreach $lib ( @ARGV ) {
  my %temp = getSymbols( "nm -Aa --defined-only", $lib );

  foreach $key ( keys( %temp ) ) {
    $symtbl{$key} =   (defined($symtbl{$key}) ? "${symtbl{$key}} " : "")
                    . $temp{$key};
  }
}

my %dependencies;
foreach $symbol ( keys( %missingSymbols  ) ) {
  if( defined( $symtbl{$symbol} ) ) {
    foreach $lib ( split( / +/, $symtbl{$symbol} ) ) {
      if( !defined( $dependencies{$lib} ) ) {
        $dependencies{$lib} = 1;
      }
    }
  }
}

if( scalar( keys( %dependencies ) ) > 0 ) {
  print( "$queryFile depends on one or more of the following libs:\n\n" );

  print join( "\n", sort( keys( %dependencies ) ) ) . "\n\n";
} else {
  print( "Unable to resolve dependencies for $queryFile.\n\n" );
}

# Done.

sub getSymbols {
  my $cmd   = shift;
  my $fname = shift;

  checkFileType( $fname );

  open3( IN, OUT, ERR, "$cmd $fname" );

  my %symhash;
  close( IN );
  # If you leave ERR open and nm prints to STDERR, reads from
  # OUT can block.  You could make reads from both handles be
  # non-blocking so you could examine STDERR if needed, but I
  # don't need to.
  close( ERR );

  while( <OUT> ) {
    chomp;
    if( m/^(?:[^:]*:)+[a-zA-Z0-9]*\s*[a-zA-Z] ([^\s]+)$/ ) {
      my $temp = defined( $symhash{$1} ) ? "${symhash{$1}} " : "";
      $symhash{$1} = $temp . $fname;
    }
  }
  close( OUT );

  return %symhash;
}

sub checkFileType {
  my $fname = shift;

  die "$fname does not exist\n" if( ! -e $fname );
  die "Not an ELF or archive file\n" if( `file $fname` !~ m/ELF| ar archive/ );
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-04
    • 2023-03-15
    • 2011-06-06
    • 2016-11-29
    • 1970-01-01
    • 2021-08-28
    • 1970-01-01
    相关资源
    最近更新 更多