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 0000000000000000000000000000000000000000..7f9ce6c5082d1f963342d38e423154ae13a35c0e --- /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 3d9b1883dfbbb9a8cf59cabb82b2e9d6c03c0fdc..bb51623f238914b81f4c416f2b85f7da09009cc5 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 cd434b8ecaad51c7f24616ec82313875deaefc0c..6e324997c9c3ef8bec0daf6eec934146d9f93fa3 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 58e14d5f09eece56bb5269348e09f35e03e6c8c2..255a2d313bf9c05df8118afbc1d7e681b61827a8 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 4388b9a53480b3fe9b4f5ecea5e2b2418721df44..ddaf00972e7bb9e7b521aa11180b0467b9b7e977 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 1716edc13487fc223f60c68a8d18fc30efb7a49d..5911be6f9d1463a204228ec345b296e1c01aa43a 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 16006652824636d623bd6175e923750c4078a454..042a90dab916eb96a7d9c081d4f900bf4de04ffb 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 2264742c7c71f53e5b05c7ae627b127ccbcb8e18..7fde2d9046fceb9c194638dd6002e5bbb402a30a 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 a07f892787c42b24dcf183127cd2db7890de02ce..6f48982fbdc8e6c8eba38c1355281c8d905728c1 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 9d8bbb91294b9a293f8f82ca9131c8441589309f..7c5c79e592c9500470e8fb9d78ac8c2380793739 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 0000000000000000000000000000000000000000..ae07fe958419f379e31b5d5623912185a1f4ba23 --- /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