Bug 31814 - pthread_cleanup_push() generates compiler errors in subsequent code.
Summary: pthread_cleanup_push() generates compiler errors in subsequent code.
Status: CLOSED NOTABUG
Alias: None
Product: Red Hat Linux
Classification: Retired
Component: gcc   
(Show other bugs)
Version: 7.0
Hardware: i386
OS: Linux
high
high
Target Milestone: ---
Assignee: Jakub Jelinek
QA Contact: David Lawrence
URL:
Whiteboard:
Keywords:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2001-03-15 01:23 UTC by Need Real Name
Modified: 2005-10-31 22:00 UTC (History)
0 users

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2001-03-15 01:23:39 UTC
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

Description Need Real Name 2001-03-15 01:23:35 UTC
Here's and example code. I know it must be the line with 
pthread_cleanup_push() because the errors cease when I comment out this 
one line:

EXTERN_C
DWORD	naiBeginThread(	LPVOID			pSecurity,
			UINT		 	unStackSize, 
			void		 	(*pfStartAddr)(void *), 
			void		 	*pArgs,
			UINT			nInitFlag,
			LPDWORD			pdwThreadID)
{
   naiHandleObject_t	*hThread;
   int			nThreadID;

   // Create the thread object
   if ( (hThread = (naiHandleObject_t *)malloc(sizeof(naiHandleObject_t))) 
								== NULL)
   {
      nErrno = ENOMEM;
      return((DWORD)(-1));
   }
   if ( (hThread->Handle = (void *)malloc(sizeof(naiThread_t))) == NULL)
   {
      nErrno = ENOMEM;
      free(hThread);
      return((DWORD)(-1));
   }

   // Start the thread and set all the outbound data
   if ( (nThreadID = pthread_create((naiThread_t *)hThread->Handle,NULL,
		(void *(*) (void *)) pfStartAddr,
		pArgs)) != 0)
   {
      free(hThread->Handle);
      free(hThread);
      return((DWORD)(-1));
   }

   // Push on the clean up routines - memory is freed by naiCleanupThread()
   naiThreadCleanup_t	*pCleanup;
   if ( (pCleanup = (naiThreadCleanup_t *)
			malloc(sizeof(naiThreadCleanup_t))) == NULL)
      return((DWORD)(-1));
   pCleanup->Mutex = hThread->Mutex;
   pCleanup->Condition = hThread->Condition;
   pCleanup->bSignalled = &(hThread->bSignalled);
   pthread_cleanup_push(naiCleanupThread,(void *)pCleanup);

   // The caller must deal with this and convert it to HANDLE type
   if (pdwThreadID != NULL)
   {
      *pdwThreadID = nThreadID;
   }
   hThread->nType = naiOBJECT_THREAD;
   hThread->nReferenceCounter = 1;
   if (pthread_cond_init(&hThread->Condition,NULL) != 0)
   {
      free(hThread->Handle);
      free(hThread);
      return((DWORD)(-1));
   }
   if (pthread_mutex_init(&hThread->Mutex,NULL) != 0)
   {
      free(hThread->Handle);
      free(hThread);
      return((DWORD)(-1));
   }
   hThread->bSignalled = naiFALSE;
   return((DWORD)hThread);
}
//-------------------------------------------------------------------------
---

// Just like naiBeginThread() with the exceptions noted in the docs for 
that
// function.

EXTERN_C
HANDLE	naiCreateThread(	LPSECURITY_ATTRIBUTES	lpThreadAttributes,
				DWORD			dwStackSize,
				LPTHREAD_START_ROUTINE	lpStartAddress,
				LPVOID			lpParameter,
				DWORD			dwCreationFlags,
				LPDWORD			lpThreadId)
{
   HANDLE		*Handle;
   DWORD		dwRet;


   if ( (dwRet = naiBeginThread((LPVOID)lpThreadAttributes,dwStackSize,
			( void (*) (void *) )lpStartAddress,
			(void *)lpParameter,dwCreationFlags,
			lpThreadId)) == -1)
   {
      return(NULL);
   }
   memcpy(&Handle,&dwRet,4);
   return(Handle);
}

//-------------------------------------------------------------------------
---


Here are the compiler errors that are generated (BTW, the code above 
starts with line 1133):
gcc -c -fPIC -g -D_LINUX_REDHAT -I./source -I./include -I../source -
I../include -I../../linux/source -I../linux/include -I../../linux/source -
I../../linux/include -I../../source -I../../include -
o ../linux/bin/portable.o ../../linux/source/portable.cpp
../../linux/source/portable.cpp: In function `DWORD naiBeginThread 
(void *, unsigned int, void (*) (void *), void *, unsigned int, long 
unsigned int *)':
../../linux/source/portable.cpp:1172: parse error before string 
constant
../../linux/source/portable.cpp:1184: `lpThreadAttributes' undeclared 
(first use this function)
../../linux/source/portable.cpp:1184: (Each undeclared identifier is 
reported only once for each function it appears in.)
../../linux/source/portable.cpp:1184: `dwStackSize' undeclared (first 
use this function)
../../linux/source/portable.cpp:1185: `lpStartAddress' undeclared 
(first use this function)
../../linux/source/portable.cpp:1186: `lpParameter' undeclared (first 
use this function)
../../linux/source/portable.cpp:1186: `dwCreationFlags' undeclared 
(first use this function)
../../linux/source/portable.cpp:1187: `lpThreadId' undeclared (first 
use this function)
../../linux/source/portable.cpp:1189: warning: return to non-pointer type 
`DWORD' from NULL
../../linux/source/portable.cpp:1189: warning: argument to non-pointer 
type `long unsigned int' from 
NULL
../../linux/source/portable.cpp:1191: `Handle' undeclared (first use 
this function)

Comment 1 Jakub Jelinek 2001-03-16 10:41:37 UTC
This is a bug in the code you're trying to compile.
Citing pthread.h:
/* Install a cleanup handler: ROUTINE will be called with arguments ARG
   when the thread is cancelled or calls pthread_exit.  ROUTINE will also
   be called with arguments ARG when the matching pthread_cleanup_pop
   is executed with non-zero EXECUTE argument.
   pthread_cleanup_push and pthread_cleanup_pop are macros and must always
   be used in matching pairs at the same nesting level of braces. */
You don't have the corresponding pthread_cleanup_pop macro and those must
be used in pairs at the same nesting level. Also, I'd recommend doing something
with the returns if they should be in the same pthread cleanup region
(because pushing cleanup and forgetting to pop it is a bug).


Note You need to log in before you can comment on or make changes to this bug.