diff --git a/gtests/net/packetdrill/logging.c b/gtests/net/packetdrill/logging.c index 730add4b8c8683cf8631a0b18cefa231ef397013..0b722845d6fdcc219006e3a666dc538cb7ab374a 100644 --- a/gtests/net/packetdrill/logging.c +++ b/gtests/net/packetdrill/logging.c @@ -49,3 +49,12 @@ void __attribute__((noreturn)) die_perror(char *message) exit(EXIT_FAILURE); } + +void __attribute__((noreturn)) die_strerror(char *message, int err) +{ + fprintf(stderr, "%s: %s", message, strerror(err)); + + run_cleanup_command(); + + exit(EXIT_FAILURE); +} diff --git a/gtests/net/packetdrill/logging.h b/gtests/net/packetdrill/logging.h index 2e17bd097c522bb58cbebd1b7ffe686fcfc3368c..97487ef88dbece174ed298c884d5eee93e809241 100644 --- a/gtests/net/packetdrill/logging.h +++ b/gtests/net/packetdrill/logging.h @@ -47,4 +47,6 @@ extern void __attribute__((noreturn)) die(char *format, ...); /* Call perror() with message and then exit with a failure status code. */ extern void __attribute__((noreturn)) die_perror(char *message); +/* Call strerror with with err and then exit with a failure status code. */ +extern void __attribute__((noreturn)) die_strerror(char *message, int err); #endif /* __LOGGING_H__ */ diff --git a/gtests/net/packetdrill/run.c b/gtests/net/packetdrill/run.c index 217a060782663ad1c573dcfa692b7d96d70909ef..8467bb737c165c82990c947484d4e823e94fcef1 100644 --- a/gtests/net/packetdrill/run.c +++ b/gtests/net/packetdrill/run.c @@ -87,9 +87,10 @@ struct state *state_new(struct config *config, struct netdev *netdev) { struct state *state = calloc(1, sizeof(struct state)); + int err; - if (pthread_mutex_init(&state->mutex, NULL) != 0) - die_perror("pthread_mutex_init"); + if ((err = pthread_mutex_init(&state->mutex, NULL)) != 0) + die_strerror("pthread_mutex_init", err); run_lock(state); @@ -146,6 +147,8 @@ static void close_all_sockets(struct state *state) void state_free(struct state *state, int about_to_die) { + int err; + /* We have to stop the system call thread first, since it's using * sockets that we want to close and reset. */ @@ -162,8 +165,8 @@ void state_free(struct state *state, int about_to_die) code_free(state->code); run_unlock(state); - if (pthread_mutex_destroy(&state->mutex) != 0) - die_perror("pthread_mutex_destroy"); + if ((err = pthread_mutex_destroy(&state->mutex)) != 0) + die_strerror("pthread_mutex_destroy", err); memset(state, 0, sizeof(*state)); /* paranoia to help catch bugs */ free(state); diff --git a/gtests/net/packetdrill/run.h b/gtests/net/packetdrill/run.h index 6acb518b397a222ac605fd83b751b940194156f3..ccba2fef1386a260b37fb46e2825de68ae0b6abe 100644 --- a/gtests/net/packetdrill/run.h +++ b/gtests/net/packetdrill/run.h @@ -115,15 +115,19 @@ void state_free(struct state *state, int about_to_die); /* Grab the global lock for all global state. */ static inline void run_lock(struct state *state) { - if (pthread_mutex_lock(&state->mutex) != 0) - die_perror("pthread_mutex_lock"); + int err; + + if ((err = pthread_mutex_lock(&state->mutex)) != 0) + die_strerror("pthread_mutex_lock", err); } /* Release the global lock for all global state. */ static inline void run_unlock(struct state *state) { - if (pthread_mutex_unlock(&state->mutex) != 0) - die_perror("pthread_mutex_unlock"); + int err; + + if ((err = pthread_mutex_unlock(&state->mutex)) != 0) + die_strerror("pthread_mutex_unlock", err); } /* Get the wall clock time of day in microseconds. */ diff --git a/gtests/net/packetdrill/run_system_call.c b/gtests/net/packetdrill/run_system_call.c index 3bb73fc20e55be0c13e24d3e9d34f23a3e1bb370..4a0d9396acb63eb51f51168854dbf24634f52b69 100644 --- a/gtests/net/packetdrill/run_system_call.c +++ b/gtests/net/packetdrill/run_system_call.c @@ -1647,13 +1647,15 @@ static int pollfds_check(struct expression *fds_expression, */ static void begin_syscall(struct state *state, struct syscall_spec *syscall) { + int err; + if (is_blocking_syscall(syscall)) { assert(state->syscalls->state == SYSCALL_ENQUEUED); state->syscalls->state = SYSCALL_RUNNING; run_unlock(state); DEBUGP("syscall thread: begin_syscall signals dequeued\n"); - if (pthread_cond_signal(&state->syscalls->dequeued) != 0) - die_perror("pthread_cond_signal"); + if ((err = pthread_cond_signal(&state->syscalls->dequeued)) != 0) + die_strerror("pthread_cond_signal", err); } } @@ -7002,12 +7004,12 @@ static int await_idle_thread(struct state *state) } /* Wait for a signal or our timeout end_time to arrive. */ DEBUGP("main thread: awaiting idle syscall thread\n"); - int status = pthread_cond_timedwait(&state->syscalls->idle, - &state->mutex, &end_time); - if (status == ETIMEDOUT) + int err = pthread_cond_timedwait(&state->syscalls->idle, + &state->mutex, &end_time); + if (err == ETIMEDOUT) return STATUS_ERR; - else if (status != 0) - die_perror("pthread_cond_timedwait"); + else if (err != 0) + die_strerror("pthread_cond_timedwait", err); } return STATUS_OK; } @@ -7034,6 +7036,7 @@ static void enqueue_system_call( struct state *state, struct event *event, struct syscall_spec *syscall) { char *error = NULL, *script_path = NULL; + int err; bool done = false; /* Wait if there are back-to-back blocking system calls. */ @@ -7046,16 +7049,16 @@ static void enqueue_system_call( /* Enqueue the system call info and wake up the syscall thread. */ DEBUGP("main thread: signal enqueued\n"); state->syscalls->state = SYSCALL_ENQUEUED; - if (pthread_cond_signal(&state->syscalls->enqueued) != 0) - die_perror("pthread_cond_signal"); + if ((err = pthread_cond_signal(&state->syscalls->enqueued)) != 0) + die_strerror("pthread_cond_signal", err); /* Wait for the syscall thread to dequeue and start the system call. */ while (state->syscalls->state == SYSCALL_ENQUEUED) { DEBUGP("main thread: waiting for dequeued signal; " "state: %d\n", state->syscalls->state); - if (pthread_cond_wait(&state->syscalls->dequeued, - &state->mutex) != 0) { - die_perror("pthread_cond_wait"); + if ((err = pthread_cond_wait(&state->syscalls->dequeued, + &state->mutex)) != 0) { + die_strerror("pthread_cond_wait", err); } } @@ -7127,6 +7130,7 @@ static void *system_call_thread(void *arg) char *error = NULL; struct event *event = NULL; struct syscall_spec *syscall = NULL; + int err; bool done = false; #if defined(__FreeBSD__) @@ -7156,9 +7160,9 @@ static void *system_call_thread(void *arg) switch (state->syscalls->state) { case SYSCALL_IDLE: DEBUGP("syscall thread: waiting\n"); - if (pthread_cond_wait(&state->syscalls->enqueued, - &state->mutex)) { - die_perror("pthread_cond_wait"); + if ((err = pthread_cond_wait(&state->syscalls->enqueued, + &state->mutex))) { + die_strerror("pthread_cond_wait", err); } break; @@ -7209,8 +7213,8 @@ static void *system_call_thread(void *arg) state->syscalls->event = NULL; state->syscalls->live_end_usecs = -1; DEBUGP("syscall thread: now idle\n"); - if (pthread_cond_signal(&state->syscalls->idle) != 0) - die_perror("pthread_cond_signal"); + if ((err = pthread_cond_signal(&state->syscalls->idle)) != 0) + die_strerror("pthread_cond_signal", err); break; case SYSCALL_EXITING: @@ -7228,18 +7232,19 @@ static void *system_call_thread(void *arg) struct syscalls *syscalls_new(struct state *state) { struct syscalls *syscalls = calloc(1, sizeof(struct syscalls)); + int err; syscalls->state = SYSCALL_IDLE; - if (pthread_create(&syscalls->thread, NULL, system_call_thread, - state) != 0) { - die_perror("pthread_create"); + if ((err = pthread_create(&syscalls->thread, NULL, system_call_thread, + state)) != 0) { + die_strerror("pthread_create", err); } - if ((pthread_cond_init(&syscalls->idle, NULL) != 0) || - (pthread_cond_init(&syscalls->enqueued, NULL) != 0) || - (pthread_cond_init(&syscalls->dequeued, NULL) != 0)) { - die_perror("pthread_cond_init"); + if (((err= pthread_cond_init(&syscalls->idle, NULL)) != 0) || + ((err = pthread_cond_init(&syscalls->enqueued, NULL)) != 0) || + ((err = pthread_cond_init(&syscalls->dequeued, NULL)) != 0)) { + die_strerror("pthread_cond_init", err); } return syscalls; @@ -7247,7 +7252,7 @@ struct syscalls *syscalls_new(struct state *state) void syscalls_free(struct state *state, struct syscalls *syscalls, int about_to_die) { - int status; + int status, err; /* Wait a bit for the thread to go idle. */ status = await_idle_thread(state); @@ -7266,21 +7271,21 @@ void syscalls_free(struct state *state, struct syscalls *syscalls, int about_to_ /* Send a request to terminate the thread. */ DEBUGP("main thread: signaling syscall thread to exit\n"); syscalls->state = SYSCALL_EXITING; - if (pthread_cond_signal(&syscalls->enqueued) != 0) - die_perror("pthread_cond_signal"); + if ((err = pthread_cond_signal(&syscalls->enqueued)) != 0) + die_strerror("pthread_cond_signal", err); } /* Release the lock briefly and wait for syscall thread to finish. */ run_unlock(state); DEBUGP("main thread: unlocking, waiting for syscall thread exit\n"); void *thread_result = NULL; - if (pthread_join(syscalls->thread, &thread_result) != 0) - die_perror("pthread_cancel"); + if ((err = pthread_join(syscalls->thread, &thread_result)) != 0) + die_strerror("pthread_join", err); DEBUGP("main thread: joined syscall thread; relocking\n"); run_lock(state); - if ((pthread_cond_destroy(&syscalls->idle) != 0) || - (pthread_cond_destroy(&syscalls->enqueued) != 0) || - (pthread_cond_destroy(&syscalls->dequeued) != 0)) { - die_perror("pthread_cond_destroy"); + if (((err = pthread_cond_destroy(&syscalls->idle)) != 0) || + ((err = pthread_cond_destroy(&syscalls->enqueued)) != 0) || + ((err = pthread_cond_destroy(&syscalls->dequeued)) != 0)) { + die_strerror("pthread_cond_destroy", err); } memset(syscalls, 0, sizeof(*syscalls)); /* to help catch bugs */ diff --git a/gtests/net/packetdrill/wire_server.c b/gtests/net/packetdrill/wire_server.c index 6e722dc791e8b5e00544c639b224f2722e7fd69e..c9923f14ca8547aa3e6abe3cbc2eee9ce80cbcb9 100644 --- a/gtests/net/packetdrill/wire_server.c +++ b/gtests/net/packetdrill/wire_server.c @@ -504,12 +504,13 @@ error_done: static void start_wire_server_thread(struct wire_server *wire_server) { - DEBUGP("start_wire_server_thread\n"); - pthread_t thread; /* pthread thread handle */ - if (pthread_create(&thread, NULL, wire_server_thread, - wire_server) != 0) { - die_perror("pthread_create"); + int err; + + DEBUGP("start_wire_server_thread\n"); + if ((err = pthread_create(&thread, NULL, wire_server_thread, + wire_server)) != 0) { + die_strerror("pthread_create", err); } }