On Tue, Sep 12, 2017 at 02:41:29PM +0200, Michael Kerrisk (man-pages) wrote: > Hello Yubin, > > [...] > > +.B PTHREAD_MUTEX_ROBUST > > +can be set on a mutex attribute object so that when the owner of the mutex > > +dies or when the process containing such a locked mutex performs > > +.IR execve (2) > > +, any future attempts to call > > +.IR pthread_mutex_lock (3) > > +on this mutex will suceed and return > > +.B EOWNERDEAD > > +to indicate that the original owner no longer exists and the mutex is left in > > +an inconsistent state. > How did you verify the point regarding execve(2)? I don't see this > detailed mentioned in the standards or in the glibc source. Please see below the program I used to verify that. I haven't go into too much detail in the POSIX standard, though. I think I must have read it at [1] or somewhere else (don't remember...). And also, it is mentioned at [1] that when the process containing such a locked mutex unmaps the memory containing the mutex, the mutex is unlocked... I think this is trivial so I don't add it. Thanks, Yubin [1]: https://docs.oracle.com/cd/E19253-01/816-5168/pthread-mutexattr-setrobust-np-3c/index.html /************ verify-execve.c *****************/ #include <errno.h> #include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> #define VERIFY_KEY 20170010 #define ERROR_ON(func_name) \ fprintf(stderr, "error: " #func_name ": line[%d]: %s\n", __LINE__, strerror(errno)); int main(int argc, char *argv[]) { int shmid = -1; struct shm *shm = NULL; mode_t previous_umask = -1; int ret_code = 0; pthread_mutex_t *mutexp = NULL; pthread_mutexattr_t attr; pid_t pid = 0; char *const * execve_arg = {"cat", NULL}; char *const * execve_env = {NULL}; previous_umask = umask(0); shmid = shmget(VERIFY_KEY, sizeof(pthread_mutex_t), IPC_CREAT | 0666); if (shmid < 0) { ERROR_ON(shmget); return -1; } shm = (struct shm *)shmat(shmid, NULL, 0); if ((void *)-1 == shm) { ERROR_ON(shmat); return -1; } memset(shm, 0, sizeof(pthread_mutex_t)); printf("Successfully attached shared memory, trying to lock\n"); //initialize the lock mutexp = (pthread_mutex_t *)shm; pthread_mutexattr_init(&attr); pthread_mutexattr_setrobust(&attr, PTHREAD_MUTEX_ROBUST); pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); pthread_mutex_init(mutexp, &attr); ret_code = pthread_mutex_lock(mutexp); if (0 == ret_code) { printf("successfull acquired the lock. Going to fork/execve now\n"); } else { ERROR_ON(pthread_mutex_lock); return -1; } pid = fork(); if (0 == pid) { printf("child would sleep for 2 sec and then lock the mutex\n"); sleep(2); ret_code = pthread_mutex_lock(mutexp); if (EOWNERDEAD == ret_code) { printf("child see EOWNERDEAD returned. Verification completed\n"); pthread_mutex_consistent(mutexp); pthread_mutex_unlock(mutexp); exit(0); } else { printf("child see [%d] returned\n", ret_code); exit(1); } } else { printf("parent going to execve(/bin/cat)\n"); execve("/bin/cat", execve_arg, execve_env); } return 0; } -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html