** 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 ubuntu-bugs@lists.ubuntu.com https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs