Subject: bug#6551: [PATCH] hash: extend module to deal with non-pointer keys

From: Jim Meyering <[email-masked]>
Date: Fri, 02 Jul 2010 12:58:50 +0200

Paul Eggert wrote:

> On 07/01/10 15:59, Jim Meyering wrote:
>
>> Can you give me a backtrace?
>> Even if your patch is clearly better, I'd like to know
>> how my code is malfunctioning.
>
> Sure.  This uses your older patch, not the newer gnulib one.

I think they're functionally equivalent.
The new one adds comments.

> Program received signal SIGABRT, Aborted.
> 0x0012d422 in __kernel_vsyscall ()
> (gdb) where
> #0  0x0012d422 in __kernel_vsyscall ()
> #1  0x00158651 in *__GI_raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
> #2  0x0015ba82 in *__GI_abort () at abort.c:92
> #3  0x08054826 in hash_insert0 (table=0x805f208, entry=0x8017384d, matched_ent=0x0) at hash.c:1078
> #4  0x0804bdba in di_set_insert (dis=0x805e2f4, dev=2049, ino=380435) at di-set.c:264
> #5  0x0804ab0f in hash_ins (argc=52, argv=0xbffff304) at du.c:335
> #6  process_file (argc=52, argv=0xbffff304) at du.c:467
> #7  du_files (argc=52, argv=0xbffff304) at du.c:592
> #8  main (argc=52, argv=0xbffff304) at du.c:962
>
> The test case, by the way, is "./du ../../cu*", where the
> globbing pattern expands to 51 directories, each a copy of coreutils,
> with several hard links because many are git clones of each other.

Ouch.  That's the same assertion that Pádraig hit.  But he was
subsequently unable to reproduce it.  It indicates that when attempting
to insert the 2049,380435 dev,inode pair, hash_insert0 found that
the pair was not yet in the table, and that the table was too full,
so it first rehashed everything into a larger table, and then asserted
this:

    Since ENTRY was not in the initial table,
    it had better not be in the rehashed table.

That assertion failed, because somehow, ENTRY *was* in the new table.

Knowing the initial table size and the new one, given the above,
we might be able to determine what went wrong.

I have tried numerous times on both x86_64 and i686 to reproduce
it, but have never managed to trigger the failure.

Can you run "print *table" in gdb, say in hash_insert0?

Better still, set a conditional breakpoint in hash_insert0
to trigger when ENTRY == 0x8017384d (encoded version of 2049,380435),
and print the entire table using a variant of hash_print, step past
the rehash, and print the new table.