From defa802e9512e87cbcd6b31c742566d39cc11417 Mon Sep 17 00:00:00 2001 From: yi chen <94xhn1@gmail.com> Date: Mon, 13 Jul 2026 04:46:08 +0800 Subject: [PATCH] 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 --- portable/ThirdParty/GCC/Posix/port.c | 56 +++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 10 deletions(-) diff --git a/portable/ThirdParty/GCC/Posix/port.c b/portable/ThirdParty/GCC/Posix/port.c index a1b1ca8c7cf..a9d66b1630e 100644 --- a/portable/ThirdParty/GCC/Posix/port.c +++ b/portable/ThirdParty/GCC/Posix/port.c @@ -112,6 +112,7 @@ static pthread_t hTimerTickThread; static bool xTimerTickThreadShouldRun; static uint64_t prvStartTimeNs; static pthread_key_t xThreadKey = 0; +static int iThreadKeyCreateResult = 0; /*-----------------------------------------------------------*/ static void prvSetupSignalsAndSchedulerPolicy( void ); @@ -129,6 +130,8 @@ static void prvInitThreadKey( void ); static void prvMarkAsFreeRTOSThread( void ); static BaseType_t prvIsFreeRTOSThread( void ); static void prvDestroyThreadKey( void ); +static void prvFatalError( const char * pcCall, + int iErrno ) __attribute__( ( __noreturn__ ) ); /*-----------------------------------------------------------*/ static void prvThreadKeyDestructor( void * pvData ) @@ -139,24 +142,49 @@ static void prvThreadKeyDestructor( void * pvData ) static void prvInitThreadKey( void ) { - pthread_key_create( &xThreadKey, prvThreadKeyDestructor ); - /* Destroy xThreadKey when the process exits. */ - atexit( prvDestroyThreadKey ); + iThreadKeyCreateResult = pthread_key_create( &xThreadKey, prvThreadKeyDestructor ); + + if( iThreadKeyCreateResult == 0 ) + { + /* Destroy xThreadKey when the process exits. */ + atexit( prvDestroyThreadKey ); + } } /*-----------------------------------------------------------*/ static void prvMarkAsFreeRTOSThread( void ) { uint8_t * pucThreadData = NULL; + int iRet; + + iRet = pthread_once( &hThreadKeyOnce, prvInitThreadKey ); + + if( iRet != 0 ) + { + prvFatalError( "pthread_once", iRet ); + } - ( void ) pthread_once( &hThreadKeyOnce, prvInitThreadKey ); + if( iThreadKeyCreateResult != 0 ) + { + prvFatalError( "pthread_key_create", iThreadKeyCreateResult ); + } pucThreadData = malloc( 1 ); - configASSERT( pucThreadData != NULL ); + + if( pucThreadData == NULL ) + { + prvFatalError( "malloc", ENOMEM ); + } *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; 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 ); @@ -184,9 +223,6 @@ static void prvDestroyThreadKey( void ) } /*-----------------------------------------------------------*/ -static void prvFatalError( const char * pcCall, - int iErrno ) __attribute__( ( __noreturn__ ) ); - void prvFatalError( const char * pcCall, int iErrno ) {