From e2c0a692474af17232bbc89477b0c2ef654024f6 Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Mon, 17 Dec 2018 18:41:43 +0100 Subject: Add assertions to forker and erl_child_setup --- erts/emulator/sys/unix/erl_child_setup.c | 16 ++++++++++------ erts/emulator/sys/unix/erl_child_setup.h | 1 + erts/emulator/sys/unix/sys_drivers.c | 18 +++++++++++++----- 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/erts/emulator/sys/unix/erl_child_setup.c b/erts/emulator/sys/unix/erl_child_setup.c index 69fc6c2879..f2b2661eb7 100644 --- a/erts/emulator/sys/unix/erl_child_setup.c +++ b/erts/emulator/sys/unix/erl_child_setup.c @@ -92,7 +92,6 @@ static void ABORT(const char* fmt, ...) abort(); } -#ifdef DEBUG void erl_assert_error(const char* expr, const char* func, const char* file, int line) { @@ -102,7 +101,6 @@ erl_assert_error(const char* expr, const char* func, const char* file, int line) fflush(stderr); abort(); } -#endif void sys_sigblock(int sig) { @@ -230,8 +228,9 @@ start_new_child(int pipes[]) ErtsSysForkerProto proto; res = read(pipes[0], &proto, sizeof(proto)); if (res > 0) { - ASSERT(proto.action == ErtsSysForkerProtoAction_Ack); - ASSERT(res == sizeof(proto)); + ERTS_ASSERT(proto.magic_number == FORKER_MAGIC_NUMBER); + ERTS_ASSERT(proto.action == ErtsSysForkerProtoAction_Ack); + ERTS_ASSERT(res == sizeof(proto)); } } while(res < 0 && (errno == EINTR || errno == ERRNO_BLOCK)); @@ -467,6 +466,9 @@ main(int argc, char *argv[]) if (errno == EINTR) continue; DEBUG_PRINT("erl_child_setup failed to read from uds: %d, %d", res, errno); + if (errno != ECONNRESET) { + ABORT("Unexpected read error %d from beam", errno); + } _exit(0); } @@ -476,8 +478,9 @@ main(int argc, char *argv[]) } /* Since we use unix domain sockets and send the entire data in one go we *should* get the entire payload at once. */ - ASSERT(res == sizeof(proto)); - ASSERT(proto.action == ErtsSysForkerProtoAction_Start); + ERTS_ASSERT(res == sizeof(proto)); + ERTS_ASSERT(proto.magic_number == FORKER_MAGIC_NUMBER); + ERTS_ASSERT(proto.action == ErtsSysForkerProtoAction_Start); sys_sigblock(SIGCHLD); @@ -519,6 +522,7 @@ main(int argc, char *argv[]) ABORT("Failed to read from sigchld pipe: %d (%d)", res, errno); } + proto.magic_number = FORKER_MAGIC_NUMBER; proto.u.sigchld.port_id = get_port_id((pid_t)(ibuff[0])); if (proto.u.sigchld.port_id == THE_NON_VALUE) diff --git a/erts/emulator/sys/unix/erl_child_setup.h b/erts/emulator/sys/unix/erl_child_setup.h index 0058b92344..a67675489b 100644 --- a/erts/emulator/sys/unix/erl_child_setup.h +++ b/erts/emulator/sys/unix/erl_child_setup.h @@ -51,6 +51,7 @@ typedef unsigned long long ErtsSysPortId; #endif typedef struct ErtsSysForkerProto_ { + enum { FORKER_MAGIC_NUMBER = 0xbe6affe1 } magic_number; enum { ErtsSysForkerProtoAction_Start, ErtsSysForkerProtoAction_StartAck, diff --git a/erts/emulator/sys/unix/sys_drivers.c b/erts/emulator/sys/unix/sys_drivers.c index 834706d86f..044c43646d 100644 --- a/erts/emulator/sys/unix/sys_drivers.c +++ b/erts/emulator/sys/unix/sys_drivers.c @@ -807,6 +807,7 @@ static ErlDrvData spawn_start(ErlDrvPort port_num, char* name, erts_alloc(ERTS_ALC_T_DRV_CTRL_DATA, sizeof(ErtsSysForkerProto)); memset(proto, 0, sizeof(ErtsSysForkerProto)); + proto->magic_number = FORKER_MAGIC_NUMBER; proto->action = ErtsSysForkerProtoAction_Start; proto->u.start.fds[0] = ofd[0]; proto->u.start.fds[1] = ifd[1]; @@ -839,6 +840,7 @@ static ErlDrvSSizeT spawn_control(ErlDrvData e, unsigned int cmd, char *buf, ErtsSysDriverData *dd = (ErtsSysDriverData*)e; ErtsSysForkerProto *proto = (ErtsSysForkerProto *)buf; + ERTS_ASSERT(proto->magic_number == FORKER_MAGIC_NUMBER); ASSERT(len == sizeof(*proto)); ASSERT(proto->action == ErtsSysForkerProtoAction_SigChld); @@ -1382,7 +1384,8 @@ static void ready_input(ErlDrvData e, ErlDrvEvent ready_fd) return; } - ASSERT(proto.action == ErtsSysForkerProtoAction_Go); + ERTS_ASSERT(proto.magic_number == FORKER_MAGIC_NUMBER); + ERTS_ASSERT(proto.action == ErtsSysForkerProtoAction_Go); dd->pid = proto.u.go.os_pid; if (dd->pid == -1) { @@ -1776,7 +1779,8 @@ static void forker_ready_input(ErlDrvData e, ErlDrvEvent fd) if (res == 0) erts_exit(ERTS_DUMP_EXIT, "erl_child_setup closed\n"); - ASSERT(res == sizeof(*proto)); + ERTS_ASSERT(res == sizeof(*proto)); + ERTS_ASSERT(proto->magic_number == FORKER_MAGIC_NUMBER); #ifdef FORKER_PROTO_START_ACK if (proto->action == ErtsSysForkerProtoAction_StartAck) { @@ -1791,6 +1795,7 @@ static void forker_ready_input(ErlDrvData e, ErlDrvEvent fd) SysIOVec *iov = driver_peekq(port_num, &vlen); ErtsSysForkerProto *proto = (ErtsSysForkerProto *)iov[0].iov_base; + ERTS_ASSERT(proto->magic_number == FORKER_MAGIC_NUMBER); close(proto->u.start.fds[0]); close(proto->u.start.fds[1]); if (proto->u.start.fds[1] != proto->u.start.fds[2]) @@ -1825,12 +1830,13 @@ static void forker_ready_output(ErlDrvData e, ErlDrvEvent fd) int vlen; SysIOVec *iov = driver_peekq(port_num, &vlen); ErtsSysForkerProto *proto = (ErtsSysForkerProto *)iov[0].iov_base; - ASSERT(iov[0].iov_len >= (sizeof(*proto))); + ERTS_ASSERT(iov[0].iov_len >= (sizeof(*proto))); + ERTS_ASSERT(proto->magic_number == FORKER_MAGIC_NUMBER); if (sys_uds_write(forker_fd, (char*)proto, sizeof(*proto), proto->u.start.fds, 3, 0) < 0) { if (errno == ERRNO_BLOCK) return; - erts_exit(ERTS_DUMP_EXIT, "Failed to write to erl_child_setup: %d\n", errno); + erts_exit(ERTS_ABORT_EXIT, "Failed to write to erl_child_setup: %d\n", errno); } #ifndef FORKER_PROTO_START_ACK close(proto->u.start.fds[0]); @@ -1851,6 +1857,8 @@ static ErlDrvSSizeT forker_control(ErlDrvData e, unsigned int cmd, char *buf, ErlDrvPort port_num = (ErlDrvPort)e; int res; + ERTS_ASSERT(proto->magic_number == FORKER_MAGIC_NUMBER); + driver_enq(port_num, buf, len); if (driver_sizeq(port_num) > sizeof(*proto)) { return 0; @@ -1862,7 +1870,7 @@ static ErlDrvSSizeT forker_control(ErlDrvData e, unsigned int cmd, char *buf, driver_select(port_num, forker_fd, ERL_DRV_WRITE|ERL_DRV_USE, 1); return 0; } - erts_exit(ERTS_DUMP_EXIT, "Failed to write to erl_child_setup: %d\n", errno); + erts_exit(ERTS_ABORT_EXIT, "Failed to write to erl_child_setup: %d\n", errno); } #ifndef FORKER_PROTO_START_ACK -- cgit v1.2.3