Unused direct shared library dependencies and rpmlint

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

Inspired by
http://www.redhat.com/archives/fedora-maintainers/2006-June/msg00176.html,
I've had a patch for rpmlint in my local tree for a while which checks for
unused direct shared library dependencies in shared libs.

I'm wondering whether this check is a good idea; I'm not an expert in this
area and the check does produce quite a bit of output on some packages. 
Comments very much welcome.  At the moment I'm leaning towards including
this in the next rpmlint release anyway.

For the adventurous, grab the latest rpmlint from svn (see
http://rpmlint.zarb.org/cgi-bin/trac.cgi/browser/trunk/README.devel) and apply
the attached patch to BinariesCheck.py.

Example output:

$ rpmlint krb5-libs | grep shlib
W: krb5-libs unused-direct-shlib-dependency /usr/lib/libkrb5support.so.0.1 /lib/libresolv.so.2
W: krb5-libs unused-direct-shlib-dependency /usr/lib/libk5crypto.so.3.0 /lib/libresolv.so.2
W: krb5-libs unused-direct-shlib-dependency /usr/lib/libkdb5.so.4.0 /lib/libdl.so.2
W: krb5-libs unused-direct-shlib-dependency /usr/lib/libkdb5.so.4.0 /lib/libresolv.so.2
W: krb5-libs unused-direct-shlib-dependency /usr/lib/libgssrpc.so.4.0 /usr/lib/libkrb5.so.3
W: krb5-libs unused-direct-shlib-dependency /usr/lib/libgssrpc.so.4.0 /usr/lib/libk5crypto.so.3
W: krb5-libs unused-direct-shlib-dependency /usr/lib/libgssrpc.so.4.0 /lib/libcom_err.so.2
W: krb5-libs unused-direct-shlib-dependency /usr/lib/libgssapi_krb5.so.2.2 /lib/libdl.so.2
W: krb5-libs unused-direct-shlib-dependency /usr/lib/libgssapi_krb5.so.2.2 /lib/libresolv.so.2
W: krb5-libs unused-direct-shlib-dependency /usr/lib/libdes425.so.3.0 /lib/libcom_err.so.2

$ rpmlint -I unused-direct-shlib-dependency
unused-direct-shlib-dependency :
The binary contains unused direct shared library dependencies.  This may
indicate gratuitously bloated linkage; check that the binary has been linked
with the intended shared libraries only.
Index: BinariesCheck.py
===================================================================
--- BinariesCheck.py	(revision 1306)
+++ BinariesCheck.py	(working copy)
@@ -30,6 +30,7 @@
     pic_regex=re.compile('^\s+\d+\s+\.rela?\.(data|text)')
     non_pic_regex=re.compile('TEXTREL', re.MULTILINE)
     undef_regex=re.compile('^undefined symbol:\s+(\S+)')
+    unused_regex=re.compile('^\s+(\S+)')
     debug_file_regex=re.compile('\.debug$')
 
     def __init__(self, pkg, path, file, is_ar):
@@ -37,6 +38,7 @@
         self.needed=[]
         self.rpath=[]
         self.undef=[]
+        self.unused=[]
         self.comment=0
         self.dynsyms=0
         self.soname=0
@@ -73,11 +75,12 @@
             self.objdump_error=1
             printWarning(pkg, 'objdump-failed', re.sub('\n.*', '', res[1]))
 
-        # undefined symbol check makes sense only for installed packages
+        # Undefined symbol and unused direct dependency checks make sense only
+        # for installed packages.
         # skip debuginfo: https://bugzilla.redhat.com/190599
         if not is_ar and not is_debug and isinstance(pkg, Pkg.InstalledPkg):
             # We could do this with objdump, but it's _much_ simpler with ldd.
-            res = Pkg.getstatusoutput(('env', 'LC_ALL=C', 'ldd', '-d', '-r', path))
+            res = Pkg.getstatusoutput(('env','LC_ALL=C','ldd','-d','-r',path))
             if not res[0]:
                 for l in string.split(res[1], '\n'):
                     undef=BinaryInfo.undef_regex.search(l)
@@ -85,6 +88,22 @@
                         self.undef.append(undef.group(1))
             else:
                 printWarning(pkg, 'ldd-failed', file)
+            res = Pkg.getstatusoutput(('env','LC_ALL=C','ldd','-r','-u',path))
+            if res[0]:
+                # Either ldd doesn't grok -u (added in glibc 2.3.4) or we have
+                # unused direct dependencies
+                in_unused = 0
+                for l in string.split(res[1], '\n'):
+                    if not l.rstrip():
+                        pass
+                    elif l.startswith('Unused direct dependencies'):
+                        in_unused = 1
+                    elif in_unused:
+                        unused = BinaryInfo.unused_regex.search(l)
+                        if unused:
+                            self.unused.append(unused.group(1))
+                        else:
+                            in_unused = 0
 
 path_regex=re.compile('(.*/)([^/]+)')
 numeric_dir_regex=re.compile('/usr(?:/share)/man/man./(.*)\.[0-9](?:\.gz|\.bz2)')
@@ -248,12 +267,14 @@
                                             printError(pkg, 'library-not-linked-against-libc', i[0])
                                         else:
                                             printError(pkg, 'program-not-linked-against-libc', i[0])
-                            # It could be useful to check this for
-                            # non-shared-libs too, but that has potential to
+                            # It could be useful to check these for others than
+                            # shared libs only, but that has potential to
                             # generate lots of false positives and noise.
-                            if bin_info.undef and so_regex.search(i[0]):
+                            if so_regex.search(i[0]):
                                 for s in bin_info.undef:
                                     printWarning(pkg, 'undefined-non-weak-symbol', i[0], s)
+                                for s in bin_info.unused:
+                                    printWarning(pkg, 'unused-direct-shlib-dependency', i[0], s)
             else:
                 if reference_regex.search(i[0]):
                     lines = pkg.grep(invalid_dir_ref_regex, i[0])
@@ -366,6 +387,12 @@
 '''The binary contains undefined non-weak symbols.  This may indicate improper
 linkage; check that the binary has been linked as expected.''',
 
+# http://www.redhat.com/archives/fedora-maintainers/2006-June/msg00176.html
+'unused-direct-shlib-dependency',
+'''The binary contains unused direct shared library dependencies.  This may
+indicate gratuitously bloated linkage; check that the binary has been linked
+with the intended shared libraries only.''',
+
 'only-non-binary-in-usr-lib',
 '''There are only non binary files in /usr/lib so they should be in /usr/share.''',
 
--
Fedora-packaging mailing list
Fedora-packaging@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/fedora-packaging

[Index of Archives]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite Forum]     [KDE Users]

  Powered by Linux