[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