gdb and memory caching?

Julien ÉLIE julien at trigofacile.com
Mon Nov 2 21:09:20 UTC 2009


Hi,

Trying to debug keyword generation code because of a
    *** glibc detected *** free(): invalid next size (fast): 0x083338b8 ***
I had last night when freeing hc->Value, I do not understand the output given
by gdb:

(gdb) step
246         strlcpy(hc->Value + l, ",\377", innconf->keylimit + 1 - l);
(gdb)
strlcpy (dst=0x8312a15 "", src=0x80a2af2 ",ÿ", size=1) at strlcpy.c:31

hc->Value is a pointer to the value of the Keywords: header.
l is the length of that value.
We see that "hc->Value + l" is 0x8312a15, which is '\0'.
That's fine.  We are at the end of the header.

innconf->keylimit = 5
And the header is "12345" at 0x8312a10.


Then, what I do not understand is that gdb mentions that l is 7
whereas it was changed to 5.
Is it a gdb bug?  (Very strange.)
Isn't gdb returning the current value of l?

247         for (chase = hc->Value + l + 2, word_index = 0;
(gdb) print l
$7 = 7
(gdb) print  hc->Value + l + 2
$9 = 0x8312a19 ""
(gdb) print  hc->Value + l
$11 = 0x8312a17 "\b\020"
(gdb) print hc->Value
$12 = 0x8312a10 "12345"
(gdb) print innconf->keylimit + 1 - l
$13 = 4294967295
(gdb) print innconf->keylimit
$14 = 5
(gdb) print strlen(hc->Value)
$17 = 5
(gdb) print hc->Length
$18 = 5

chase has the right value computed with l=5 (and not 7):

(gdb) s
256             *chase++ = ',';
(gdb) print l
$25 = 7
(gdb) print chase
$26 = 0x8312a17 "\b\020"
(gdb) s
257             strlcpy(chase, word[word_vec[word_index].index],
(gdb) print chase
$27 = 0x8312a18 "\020"
(gdb) print hc->Value
$28 = 0x8312a10 "12345"
(gdb) print hc->Value + 5
$29 = 0x8312a15 ""
(gdb) print hc->Value + 6
$30 = 0x8312a16 "\024,\020"



    /* Scribble onto end of Keywords: after a magic separator. */
    strlcpy(hc->Value + l, ",\377", innconf->keylimit + 1 - l);
    for (chase = hc->Value + l + 2, word_index = 0;
        word_index < distinct_words;
        word_index++) {

        /* Add to list. */
        *chase++ = ',';
        strlcpy(chase, word[word_vec[word_index].index],
                innconf->keylimit + 1 - (chase - hc->Value));
        chase += word_vec[word_index].length;

        if (chase - hc->Value > (innconf->keylimit - (MAX_WORD_LENGTH + 4)))
            break;
    }

chase is first set to "hc->Value + l + 2" even though it is beyond
the end of hc->Value; then a "," is added even though it is beyond
the end of hc->Value; and the comparison might be unsigned (size_t)
and therefore be wrong if the second member is negative.

I believe such things could trigger that error off:
    *** glibc detected *** free(): invalid next size (fast): 0x083338b8 ***
though I am not sure.  I do not manage to reproduce the crash; it does
not seem to be deterministic but depends on the contents of the allocated
memory.  I also wonder the difference between "(fast)" and "(normal)"...

-- 
Julien ÉLIE

« A man inserted an 'ad' in the classifieds: "Wife wanted".
  Next day he received a hundred letters.  They all said
  the same thing:  "You can have mine." » 




More information about the inn-workers mailing list