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

Bug#231470: apt: Apt helper needed to debug package dependency breakage



Package: apt
Version: 0.6.18
Severity: wishlist
Tags: patch

I have frequently been in a situation where a program I use suddenly
breaks after an apt-get upgrade, but I'm not sure why.  Was it a new
version of the package?  Perhaps I don't recall what version I was
using before the breakage, or when I might have upgraded.  Was it some
package that the program I'm using depends on?  Maybe, but I'm not
really sure of EVERYTHING the package in question (recursively)
depends on or when I upgraded.

So I wrote a short python script to help with this problem.  The
script prints out a list of the named package and all its dependencies
sorted by the time they were installed on the system (as determined
from /var/lib/dpkg/info/*.list mtime).  This gives me information to
help correlate my apt-get runs with observed package breakage to try
to find the culprit.

For example, if aptitude stops working properly,

serrano> ~/what-broke aptitude
Package <libapt-pkg-libc6.3-5-3.3> has no install time info
libdb1-compat                                          Fri Aug  8 03:02:11 2003
libsigc++-1.2-5c102                                    Fri Aug  8 05:15:58 2003
aptitude                                               Sun Jan 11 17:38:06 2004
libncurses5                                            Sun Jan 18 08:11:05 2004
libc6                                                  Thu Jan 22 07:55:10 2004
libgcc1                                                Tue Jan 27 07:37:22 2004
gcc-3.3-base                                           Tue Jan 27 07:37:31 2004
libstdc++5                                             Tue Jan 27 07:37:32 2004

So depending on exactly when I started seeing the misbehavior, there
may be a reason to point the finger at a more-recently updated library
like libstdc++ or libncurses, which are more-recently installed than
aptitude itself.

I have put this script in the public domain and I am including it with
this bug report in case it might by useful in a future version of apt.
I guess it would have to be recoded in C/C++ to be part of apt so I
don't expect that it will be used as-is, but I thought it might be
nice as a concrete example of what I'm talking about.

Script pasted below.  Enjoy!

#! /usr/bin/python
#  what-broke: help find offending packages when something breaks
#  Placed in the public domain by Bill Gribble <grib@billgribble.com>

import sys
import os
import popen2
import time 
from string import *
from stat import *

def pkgdeps(pkg):
    outstr, instr = popen2.popen4("apt-cache depends %s" % pkg)
    deps = [] 
    myline = outstr.readline()
    while(myline != ''):
        elts = map(strip, myline.split(':'))
        if len(elts) == 2:
            how, pkg = elts
            if how == 'Depends':
                deps.append(pkg)
        myline = outstr.readline()
    return deps

def alldeps(pkg, ignore):
    deps = {}
    imm_deps = pkgdeps(pkg)
    for i in imm_deps:
        if ignore.get(i) is None:
            deps[i] = 1
            ignore[i] = 1
            childeps = alldeps(i, ignore)
            for c in childeps:
                deps[c] = 1
                ignore[i] = 1

    dlist = deps.keys()
    return dlist
    
def pkginstalltime(pkg):
    listfile = '/var/lib/dpkg/info/' + pkg + '.list'
    try:
        return os.stat(listfile)[ST_MTIME]
    except:
        print "Package", pkg, "has no install time info"
        return None
    
def what_broke(pname):
    def sortfun(a, b):
        return cmp(a[1], b[1])
    
    pkgs = [ pname ]
    pkgs.extend(alldeps(sys.argv[1], {}))

    itimes = [] 
    for p in pkgs:
        itimes.append([p, pkginstalltime(p)])
    itimes.sort(sortfun)
    for i in itimes:
        p, t = i
        if t is not None:
            print ljust(p, 54), time.asctime(time.localtime(float(t)))

if (len(sys.argv) != 2 or sys.argv[1][0] == '-'):
    print "Usage: what-broke <pkg-name>"
    sys.exit(-1)
else:
    what_broke(sys.argv[1])
    sys.exit(0)



-- Package-specific info:

-- (/etc/apt/preferences present, but not submitted) --


-- (/etc/apt/sources.list present, but not submitted) --


-- System Information:
Debian Release: testing/unstable
  APT prefers experimental
  APT policy: (900, 'experimental'), (500, 'unstable')
Architecture: i386 (i686)
Kernel: Linux 2.6.1
Locale: LANG=C, LC_CTYPE=C

Versions of packages apt depends on:
ii  libc6                      2.3.2.ds1-11  GNU C Library: Shared libraries an
ii  libgcc1                    1:3.3.3-0pre3 GCC support library
ii  libstdc++5                 1:3.3.3-0pre3 The GNU Standard C++ Library v3

-- no debconf information




Reply to: