[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Preventing stack overflows with alloca.
From: |
Kim F. Storm |
Subject: |
Re: Preventing stack overflows with alloca. |
Date: |
18 Jun 2004 14:02:00 +0200 |
User-agent: |
Gnus/5.09 (Gnus v5.9.0) Emacs/21.3.50 |
Kenichi Handa <address@hidden> writes:
> > But there are other risky uses of alloca, so I suggest the
> > patch below which takes care of the problems in fns.c.
>
> Oops, I have completely forgotten about this problem.
> Actually I noticed it last year and sent the attached mail,
> but haven't worked on it any further. I remember Richard
> agreed with having the macro SAFE_ALLOCA. Of course we need
> the pairing SAFE_FREE which frees `address' and calls
> unbind_to if necessary.
Actually, now that you mention it, I remember your mail.
I think your approach is ok, but we can make it a bit
more generic with the following approach:
/* Define this in alloc.c */
Lisp_Object
safe_alloca_unwind (arg)
Lisp_Object arg;
{
xfree ((void *)arg);
return Qnil;
}
/* Add this to lisp.h */
extern Lisp_Object safe_alloca_unwind (Lisp_Object *);
#define USE_SAFE_ALLOCA \
int sa_count = SPECPDL_INDEX ()
#define SAFE_ALLOCA(buf, size) \
do { \
if (size < MAX_ALLOCA) \
buf = alloca (size); \
else \
record_unwind_protect (safe_alloca_unwind, \
(Lisp_Object)(buf = xmalloc (size))); \
} while (0)
#define SAFE_FREE(size) \
do { \
if (size >= MAX_ALLOCA) \
unbind_to (sa_count, Qnil); \
} while (0)
Of course, if a function already uses unwind protect,
it doesn't need USE_SAFE_ALLOCA and SAFE_FREE.
Since old_value is not a lisp object here,
we would need to fix (hack) GC like this:
for (bind = specpdl; bind != specpdl_ptr; bind++)
{
mark_object (bind->symbol);
if (bind->func != safe_alloca_unwind)
mark_object (bind->old_value);
}
A sample use would look like this:
Lisp_Object
string_make_multibyte (string)
Lisp_Object string;
{
unsigned char *buf;
int nbytes;
Lisp_Object ret;
USE_SAFE_ALLOCA;
if (STRING_MULTIBYTE (string))
return string;
nbytes = count_size_as_multibyte (SDATA (string),
SCHARS (string));
/* If all the chars are ASCII, they won't need any more bytes
once converted. In that case, we can return STRING itself. */
if (nbytes == SBYTES (string))
return string;
SAFE_ALLOCA (buf, nbytes);
copy_text (SDATA (string), buf, SBYTES (string),
0, 1);
ret = make_multibyte_string (buf, SCHARS (string), nbytes);
SAFE_FREE (nbytes);
return ret;
}
--
Kim F. Storm <address@hidden> http://www.cua.dk
- Preventing stack overflows with alloca., Kim F. Storm, 2004/06/18
- Re: Preventing stack overflows with alloca., Kenichi Handa, 2004/06/18
- Re: Preventing stack overflows with alloca.,
Kim F. Storm <=
- Re: Preventing stack overflows with alloca., Kenichi Handa, 2004/06/18
- Re: Preventing stack overflows with alloca., Richard Stallman, 2004/06/18
- Re: Preventing stack overflows with alloca., Kim F. Storm, 2004/06/20
- Re: Preventing stack overflows with alloca., Kim F. Storm, 2004/06/21
- Re: Preventing stack overflows with alloca., Richard Stallman, 2004/06/22