Skip to content

Commit

Permalink
All hooks are required now, they are only initialized if they are used
Browse files Browse the repository at this point in the history
  • Loading branch information
dsharlet committed Nov 20, 2024
1 parent 7f80ee9 commit 10379f1
Showing 1 changed file with 28 additions and 68 deletions.
96 changes: 28 additions & 68 deletions pthread_trace.cc
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ int (*sem_timedwait)(sem_t*, const struct timespec*) = nullptr;
int (*sem_trywait)(sem_t*) = nullptr;
int (*sem_post)(sem_t*) = nullptr;

template <bool Required, typename T>
template <typename T>
NOINLINE void init(T& hook, T def, const char* name, const char* version = nullptr) {
if (hook) return;

Expand All @@ -96,12 +96,8 @@ NOINLINE void init(T& hook, T def, const char* name, const char* version = nullp
}
}
if (!result) {
if (Required) {
fprintf(stderr, "Failed to find %s\n", name);
exit(1);
} else {
return;
}
fprintf(stderr, "Failed to find %s\n", name);
exit(1);
}

// This might run on more than one thread, this is a benign race.
Expand Down Expand Up @@ -624,134 +620,112 @@ track track::dummy{std::false_type()};
extern "C" {

unsigned int sleep(unsigned int secs) {
if (!hooks::sleep) hooks::init<true>(hooks::sleep, __sleep, "sleep");

auto& t = track::get_thread();
t.write_begin(slice_begin_sleep);
assert(hooks::sleep);
if (!hooks::sleep) hooks::init(hooks::sleep, __sleep, "sleep");
unsigned int result = hooks::sleep(secs);
t.write_end(); // slice_begin_sleep
return result;
}

int usleep(useconds_t usecs) {
if (!hooks::usleep) hooks::init<true>(hooks::usleep, __usleep, "usleep");

auto& t = track::get_thread();
t.write_begin(slice_begin_usleep);
assert(hooks::usleep);
if (!hooks::usleep) hooks::init(hooks::usleep, __usleep, "usleep");
int result = hooks::usleep(usecs);
t.write_end(); // slice_begin_usleep
return result;
}

int nanosleep(const struct timespec* duration, struct timespec* rem) {
if (!hooks::nanosleep) hooks::init<true>(hooks::nanosleep, __nanosleep, "nanosleep");

auto& t = track::get_thread();
t.write_begin(slice_begin_nanosleep);
assert(hooks::nanosleep);
if (!hooks::nanosleep) hooks::init(hooks::nanosleep, __nanosleep, "nanosleep");
int result = hooks::nanosleep(duration, rem);
t.write_end(); // slice_begin_nanosleep
return result;
}

int sched_yield() {
if (!hooks::sched_yield) hooks::init<true>(hooks::sched_yield, __sched_yield, "sched_yield");

auto& t = track::get_thread();
t.write_begin(slice_begin_yield);
assert(hooks::sched_yield);
if (!hooks::sched_yield) hooks::init(hooks::sched_yield, __sched_yield, "sched_yield");
int result = hooks::sched_yield();
t.write_end(); // slice_begin_yield
return result;
}

int pthread_cond_broadcast(pthread_cond_t* cond) {
if (!hooks::pthread_cond_broadcast)
hooks::init<true>(hooks::pthread_cond_broadcast, __pthread_cond_broadcast, "pthread_cond_broadcast", "GLIBC_2.3.2");

auto& t = track::get_thread();
t.write_begin(slice_begin_cond_broadcast);
assert(hooks::pthread_cond_broadcast);
if (!hooks::pthread_cond_broadcast)
hooks::init(hooks::pthread_cond_broadcast, __pthread_cond_broadcast, "pthread_cond_broadcast", "GLIBC_2.3.2");
int result = hooks::pthread_cond_broadcast(cond);
t.write_end(); // slice_begin_cond_broadcast
return result;
}

int pthread_cond_signal(pthread_cond_t* cond) {
if (!hooks::pthread_cond_signal)
hooks::init<true>(hooks::pthread_cond_signal, __pthread_cond_signal, "pthread_cond_signal", "GLIBC_2.3.2");

auto& t = track::get_thread();
t.write_begin(slice_begin_cond_signal);
assert(hooks::pthread_cond_signal);
if (!hooks::pthread_cond_signal)
hooks::init(hooks::pthread_cond_signal, __pthread_cond_signal, "pthread_cond_signal", "GLIBC_2.3.2");
int result = hooks::pthread_cond_signal(cond);
t.write_end(); // slice_begin_cond_signal
return result;
}

int pthread_cond_timedwait(pthread_cond_t* cond, pthread_mutex_t* mutex, const struct timespec* abstime) {
if (!hooks::pthread_cond_timedwait)
hooks::init<true>(hooks::pthread_cond_timedwait, __pthread_cond_timedwait, "pthread_cond_timedwait", "GLIBC_2.3.2");

// When we wait on a cond var, the mutex gets unlocked, and then relocked before returning.
auto& t = track::get_thread();
t.write_end_mutex_locked("mutex", mutex);
t.write_begin(slice_begin_cond_timedwait);
assert(hooks::pthread_cond_timedwait);
if (!hooks::pthread_cond_timedwait)
hooks::init(hooks::pthread_cond_timedwait, __pthread_cond_timedwait, "pthread_cond_timedwait", "GLIBC_2.3.2");
int result = hooks::pthread_cond_timedwait(cond, mutex, abstime);
t.write_end(); // slice_begin_cond_timedwait
t.write_begin_mutex_locked("mutex", mutex);
return result;
}

int pthread_cond_wait(pthread_cond_t* cond, pthread_mutex_t* mutex) {
if (!hooks::pthread_cond_wait)
hooks::init<true>(hooks::pthread_cond_wait, __pthread_cond_wait, "pthread_cond_wait", "GLIBC_2.3.2");

// When we wait on a cond var, the mutex gets unlocked, and then relocked before returning.
auto& t = track::get_thread();
t.write_end_mutex_locked("mutex", mutex);
t.write_begin(slice_begin_cond_wait);
assert(hooks::pthread_cond_wait);
if (!hooks::pthread_cond_wait)
hooks::init(hooks::pthread_cond_wait, __pthread_cond_wait, "pthread_cond_wait", "GLIBC_2.3.2");
int result = hooks::pthread_cond_wait(cond, mutex);
t.write_end(); // slice_begin_cond_wait
t.write_begin_mutex_locked("mutex", mutex);
return result;
}

int pthread_join(pthread_t thread, void** value_ptr) {
if (!hooks::pthread_join) hooks::init<true>(hooks::pthread_join, __pthread_join, "pthread_join");

auto& t = track::get_thread();
t.write_begin(slice_begin_join);
assert(hooks::pthread_join);
if (!hooks::pthread_join) hooks::init(hooks::pthread_join, __pthread_join, "pthread_join");
int result = hooks::pthread_join(thread, value_ptr);
t.write_end(); // slice_begin_join
return result;
}

int pthread_mutex_lock(pthread_mutex_t* mutex) {
if (!hooks::pthread_mutex_lock)
hooks::init<true>(hooks::pthread_mutex_lock, __pthread_mutex_lock, "pthread_mutex_lock");

auto& t = track::get_thread();
t.write_begin(slice_begin_mutex_lock);
assert(hooks::pthread_mutex_lock);
if (!hooks::pthread_mutex_lock)
hooks::init(hooks::pthread_mutex_lock, __pthread_mutex_lock, "pthread_mutex_lock");
int result = hooks::pthread_mutex_lock(mutex);
t.write_end(); // slice_begin_mutex_lock
t.write_begin_mutex_locked("mutex", mutex);
return result;
}

int pthread_mutex_trylock(pthread_mutex_t* mutex) {
if (!hooks::pthread_mutex_trylock)
hooks::init<true>(hooks::pthread_mutex_trylock, __pthread_mutex_trylock, "pthread_mutex_trylock");

auto& t = track::get_thread();
t.write_begin(slice_begin_mutex_trylock);
assert(hooks::pthread_mutex_trylock);
if (!hooks::pthread_mutex_trylock)
hooks::init(hooks::pthread_mutex_trylock, __pthread_mutex_trylock, "pthread_mutex_trylock");
int result = hooks::pthread_mutex_trylock(mutex);
t.write_end(); // slice_begin_mutex_trylock
if (result == 0) {
Expand All @@ -761,58 +735,48 @@ int pthread_mutex_trylock(pthread_mutex_t* mutex) {
}

int pthread_mutex_unlock(pthread_mutex_t* mutex) {
if (!hooks::pthread_mutex_unlock)
hooks::init<true>(hooks::pthread_mutex_unlock, __pthread_mutex_unlock, "pthread_mutex_unlock");

auto& t = track::get_thread();
t.write_end_mutex_locked("mutex", mutex);
t.write_begin(slice_begin_mutex_unlock);
assert(hooks::pthread_mutex_unlock);
if (!hooks::pthread_mutex_unlock)
hooks::init(hooks::pthread_mutex_unlock, __pthread_mutex_unlock, "pthread_mutex_unlock");
int result = hooks::pthread_mutex_unlock(mutex);
t.write_end(); // slice_begin_mutex_unlock
return result;
}

int pthread_once(pthread_once_t* once_control, void (*init_routine)(void)) {
if (!hooks::pthread_once) hooks::init<true>(hooks::pthread_once, __pthread_once, "pthread_once");

auto& t = track::get_thread();
t.write_begin(slice_begin_once);
assert(hooks::pthread_once);
if (!hooks::pthread_once) hooks::init(hooks::pthread_once, __pthread_once, "pthread_once");
int result = hooks::pthread_once(once_control, init_routine);
t.write_end(); // slice_begin_once
return result;
}

int pthread_barrier_wait(pthread_barrier_t* barrier) {
hooks::init<false>(hooks::pthread_barrier_wait, __pthread_barrier_wait, "pthread_barrier_wait");

auto& t = track::get_thread();
t.write_begin(slice_begin_barrier_wait);
assert(hooks::pthread_barrier_wait);
hooks::init(hooks::pthread_barrier_wait, __pthread_barrier_wait, "pthread_barrier_wait");
int result = hooks::pthread_barrier_wait(barrier);
t.write_end();
return result;
}

int sem_wait(sem_t* sem) {
if (!hooks::sem_wait) hooks::init<true>(hooks::sem_wait, __sem_wait, "sem_wait");

auto& t = track::get_thread();
t.write_begin(slice_begin_sem_wait);
assert(hooks::sem_wait);
if (!hooks::sem_wait) hooks::init(hooks::sem_wait, __sem_wait, "sem_wait");
int result = hooks::sem_wait(sem);
t.write_end();
t.write_begin_mutex_locked("semaphore", sem);
return result;
}

int sem_timedwait(sem_t* sem, const struct timespec* abstime) {
if (!hooks::sem_timedwait) hooks::init<true>(hooks::sem_timedwait, __sem_timedwait, "sem_timedwait");

auto& t = track::get_thread();
t.write_begin(slice_begin_sem_timedwait);
assert(hooks::sem_timedwait);
if (!hooks::sem_timedwait) hooks::init(hooks::sem_timedwait, __sem_timedwait, "sem_timedwait");
int result = hooks::sem_timedwait(sem, abstime);
t.write_end();
if (result == 0) {
Expand All @@ -822,11 +786,9 @@ int sem_timedwait(sem_t* sem, const struct timespec* abstime) {
}

int sem_trywait(sem_t* sem) {
if (!hooks::sem_trywait) hooks::init<true>(hooks::sem_trywait, __sem_trywait, "sem_trywait");

auto& t = track::get_thread();
t.write_begin(slice_begin_sem_trywait);
assert(hooks::sem_trywait);
if (!hooks::sem_trywait) hooks::init(hooks::sem_trywait, __sem_trywait, "sem_trywait");
int result = hooks::sem_trywait(sem);
t.write_end();
if (result == 0) {
Expand All @@ -836,12 +798,10 @@ int sem_trywait(sem_t* sem) {
}

int sem_post(sem_t* sem) {
if (!hooks::sem_post) hooks::init<true>(hooks::sem_post, __sem_post, "sem_post");

auto& t = track::get_thread();
t.write_end_mutex_locked("semaphore", sem);
t.write_begin(slice_begin_sem_post);
assert(hooks::sem_post);
if (!hooks::sem_post) hooks::init(hooks::sem_post, __sem_post, "sem_post");
int result = hooks::sem_post(sem);
t.write_end();
return result;
Expand Down

0 comments on commit 10379f1

Please sign in to comment.