[RFA] libc/include/machine/setjmp.h: Only evaluate first parameter to sig{set,long}jmp once
Jeff Johnston
jjohnstn@redhat.com
Thu Mar 17 20:00:00 GMT 2005
Ok. The macros using the GCC extension should be protected with a check for
__GNUC__. Feel free to check that in. Thanks.
-- Jeff J.
Corinna Vinschen wrote:
> Ping?
>
> Corinna
>
> On Mar 9 18:12, Corinna Vinschen wrote:
>
>>Hi,
>>
>>while debugging current CVS of GDB under Cygwin, I found that the cause
>>of the problem I was looking for was this (simplified for readability):
>>
>>- There's a function call which returns a pointer to a freshly allocated
>> sigjmp_buf, let's name it alloc_jmpbuf().
>>
>>- sigsetjmp is called like this:
>>
>> sigsetjmp (*alloc_jmpbuf(), 1);
>>
>>- In libc/include/machine/setjmp.h, sigsetjmp is defined like this:
>>
>> #define sigsetjmp(env, savemask) ((env)[_SAVEMASK] = savemask,\
>> sigprocmask (SIG_SETMASK, 0, (sigset_t *) ((env) + _SIGMASK)),\
>> setjmp (env))
>>
>>A close look into this macro shows, that the first parameter, "env" is
>>evaluated three times. In the above situation, that means that three
>>times the function alloc_jmpbuf() is invocated, therefore three new
>>sigjmp_buf's exist after one call to sigsetjmp.
>>
>>While the implementation of sigsetjmp is not wrong in the first place,
>>it would be better if the implementation would handle cases like the
>>above gracefully.
>>
>>Therefore I propose the below patch. It uses a GCC extension, ({ ... })
>>bracketing, to evaluate the incoming parameter only once. I hope that's
>>ok for RTEMS as well?
>>
>>
>>Corinna
>>
>>ChangeLog:
>>
>> * libc/include/machine/setjmp.h (sigsetjmp): Use GCC extension to
>> evaluate first parameter only once.
>> (siglongjmp): Ditto.
>>
>>Index: libc/include/machine/setjmp.h
>>===================================================================
>>RCS file: /cvs/src/src/newlib/libc/include/machine/setjmp.h,v
>>retrieving revision 1.23
>>diff -u -p -r1.23 setjmp.h
>>--- libc/include/machine/setjmp.h 27 Jan 2005 23:54:42 -0000 1.23
>>+++ libc/include/machine/setjmp.h 9 Mar 2005 17:01:08 -0000
>>@@ -236,13 +236,22 @@ typedef int sigjmp_buf[_JBLEN+2];
>> # define _CYGWIN_WORKING_SIGSETJMP
>> #endif
>>
>>-#define sigsetjmp(env, savemask) ((env)[_SAVEMASK] = savemask,\
>>- sigprocmask (SIG_SETMASK, 0, (sigset_t *) ((env) + _SIGMASK)),\
>>- setjmp (env))
>>+#define sigsetjmp(env, savemask) \
>>+ ({ \
>>+ sigjmp_buf *_sjbuf = &(env); \
>>+ ((*_sjbuf)[_SAVEMASK] = savemask,\
>>+ sigprocmask (SIG_SETMASK, 0, (sigset_t *)((*_sjbuf) + _SIGMASK)),\
>>+ setjmp (*_sjbuf)); \
>>+ })
>>
>>-#define siglongjmp(env, val) ((((env)[_SAVEMASK])?\
>>- sigprocmask (SIG_SETMASK, (sigset_t *) ((env) + _SIGMASK), 0):0),\
>>- longjmp (env, val))
>>+#define siglongjmp(env, val) \
>>+ ({ \
>>+ sigjmp_buf *_sjbuf = &(env); \
>>+ ((((*_sjbuf)[_SAVEMASK]) ? \
>>+ sigprocmask (SIG_SETMASK, (sigset_t *)((*_sjbuf) + _SIGMASK), 0)\
>>+ : 0), \
>>+ longjmp (*_sjbuf, val)); \
>>+ })
>>
>> #ifdef __cplusplus
>> }
>>
>>
>>--
>>Corinna Vinschen
>>Cygwin Project Co-Leader
>>Red Hat, Inc.
>
>
More information about the Newlib
mailing list