mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2026-10-10 08:02:57 -04:00
Preserve POSIX thread identity after TLS errors
TLS setup failures cannot be recovered without misclassifying FreeRTOS-owned pthreads. Fail fast after cleaning up the per-thread marker, and retain key-creation status across pthread_once callers. Constraint: Thread identity has no recoverable fallback when POSIX TLS setup fails Rejected: Free and continue | leaves FreeRTOS-owned pthreads misclassified Confidence: high Scope-risk: narrow Reversibility: clean Directive: Keep fatal handling unless a recoverable status path is added end to end Tested: WSL GCC -Wall -Wextra -Werror compile; success path; injected pthread_once, pthread_key_create, malloc, and pthread_setspecific failures Not-tested: Full FreeRTOS POSIX scheduler test suite Related: FreeRTOS/FreeRTOS-Kernel#1447
This commit is contained in:
parent
9db704cd3b
commit
defa802e95
1 changed files with 46 additions and 10 deletions
52
portable/ThirdParty/GCC/Posix/port.c
vendored
52
portable/ThirdParty/GCC/Posix/port.c
vendored
|
|
@ -112,6 +112,7 @@ static pthread_t hTimerTickThread;
|
||||||
static bool xTimerTickThreadShouldRun;
|
static bool xTimerTickThreadShouldRun;
|
||||||
static uint64_t prvStartTimeNs;
|
static uint64_t prvStartTimeNs;
|
||||||
static pthread_key_t xThreadKey = 0;
|
static pthread_key_t xThreadKey = 0;
|
||||||
|
static int iThreadKeyCreateResult = 0;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void prvSetupSignalsAndSchedulerPolicy( void );
|
static void prvSetupSignalsAndSchedulerPolicy( void );
|
||||||
|
|
@ -129,6 +130,8 @@ static void prvInitThreadKey( void );
|
||||||
static void prvMarkAsFreeRTOSThread( void );
|
static void prvMarkAsFreeRTOSThread( void );
|
||||||
static BaseType_t prvIsFreeRTOSThread( void );
|
static BaseType_t prvIsFreeRTOSThread( void );
|
||||||
static void prvDestroyThreadKey( void );
|
static void prvDestroyThreadKey( void );
|
||||||
|
static void prvFatalError( const char * pcCall,
|
||||||
|
int iErrno ) __attribute__( ( __noreturn__ ) );
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void prvThreadKeyDestructor( void * pvData )
|
static void prvThreadKeyDestructor( void * pvData )
|
||||||
|
|
@ -139,24 +142,49 @@ static void prvThreadKeyDestructor( void * pvData )
|
||||||
|
|
||||||
static void prvInitThreadKey( void )
|
static void prvInitThreadKey( void )
|
||||||
{
|
{
|
||||||
pthread_key_create( &xThreadKey, prvThreadKeyDestructor );
|
iThreadKeyCreateResult = pthread_key_create( &xThreadKey, prvThreadKeyDestructor );
|
||||||
|
|
||||||
|
if( iThreadKeyCreateResult == 0 )
|
||||||
|
{
|
||||||
/* Destroy xThreadKey when the process exits. */
|
/* Destroy xThreadKey when the process exits. */
|
||||||
atexit( prvDestroyThreadKey );
|
atexit( prvDestroyThreadKey );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void prvMarkAsFreeRTOSThread( void )
|
static void prvMarkAsFreeRTOSThread( void )
|
||||||
{
|
{
|
||||||
uint8_t * pucThreadData = NULL;
|
uint8_t * pucThreadData = NULL;
|
||||||
|
int iRet;
|
||||||
|
|
||||||
( void ) pthread_once( &hThreadKeyOnce, prvInitThreadKey );
|
iRet = pthread_once( &hThreadKeyOnce, prvInitThreadKey );
|
||||||
|
|
||||||
|
if( iRet != 0 )
|
||||||
|
{
|
||||||
|
prvFatalError( "pthread_once", iRet );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( iThreadKeyCreateResult != 0 )
|
||||||
|
{
|
||||||
|
prvFatalError( "pthread_key_create", iThreadKeyCreateResult );
|
||||||
|
}
|
||||||
|
|
||||||
pucThreadData = malloc( 1 );
|
pucThreadData = malloc( 1 );
|
||||||
configASSERT( pucThreadData != NULL );
|
|
||||||
|
if( pucThreadData == NULL )
|
||||||
|
{
|
||||||
|
prvFatalError( "malloc", ENOMEM );
|
||||||
|
}
|
||||||
|
|
||||||
*pucThreadData = 1;
|
*pucThreadData = 1;
|
||||||
|
|
||||||
pthread_setspecific( xThreadKey, pucThreadData );
|
iRet = pthread_setspecific( xThreadKey, pucThreadData );
|
||||||
|
|
||||||
|
if( iRet != 0 )
|
||||||
|
{
|
||||||
|
free( pucThreadData );
|
||||||
|
prvFatalError( "pthread_setspecific", iRet );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
@ -164,8 +192,19 @@ static BaseType_t prvIsFreeRTOSThread( void )
|
||||||
{
|
{
|
||||||
uint8_t * pucThreadData = NULL;
|
uint8_t * pucThreadData = NULL;
|
||||||
BaseType_t xRet = pdFALSE;
|
BaseType_t xRet = pdFALSE;
|
||||||
|
int iRet;
|
||||||
|
|
||||||
( void ) pthread_once( &hThreadKeyOnce, prvInitThreadKey );
|
iRet = pthread_once( &hThreadKeyOnce, prvInitThreadKey );
|
||||||
|
|
||||||
|
if( iRet != 0 )
|
||||||
|
{
|
||||||
|
prvFatalError( "pthread_once", iRet );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( iThreadKeyCreateResult != 0 )
|
||||||
|
{
|
||||||
|
prvFatalError( "pthread_key_create", iThreadKeyCreateResult );
|
||||||
|
}
|
||||||
|
|
||||||
pucThreadData = ( uint8_t * ) pthread_getspecific( xThreadKey );
|
pucThreadData = ( uint8_t * ) pthread_getspecific( xThreadKey );
|
||||||
|
|
||||||
|
|
@ -184,9 +223,6 @@ static void prvDestroyThreadKey( void )
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void prvFatalError( const char * pcCall,
|
|
||||||
int iErrno ) __attribute__( ( __noreturn__ ) );
|
|
||||||
|
|
||||||
void prvFatalError( const char * pcCall,
|
void prvFatalError( const char * pcCall,
|
||||||
int iErrno )
|
int iErrno )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue