This is the mail archive of the newlib@sources.redhat.com mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFA] libc/include/machine/setjmp.h: Only evaluate first parameter to sig{set,long}jmp once


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.

-- 
Corinna Vinschen
Cygwin Project Co-Leader
Red Hat, Inc.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]