From 19b53ac3d79c77d2454385365347bff48d2877e1 Mon Sep 17 00:00:00 2001 From: Ilya Verbin <iverbin@gmail.com> Date: Mon, 3 Apr 2023 21:23:46 +0300 Subject: [PATCH] cmake: always define TARGET_OS_* to 0 or 1 There is a system include file TargetConditionals.h on macOS, which defines TARGET_OS_LINUX (and others) to 0 or 1. On the other side, TARGET_OS_LINUX is also defined by trivia/config.h.cmake, but there it has another possible values: undefined or 1. This inconsistency causes issues like #8445, when TARGET_OS_LINUX is defined (to 0) in one file and undefined in another. Let's always define it to 0 or 1. Closes #8445 NO_DOC=bugfix --- .../gh-8445-crash-during-crash-report.md | 4 ++ src/box/module_cache.c | 2 +- src/lib/core/crash.c | 2 +- src/lib/core/crash.h | 2 +- src/lib/core/fio.c | 2 +- src/lib/core/popen.c | 10 ++-- src/lib/core/say.c | 2 +- src/lib/core/sio.c | 2 +- src/main.cc | 6 +-- src/trivia/config.h.cmake | 20 +++---- ...gh_8445_crash_during_crash_report_test.lua | 54 +++++++++++++++++++ 11 files changed, 82 insertions(+), 24 deletions(-) create mode 100644 changelogs/unreleased/gh-8445-crash-during-crash-report.md create mode 100644 test/app-luatest/gh_8445_crash_during_crash_report_test.lua diff --git a/changelogs/unreleased/gh-8445-crash-during-crash-report.md b/changelogs/unreleased/gh-8445-crash-during-crash-report.md new file mode 100644 index 0000000000..7f9ce6c508 --- /dev/null +++ b/changelogs/unreleased/gh-8445-crash-during-crash-report.md @@ -0,0 +1,4 @@ +## bugfix/core + +* Fixed a crash that could happen when preparing a crash report on macOS + (gh-8445). diff --git a/src/box/module_cache.c b/src/box/module_cache.c index 3d9b1883df..bb51623f23 100644 --- a/src/box/module_cache.c +++ b/src/box/module_cache.c @@ -261,7 +261,7 @@ module_attr_fill(struct module_attr *attr, struct stat *st) attr->st_dev = (uint64_t)st->st_dev; attr->st_ino = (uint64_t)st->st_ino; attr->st_size = (uint64_t)st->st_size; -#ifdef TARGET_OS_DARWIN +#if TARGET_OS_DARWIN attr->tv_sec = (uint64_t)st->st_mtimespec.tv_sec; attr->tv_nsec = (uint64_t)st->st_mtimespec.tv_nsec; #else diff --git a/src/lib/core/crash.c b/src/lib/core/crash.c index cd434b8eca..6e324997c9 100644 --- a/src/lib/core/crash.c +++ b/src/lib/core/crash.c @@ -184,7 +184,7 @@ crash_signal_cb(int signo, siginfo_t *siginfo, void *context) crash_callback(cinfo); } else { /* Got a signal while running the handler. */ - fprintf(stderr, "Fatal %d while backtracing", signo); + fprintf(stderr, "Fatal %d while backtracing\n", signo); } /* Try to dump a core */ diff --git a/src/lib/core/crash.h b/src/lib/core/crash.h index 58e14d5f09..255a2d313b 100644 --- a/src/lib/core/crash.h +++ b/src/lib/core/crash.h @@ -13,7 +13,7 @@ extern "C" { #endif /* defined(__cplusplus) */ -#if defined(TARGET_OS_LINUX) && defined(__x86_64__) +#if TARGET_OS_LINUX && defined(__x86_64__) # define HAS_GREG #endif diff --git a/src/lib/core/fio.c b/src/lib/core/fio.c index 4388b9a534..ddaf00972e 100644 --- a/src/lib/core/fio.c +++ b/src/lib/core/fio.c @@ -46,7 +46,7 @@ const char * fio_filename(int fd) { -#ifdef TARGET_OS_LINUX +#if TARGET_OS_LINUX int save_errno = errno; char *proc_path = tt_static_buf(); diff --git a/src/lib/core/popen.c b/src/lib/core/popen.c index 1716edc134..5911be6f9d 100644 --- a/src/lib/core/popen.c +++ b/src/lib/core/popen.c @@ -19,7 +19,7 @@ #include "say.h" #include "tarantool_ev.h" -#ifdef TARGET_OS_DARWIN +#if TARGET_OS_DARWIN # include <sys/ioctl.h> #endif @@ -861,7 +861,7 @@ popen_delete(struct popen_handle *handle) static int make_pipe(int pfd[2]) { -#ifdef TARGET_OS_LINUX +#if TARGET_OS_LINUX if (pipe2(pfd, O_CLOEXEC)) { diag_set(SystemError, "Can't create pipe2"); return -1; @@ -895,7 +895,7 @@ make_pipe(int pfd[2]) static int close_inherited_fds(int *skip_fds, size_t nr_skip_fds) { -# if defined(TARGET_OS_LINUX) +# if TARGET_OS_LINUX static const char path[] = "/proc/self/fd"; # else static const char path[] = "/dev/fd"; @@ -1004,7 +1004,7 @@ signal_reset(void) } } -#ifdef TARGET_OS_DARWIN +#if TARGET_OS_DARWIN /** * Wait until a child process will become a group leader or will * complete. @@ -1312,7 +1312,7 @@ popen_new(struct popen_opts *opts) signal_reset(); if (opts->flags & POPEN_FLAG_SETSID) { -#ifndef TARGET_OS_DARWIN +#if !TARGET_OS_DARWIN if (setsid() == -1) { say_syserror("child: setsid failed"); goto exit_child; diff --git a/src/lib/core/say.c b/src/lib/core/say.c index 1600665282..042a90dab9 100644 --- a/src/lib/core/say.c +++ b/src/lib/core/say.c @@ -451,7 +451,7 @@ log_pipe_init(struct log *log, const char *init_str) diag_set(SystemError, "can't start logger: %s", init_str); return -1; } -#ifndef TARGET_OS_DARWIN +#if !TARGET_OS_DARWIN /* * A courtesy to a DBA who might have * misconfigured the logger option: check whether diff --git a/src/lib/core/sio.c b/src/lib/core/sio.c index 2264742c7c..7fde2d9046 100644 --- a/src/lib/core/sio.c +++ b/src/lib/core/sio.c @@ -128,7 +128,7 @@ sio_option_name(int option) static int sio_listen_backlog() { -#ifdef TARGET_OS_LINUX +#if TARGET_OS_LINUX FILE *proc = fopen("/proc/sys/net/core/somaxconn", "r"); if (proc) { int backlog; diff --git a/src/main.cc b/src/main.cc index a07f892787..6f48982fbd 100644 --- a/src/main.cc +++ b/src/main.cc @@ -47,7 +47,7 @@ #include <locale.h> #include <libgen.h> #include <sysexits.h> -#if defined(TARGET_OS_LINUX) && defined(HAVE_PRCTL_H) +#if TARGET_OS_LINUX && defined(HAVE_PRCTL_H) # include <sys/prctl.h> #endif #include "fiber.h" @@ -398,7 +398,7 @@ load_cfg(void) say_syserror("setrlimit"); exit(EX_OSERR); } -#if defined(TARGET_OS_LINUX) && defined(HAVE_PRCTL_H) +#if TARGET_OS_LINUX && defined(HAVE_PRCTL_H) if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) < 0) { say_syserror("prctl"); exit(EX_OSERR); @@ -415,7 +415,7 @@ load_cfg(void) if (!small_test_feature(SMALL_FEATURE_DONTDUMP)) { static const char strip_msg[] = "'strip_core' is set but unsupported"; -#ifdef TARGET_OS_LINUX +#if TARGET_OS_LINUX /* * Linux is known to support madvise(DONT_DUMP) * feature, thus warn on this platform only. The diff --git a/src/trivia/config.h.cmake b/src/trivia/config.h.cmake index 9d8bbb9129..7c5c79e592 100644 --- a/src/trivia/config.h.cmake +++ b/src/trivia/config.h.cmake @@ -27,16 +27,16 @@ /** \endcond public */ #define PACKAGE "@PACKAGE@" -/* Defined if building for Linux */ -#cmakedefine TARGET_OS_LINUX 1 -/* Defined if building for FreeBSD */ -#cmakedefine TARGET_OS_FREEBSD 1 -/* Defined if building for NetBSD */ -#cmakedefine TARGET_OS_NETBSD 1 -/* Defined if building for Darwin */ -#cmakedefine TARGET_OS_DARWIN 1 - -#ifdef TARGET_OS_DARWIN +/* Defined to 1 if building for Linux, or to 0 otherwise. */ +#cmakedefine01 TARGET_OS_LINUX +/* Defined to 1 if building for FreeBSD, or to 0 otherwise. */ +#cmakedefine01 TARGET_OS_FREEBSD +/* Defined to 1 if building for NetBSD, or to 0 otherwise. */ +#cmakedefine01 TARGET_OS_NETBSD +/* Defined to 1 if building for Darwin, or to 0 otherwise. */ +#cmakedefine01 TARGET_OS_DARWIN + +#if TARGET_OS_DARWIN #define TARANTOOL_LIBEXT "dylib" #else #define TARANTOOL_LIBEXT "so" diff --git a/test/app-luatest/gh_8445_crash_during_crash_report_test.lua b/test/app-luatest/gh_8445_crash_during_crash_report_test.lua new file mode 100644 index 0000000000..ae07fe9584 --- /dev/null +++ b/test/app-luatest/gh_8445_crash_during_crash_report_test.lua @@ -0,0 +1,54 @@ +local t = require('luatest') +local g = t.group('gh-8445') + +g.before_all(function(cg) + -- TODO(gh-8572) + t.skip_if(jit.arch == 'arm64' and jit.os == 'Linux', + 'Disabled on AArch64 Linux due to #8572') + local server = require('luatest.server') + cg.server = server:new({alias = 'gh-8445'}) +end) + +g.after_all(function(cg) + cg.server:drop() +end) + +-- Check that forked Tarantool doesn't crash when preparing a crash report. +g.test_crash_during_crash_report = function(cg) + local ffi = require('ffi') + local popen = require('popen') + + -- Use `cd' and `shell = true' due to lack of cwd option in popen (gh-5633). + local exe = arg[-1] + local dir = cg.server.workdir + local cmd = [[ + cd %s && %s -e "box.cfg{} require('log').info('pid = ' .. box.info.pid)" + ]] + local ph = popen.new({string.format(cmd, dir, exe)}, + {stdout = popen.opts.DEVNULL, + stderr = popen.opts.PIPE, shell = true}) + t.assert(ph) + + -- Wait for box.cfg{} completion. + local output = '' + t.helpers.retrying({}, function() + local chunk = ph:read({stderr = true, timeout = 0.05}) + if chunk ~= nil then + output = output .. chunk + end + t.assert_str_contains(output, "pid = ") + end) + + -- ph:info().pid won't work, because it returns pid of the shell rather than + -- pid of the Tarantool. + local pid = tonumber(string.match(output, "pid = (%d+)")) + t.assert(pid) + ffi.C.kill(pid, popen.signal.SIGILL) + ph:wait() + output = ph:read({stderr = true}) + t.assert_str_contains(output, "Please file a bug") + + -- Check that there were no fatal signals during crash report. + t.assert_not_str_contains(output, "Fatal 11 while backtracing") + ph:close() +end -- GitLab