Hi, Anthony,

I just found an issue with using libcxx std::thread library on NuttX. The
std::thread implementation uses pthread_key_create and pthread_setspecific
in order to setup a destructor that should be called to cleanup the memory.
Of course, it became pretty obvious what was wrong once I read the
following comment for pthread_key_create

  * Input Parameters:
  *   key        - A pointer to the key to create.
  *   destructor - An optional destructor() function that may be associated
  *                with each key that is invoked when a thread exits.
  *
*However, this argument is ignored in the current** *
implementation.*

From
https://www.ibm.com/support/knowledgecenter/en/SSLTBW_2.3.0/com.ibm.zos.v2r3.bpxbd00/ptkycre.htm

The destructor routine may be called when the thread ends. It is called
when a non-NULL value has been set for the key for this thread, using
pthread_setspecific(), and the thread:

    - Calls pthread_exit()


    - Does a return from the start routine


    - Is canceled because of a pthread_cancel() request.


So it seems that the implementation would require the destructor to be
called from pthread_exit and pthread_cancel.

However, I'm still uncertain where in the order of operations the
destructor should be called.  Before or after pthread_completejoin? Before
or after pthread_mutex_inconsistent?

Looking for some guidance before I start working on a fix.
A complication is that the destructor must run in user-mode in the user-address space.  pthread_exit() runs entirely in kernel mode in the kernel address space.  This is not a critical critical for the FLAT build since everything runs in a flat address space and everything runs in kernel mode.  But this is a probleml for the PROTECTED and KERNEL builds.  Having the destructor running is kernel mode would be a major security hole.

The same is true of pthread_cleanup() routines and the some solution would be required. See issue # 1263, https://github.com/apache/incubator-nuttx/issues/1263.  That solution would involve:

1. Add the pthread destructor functions to the TLS data structure, and

2. Move a portion of the pthread_cleanup logic into libs/libc/pthread: That portion would do the pthread_cleanup callbacks and the pthread-specific data desctructor calls while still in user mode.  Then trap into the kernel complete the find stages of the pthread exit logic.

Greg


Reply via email to