pthread_cleanup_push error
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
eglibc (Ubuntu) |
Invalid
|
Undecided
|
petter wahlman |
Bug Description
Code to trigger the problem:
=======
#include <stdio.h>
#include <pthread.h>
static void thread_
{
printf(
}
int main(int argc, const char *argv[])
{
pthread_
return 0;
}
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 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_
return 0;
}
The correct code should look similar to the following:
=======
#define pthread_
do { \
__pthread_
void (*__cancel_routine) (void *) = (__thread_
void *__cancel_arg = (__arg); \
int not_first_call = __sigsetjmp ((struct __jmp_buf_tag *) (void *) __cancel_
if (__builtin_expect (not_first_call, 0)) { \
} \
__pthread_
} while(0)
ProblemType: Bug
DistroRelease: Ubuntu 10.04
Package: libc6-dev 2.11.1-0ubuntu7
ProcVersionSign
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
SourcePackage: eglibc
description: | updated |
summary: |
- the pthread_cleanup_push macro generates incorrect code + pthread_cleanup_push error |
tags: | removed: amd64 apport-bug lucid |
Changed in eglibc (Ubuntu): | |
assignee: | nobody → petter wahlman (petter-wahlman) |
status: | New → Invalid |
Not a bug. A pthread_ cleanup_ push must be accompanied by a matching pthread_ cleanup_ pop. The macro definition contains an explanation:
/* Believe or not, the definitions of pthread_ cleanup_ push and longjmp/ return/ break/continue cleanup_ push(routine, arg) \
__pthread_ cleanup_ t __cleanup; \
__pthread_ cleanup_ push( &__cleanup, (routine), (arg) ); \
* pthread_cleanup_pop below are correct. Posix states that these
* can be implemented as macros that might introduce opening and
* closing braces, and that using setjmp/
* between them results in undefined behaviour.
*
* And indeed, GLibc and other C libraries use a similar definition
*/
#define pthread_
do { \
#define pthread_ cleanup_ pop(execute) \
__pthread_ cleanup_ pop( &__cleanup, (execute)); \
} while (0);