** Description changed:
- example code:
- ------------------
+ Code to trigger the problem:
+ ================================================================
#include <stdio.h>
#include <pthread.h>
static void thread_destructor(void *arg)
{
- printf("die!\n");
+ printf("die!\n");
}
int main(int argc, const char *argv[])
{
- pthread_cleanup_push(thread_destructor, NULL);
+ pthread_cleanup_push(thread_destructor, NULL);
- return 0;
+ return 0;
}
- compiling results in the following errors:
- --------------------------------------------------
- /tmp/ cc foo.c -Wall
+ Compiling results in the following errors:
+ ================================================================
+ /tmp/ cc foo.c -Wall
foo.c: In function ‘main’:
foo.c:14: error: expected ‘while’ at end of input
foo.c:14: error: expected declaration or statement at end of input
foo.c:14: error: expected declaration or statement at end of input
- the problem is obvious when you look at the code generated by the
preprocesssor:
-
--------------------------------------------------------------------------------------------------------
+ The problem is obvious if you look at the code generated by the preprocessor:
+ ('do { } while(0)' is not terminated with '} while(0)', but 'do {' )
+ ================================================================
...
int main(int argc, char **argv)
{
- do { __pthread_unwind_buf_t __cancel_buf; void (*__cancel_routine) (void
*) = (((void *)0)); void *__cancel_arg = (((void *)0)); int not_first_call =
__sigsetjmp ((struct __jmp_buf_tag *) (void *) __cancel_buf.__cancel_jmp_buf,
0); if (__builtin_expect (not_first_call, 0)) { __cancel_routine
(__cancel_arg); __pthread_unwind_next (&__cancel_buf); }
__pthread_register_cancel (&__cancel_buf); do {;
+ do { __pthread_unwind_buf_t __cancel_buf; void (*__cancel_routine) (void
*) = (((void *)0)); void *__cancel_arg = (((void *)0)); int not_first_call =
__sigsetjmp ((struct __jmp_buf_tag *) (void *) __cancel_buf.__cancel_jmp_buf,
0); if (__builtin_expect (not_first_call, 0)) { __cancel_routine
(__cancel_arg); __pthread_unwind_next (&__cancel_buf); }
__pthread_register_cancel (&__cancel_buf); do {;
- return 0;
+ return 0;
}
-
The correct code should look similar to the following:
- -----------------------------------------------------------------
+ ================================================================
#define pthread_cleanup_push(__thread_destructor, __arg) \
do { \
- __pthread_unwind_buf_t __cancel_buf; \
- void (*__cancel_routine) (void *) = (__thread_destructor); \
- void *__cancel_arg = (__arg); \
- int not_first_call = __sigsetjmp ((struct __jmp_buf_tag *) (void *)
__cancel_buf.__cancel_jmp_buf, 0); \
- if (__builtin_expect (not_first_call, 0)) { \
- __cancel_routine (__cancel_arg); \
- __pthread_unwind_next (&__cancel_buf); \
- } \
- __pthread_register_cancel (&__cancel_buf); \
+ __pthread_unwind_buf_t __cancel_buf; \
+ void (*__cancel_routine) (void *) = (__thread_destructor); \
+ void *__cancel_arg = (__arg); \
+ int not_first_call = __sigsetjmp ((struct __jmp_buf_tag *) (void *)
__cancel_buf.__cancel_jmp_buf, 0); \
+ if (__builtin_expect (not_first_call, 0)) { \
+ __cancel_routine (__cancel_arg); \
+ __pthread_unwind_next (&__cancel_buf); \
+ } \
+ __pthread_register_cancel (&__cancel_buf); \
} while(0)
ProblemType: Bug
DistroRelease: Ubuntu 10.04
Package: libc6-dev 2.11.1-0ubuntu7
ProcVersionSignature: Ubuntu 2.6.31-17.54-generic
Uname: Linux 2.6.31-17-generic x86_64
Architecture: amd64
Date: Tue May 4 09:57:52 2010
InstallationMedia: Ubuntu 9.10 "Karmic Koala" - Release amd64 (20091027)
ProcEnviron:
- PATH=(custom, user)
- LANG=en_US.utf8
- SHELL=/bin/bash
+ PATH=(custom, user)
+ LANG=en_US.utf8
+ SHELL=/bin/bash
SourcePackage: eglibc
--
the pthread_cleanup_push macro generates incorrect code
https://bugs.launchpad.net/bugs/575008
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
--
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs