pthread.h: typo in #define pthread_cleanup_push/pthread_cleanup_pop

Mark Andrews marka at isc.org
Tue Nov 24 21:41:14 UTC 2009


In message <20091124153422.GT2331 at deviant.kiev.zoral.com.ua>, Kostik Belousov write
s:
> 
> --i616tqyc3hrkKsk2
> Content-Type: text/plain; charset=us-ascii
> Content-Disposition: inline
> Content-Transfer-Encoding: quoted-printable
> 
> On Tue, Nov 24, 2009 at 05:18:29PM +0200, Mikolaj Golub wrote:
> > On Tue, 24 Nov 2009 16:53:35 +0200 Mikolaj Golub wrote:
> >=20
> > > Hi,
> > >
> > > I have problems with compiling our application under 8.0.
> > >
> > > It fails due to these definitions in pthread.h that look like a typo or
> > > incorrectly applied patch:
> > >
> > >     170 #define         pthread_cleanup_push(cleanup_routine, cleanup_a=
> rg)              \
> > >     171                 {                                              =
>                  \
> > >     172                         struct _pthread_cleanup_info __cleanup_=
> info__;          \
> > >     173                         __pthread_cleanup_push_imp(cleanup_rout=
> ine, cleanup_arg,\
> > >     174                                 &__cleanup_info__);            =
>                  \
> > >     175                         {
> > >     176=20
> > >     177 #define         pthread_cleanup_pop(execute)                   =
>                  \
> > >     178                         }                                      =
>                  \
> > >     179                         __pthread_cleanup_pop_imp(execute);    =
>                  \
> > >     180                 }
> > >
> > >
> > > This patch fixes the problem for me:
> >=20
> > I was hurry when said that the patch fixed the problem. The application
> > compiled but later it crashed in pthread_cleanup_pop:
> >=20
> > (gdb) bt
> > #0  0xbf4f9ee0 in ?? ()
> > #1  0x287d18c9 in __pthread_cleanup_pop_imp () from /lib/libthr.so.3
> > #2  0x287d18ed in pthread_cleanup_pop () from /lib/libthr.so.3
> > #3  0x287d123c in pthread_exit () from /lib/libthr.so.3
> > #4  0x287c7757 in pthread_getprio () from /lib/libthr.so.3
> > #5  0x00000000 in ?? ()
> >=20
> > So, I don't know what these macros actually were supposed to be. They were
> > introduced in r179662:
> >=20
> > Revision 1.43: download - view: text, markup, annotated - select for diffs
> > Mon Jun 9 01:14:10 2008 UTC (17 months, 2 weeks ago) by davidxu
> > Branches: MAIN
> > Diff to: previous 1.42: preferred, colored
> > Changes since revision 1.42: +21 -2 lines
> >=20
> > SVN rev 179662 on 2008-06-09 01:14:10Z by davidxu
> >=20
> > Make pthread_cleanup_push() and pthread_cleanup_pop() as a pair of macros,
> > use stack space to keep cleanup information, this eliminates overhead of
> > calling malloc() and free() in thread library.
> >=20
> > Discussed on: thread@
> >=20
> > > --- pthread.h.orig    2009-11-24 16:44:13.000000000 +0200
> > > +++ pthread.h   2009-11-24 16:44:45.000000000 +0200
> > > @@ -172,10 +172,10 @@
> > >                         struct _pthread_cleanup_info __cleanup_info__; =
>          \
> > >                         __pthread_cleanup_push_imp(cleanup_routine, cle=
> anup_arg,\
> > >                                 &__cleanup_info__);                    =
>          \
> > > -                       {
> > > +               }      =20
> > > =20
> > >  #define                pthread_cleanup_pop(execute)                   =
>                  \
> > > -                       }                                              =
>          \
> > > +               {                                                      =
>  \
> > >                         __pthread_cleanup_pop_imp(execute);            =
>          \
> > >                 }
> 
> pthread_cleanup_push/pop are supposed to be used from the common
> lexical scope. Citation from SUSv4:
> 
> These functions may be implemented as macros. The application shall
> ensure that they appear as statements, and in pairs within the same
> lexical scope (that is, the pthread_cleanup_push() macro may be
> thought to expand to a token list whose first token is '{' with
> pthread_cleanup_pop() expanding to a token list whose last token is the
> corresponding '}' ).
> 
> Your change is wrong.
> 
> Basically, the code should do
> 	pthread_cleanup_push(some_func, arh);
> 	something ...
> 	pthread_cleanup_pop(1);
> (1 denotes that some_func should be called).

The problem is that that expands to C code that can only be used
with newer C compilers.  This expansion should be usable with all
C compilers.

#define         pthread_cleanup_push(cleanup_routine, cleanup_arg)         \
		{                                                          \
	        	struct _pthread_cleanup_info __cleanup_info__;     \
                        __pthread_cleanup_push_imp(cleanup_routine, cleanup _arg,\
						   &__cleanup_info__)

#define         pthread_cleanup_pop(execute)                               \
                       __pthread_cleanup_pop_imp(execute);                \
                } ((void)0)

> 
> --i616tqyc3hrkKsk2
> Content-Type: application/pgp-signature
> Content-Disposition: inline
> 
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.10 (FreeBSD)
> 
> iEYEARECAAYFAksL/P4ACgkQC3+MBN1Mb4h4UwCgxIIHVqHBqU9wPIQKiOWf9g2z
> r94AoOiN4CE6Eig6AlJ1IuHFo9Hk7Pvf
> =FjUi
> -----END PGP SIGNATURE-----
> 
> --i616tqyc3hrkKsk2--
-- 
Mark Andrews, ISC
1 Seymour St., Dundas Valley, NSW 2117, Australia
PHONE: +61 2 9871 4742                 INTERNET: marka at isc.org


More information about the freebsd-stable mailing list