| 91 | } |
| 92 | |
| 93 | extern "C" int |
| 94 | pthread_create(pthread_t *pth, |
| 95 | const pthread_attr_t *attr, |
| 96 | void *(*start_routine)(void *), |
| 97 | void *arg) |
| 98 | { |
| 99 | WrapperLock wrapperLock; |
| 100 | Thread *thread = dmtcp_get_current_thread(); |
| 101 | |
| 102 | Thread *newThread = ThreadList::getNewThread(start_routine, arg); |
| 103 | ThreadSync::wrapperExecutionLockLockForNewThread(newThread); |
| 104 | JASSERT(newThread->wrapperLockCount != 0); |
| 105 | |
| 106 | JASSERT(Thread_UpdateState(thread, ST_THREAD_CREATE, ST_RUNNING)); |
| 107 | |
| 108 | int retval = _real_pthread_create(pth, attr, thread_start, newThread); |
| 109 | |
| 110 | JASSERT(Thread_UpdateState(thread, ST_RUNNING, ST_THREAD_CREATE)); |
| 111 | |
| 112 | if (retval == 0) { |
| 113 | ProcessInfo::instance().clearPthreadJoinState(*pth); |
| 114 | // Since glibc 2.42, pthread_create adds a lightweight guard page |
| 115 | // at the beginning of the new thread's stack using madvise() and |
| 116 | // MADV_GUARD_INSTALL. DMTCP may reads from this guard page and |
| 117 | // cause a segfault. As a quick fix, we remove the guard page |
| 118 | // immediately. |
| 119 | // |
| 120 | // FIXME: A better solution will be keep a record or added |
| 121 | // lightweight guard page. Remove them at checkpoint time and |
| 122 | // restore them at restart time. |
| 123 | #if __GLIBC__ == 2 && __GLIBC_MINOR__ >= 42 |
| 124 | pthread_attr_t new_attr; |
| 125 | void *stack_addr; |
| 126 | size_t stack_size, guard_size; |
| 127 | pthread_getattr_np(*pth, &new_attr); |
| 128 | pthread_attr_getstack(&new_attr, &stack_addr, &stack_size); |
| 129 | pthread_attr_getguardsize(&new_attr, &guard_size); |
| 130 | madvise((void*)((char*)stack_addr - guard_size), guard_size, |
| 131 | MADV_GUARD_REMOVE); |
| 132 | pthread_attr_destroy(&new_attr); |
| 133 | #endif |
| 134 | } else { // if we failed to create new pthread |
| 135 | ThreadSync::wrapperExecutionLockUnlockForNewThread(newThread); |
| 136 | ThreadList::threadIsDead(newThread); |
| 137 | } |
| 138 | |
| 139 | return retval; |
| 140 | } |
| 141 | |
| 142 | // Make sure __clone is not called without pthread_create. |
| 143 | extern "C" int |
no test coverage detected