From: Mathieu Desnoyers Date: Wed, 6 Nov 2013 12:03:10 +0000 (-0500) Subject: Fix: application SIGBUS when starting in parallel with sessiond X-Git-Tag: v2.2.2~1 X-Git-Url: http://git.liburcu.org/?p=lttng-ust.git;a=commitdiff_plain;h=5d32ea4466f42665808fe8cf7ac8b533cb512aee Fix: application SIGBUS when starting in parallel with sessiond There is a race between application startup and sessiond startup, where there is an intermediate state where applications can SIGBUS if they see a zero-sized shm, if the shm has been created, but not ftruncated yet. On the UST side, fix this by ensuring that UST can read the shared memory file descriptor with a read() system call before they try accessing it through a memory map (which triggers the SIGBUS if the access goes beyond the file size). On the sessiond side, another commit needs to ensure that the shared memory is writeable by applications as long as its size is 0, which allow applications to perform ftruncate and extend its size. Fixes #623 Signed-off-by: Mathieu Desnoyers --- diff --git a/liblttng-ust/lttng-ust-comm.c b/liblttng-ust/lttng-ust-comm.c index 1c7584dd..e8c85304 100644 --- a/liblttng-ust/lttng-ust-comm.c +++ b/liblttng-ust/lttng-ust-comm.c @@ -689,6 +689,30 @@ int get_wait_shm(struct sock_info *sock_info, size_t mmap_size) */ wait_shm_fd = shm_open(sock_info->wait_shm_path, O_RDONLY, 0); if (wait_shm_fd >= 0) { + int32_t tmp_read; + ssize_t len; + size_t bytes_read = 0; + + /* + * Try to read the fd. If unable to do so, try opening + * it in write mode. + */ + do { + len = read(wait_shm_fd, + &((char *) &tmp_read)[bytes_read], + sizeof(tmp_read) - bytes_read); + if (len > 0) { + bytes_read += len; + } + } while ((len < 0 && errno == EINTR) + || (len > 0 && bytes_read < sizeof(tmp_read))); + if (bytes_read != sizeof(tmp_read)) { + ret = close(wait_shm_fd); + if (ret) { + ERR("close wait_shm_fd"); + } + goto open_write; + } goto end; } else if (wait_shm_fd < 0 && errno != ENOENT) { /* @@ -699,9 +723,11 @@ int get_wait_shm(struct sock_info *sock_info, size_t mmap_size) ERR("Error opening shm %s", sock_info->wait_shm_path); goto end; } + +open_write: /* - * If the open failed because the file did not exist, try - * creating it ourself. + * If the open failed because the file did not exist, or because + * the file was not truncated yet, try creating it ourself. */ URCU_TLS(lttng_ust_nest_count)++; pid = fork();