[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
allocate_string_data memory corruption
From: |
Chong Yidong |
Subject: |
allocate_string_data memory corruption |
Date: |
Wed, 18 Jan 2006 11:57:02 -0500 |
There's been some progress tracking down the hyperthreading /
allocate_string related crash. We can now reproduce a crash reliably.
However, the memory corruption seems to happen after a debugging call
which ought to be a no-op. I'd appreciate if someone could look
through this and give a suggestion.
The memory corruption occurs in the `data' variable, an sdata struct
in alloc.c:allocate_string_data(), shown below. (The following code
is not the same as in CVS; we've changed some things for debugging):
void
allocate_string_data (s, nchars, nbytes)
struct Lisp_String *s;
int nchars, nbytes;
{
struct sdata *data;
struct sblock *b;
...
data = b->next_free;
data->string = s;
s->data = SDATA_DATA (data);
data->nbytes = nbytes;
s->size = nchars;
s->size_byte = nbytes;
s->data[nbytes] = '\0';
bcopy (string_overrun_cookie, (char *) data + needed,
GC_STRING_OVERRUN_COOKIE_SIZE);
/* no crash here */
if (data->string != s || data->nbytes != nbytes) abort ();
check_sblock (current_sblock);
/* crash occured here */
if (data->string != s || data->nbytes != nbytes) abort ();
...
}
In this function, data->string is set to s, and nbytes is set to
nbytes. If check_sblock is a no-op, there should be no change.
However, we get an abort on the second debugging check:
#0 abort () at emacs.c:461
#1 0x0817499e in allocate_string_data (s=0x8d18778, nchars=8,
nbytes=8) at alloc.c:2013
s == (struct Lisp_String *) 0x8d18778
data->string == (struct Lisp_String *) 0x8d18788 <-- off by 16
nbytes == 8
data->nbytes == 200 <-- off by 192
nchars == 8
needed == 20
#2 0x08175311 in make_uninit_multibyte_string (nchars=8, nbytes=8)
at alloc.c:2472
The definition of check_sblock() we used is as follows:
void
check_sblock (b)
struct sblock *b;
{
struct sdata *from, *end, *from_end;
end = b->next_free;
for (from = &b->first_data; from < end; from = from_end)
{
int nbytes = from->nbytes;
if (from->string && (nbytes != string_bytes (from->string)))
abort ();
nbytes = SDATA_SIZE (nbytes);
from_end = (struct sdata *) ((char *) from + nbytes + GC_STRING_EXTRA);
}
if (from != end)
abort();
}
int
string_bytes (s)
struct Lisp_String *s;
{
int nbytes = (s->size_byte < 0 ? s->size & ~ARRAY_MARK_FLAG : s->size_byte);
if (!PURE_POINTER_P (s)
&& s->data
&& nbytes != SDATA_NBYTES (SDATA_OF_STRING (s)))
abort ();
return nbytes;
}
There is clearly no assignment to any of the sdata structures in these
functions.
Any ideas?
- allocate_string_data memory corruption,
Chong Yidong <=