[pacman-dev] [BUG] segfault when the download fails

Xavier shiningxc at gmail.com
Thu Dec 6 19:41:56 EST 2007

On Thu, Dec 06, 2007 at 06:14:05PM -0600, Dan McGee wrote:
> I caught a segfault the other day during a big upgrade when one of the
> xfce4 packages was missing on my first mirror. It segfaulted after
> downloading everything else, it appeared.
> This is an interesting bug and we might just get to the bottom of this
> now that we at least have our conditions narrowed down.

Actually, it's very easy to reproduce. Just pick two packages not yet
downloaded (just remove from cache if necessary). Then run pacman -S on them
a first time to see in which order they will be installed. Then for the first
one, edit the sync db, and make a typo in the filename, so that it can't be
found on the mirror. Then install the 2 packages.

Here is the top of the backtrace, just before the segfault:
#0  alpm_list_find_str (haystack=0x88f5bf0,
    needle=0x894a020 "hunspell-1.2.1-2-i686.pkg.tar.gz")
    at alpm_list.c:628
No locals.
#1  0xb7edb71b in _alpm_downloadfiles_forreal (servers=0x807f318,
    localpath=0x8059dc0 "/var/cache/pacman/pkg/", files=0x88f53b8,
    mtime1=0, mtime2=0x0, dl_total=0xbf8966f4, totalsize=15813133)
    at server.c:207
        fileurl = (struct url *) 0x88f53e8
        realfile = "/var/cache/pacman/pkg/hunspell-1.2.1-2-i686.pkg.tar.gz<snip junk>
        fn = 0x894a020 "hunspell-1.2.1-2-i686.pkg.tar.gz"
        pkgname = "hunspell-1.2.1-2-i686.pkg.tar.gz", '\0' <repeats 223 times>
        output = "/var/cache/pacman/pkg/hunspell-1.2.1-2-i686.pkg.tar.gz.part<snip junk>
    server = (pmserver_t *) 0x807f360
    dl_thisfile = 0
    lp = (alpm_list_t *) 0x88f53b8
    complete = (alpm_list_t *) 0x88f5bf0
    i = (alpm_list_t *) 0x807ccf0
    __func__ = "_alpm_downloadfiles_forreal"
#2  0xb7edc2f8 in _alpm_downloadfiles (servers=0x807f318,
    localpath=0x8059dc0 "/var/cache/pacman/pkg/", files=0x88f53b8,
    dl_total=0xbf8966f4, totalsize=15813133) at server.c:147
No locals.
#3  0xb7edd053 in _alpm_sync_commit (trans=0x8059b50,
    db_local=0x8082e48, data=0xbf8989e0) at sync.c:1055
        spkg = (pmpkg_t *) 0x85463d0
        current = (pmdb_t *) 0x807d020
        i = (alpm_list_t *) 0x8079dd0
        j = (alpm_list_t *) 0x0
        files = (alpm_list_t *) 0x88f53b8
        patches = (alpm_list_t *) 0x0
        deltas = (alpm_list_t *) 0x0
        tr = <value optimized out>
        replaces = <value optimized out>
        retval = <value optimized out>
        cachedir = 0x8059dc0 "/var/cache/pacman/pkg/"
        dltotal = 15813133
        dl = 190656
        __func__ = "_alpm_sync_commit"

At this point, hunspell has been downloaded, and added to the complete list.
It tried to download openoffice but failed.
Then it's trying a second mirror, and wants to check if hunspell has already
been downloaded, so check if it finds it in the complete list.
That's line 207 of server.c.
At this point, the complete list is completly (ahah) broken. It looks like it
has been erased by a buffer overflow or something.
I put a breakpoint in alpm_list_find_str, and here is it :
 x/s haystack
0x88f5bf0:       "2-i686.pkg.tar.gz"
 x/s (char *)haystack-40
0x88f5bc8:       "/archlinux/extra/os/i686/hunspell-1.2.1-2-i686.pkg.tar.gz"

Instead of containing an actual list structure, complete contains the end of
this string :P When it tries to read complete->data or complete->next, it

More information about the pacman-dev mailing list