diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2020-10-16 12:52:59 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-10-16 12:52:59 +0200 |
commit | ccd90533d668eef7d204d759b92933b884038372 (patch) | |
tree | 5af00e16896ba98ac0114ad2cfd9c865a32dba9c | |
parent | 1e7398e49cada7ab43b79752d8fba9a1b72344a1 (diff) | |
parent | a91728fd900d5c0ef9a0508540802eb86e24ce90 (diff) |
Merge pull request #14919 from vespa-engine/toregge/remove-sigbushandler
Remove search::SigBusHandler.
-rw-r--r-- | searchcore/src/apps/proton/proton.cpp | 3 | ||||
-rw-r--r-- | searchlib/CMakeLists.txt | 1 | ||||
-rw-r--r-- | searchlib/src/tests/util/sigbushandler/.gitignore | 1 | ||||
-rw-r--r-- | searchlib/src/tests/util/sigbushandler/CMakeLists.txt | 9 | ||||
-rw-r--r-- | searchlib/src/tests/util/sigbushandler/sigbushandler_test.cpp | 137 | ||||
-rw-r--r-- | searchlib/src/vespa/searchlib/util/CMakeLists.txt | 1 | ||||
-rw-r--r-- | searchlib/src/vespa/searchlib/util/sigbushandler.cpp | 155 | ||||
-rw-r--r-- | searchlib/src/vespa/searchlib/util/sigbushandler.h | 41 |
8 files changed, 0 insertions, 348 deletions
diff --git a/searchcore/src/apps/proton/proton.cpp b/searchcore/src/apps/proton/proton.cpp index 691a61401de..05e0ea71443 100644 --- a/searchcore/src/apps/proton/proton.cpp +++ b/searchcore/src/apps/proton/proton.cpp @@ -3,7 +3,6 @@ #include <vespa/searchcore/proton/server/proton.h> #include <vespa/storage/storageserver/storagenode.h> #include <vespa/searchlib/util/statefile.h> -#include <vespa/searchlib/util/sigbushandler.h> #include <vespa/searchlib/util/ioerrorhandler.h> #include <vespa/metrics/metricmanager.h> #include <vespa/vespalib/util/signalhandler.h> @@ -167,7 +166,6 @@ App::Main() LOG(debug, "serviceidentity: '%s'", params.serviceidentity.c_str()); LOG(debug, "subscribeTimeout: '%" PRIu64 "'", params.subscribeTimeout); std::unique_ptr<search::StateFile> stateFile; - std::unique_ptr<search::SigBusHandler> sigBusHandler; std::unique_ptr<search::IOErrorHandler> ioErrorHandler; protonUP = std::make_unique<proton::Proton>(params.identity, _argc > 0 ? _argv[0] : "proton", std::chrono::milliseconds(params.subscribeTimeout)); proton::Proton & proton = *protonUP; @@ -185,7 +183,6 @@ App::Main() if (stateIsDown(stateString)) { LOG(error, "proton state string is %s", stateString.c_str()); } - sigBusHandler = std::make_unique<search::SigBusHandler>(stateFile.get()); ioErrorHandler = std::make_unique<search::IOErrorHandler>(stateFile.get()); if ( ! params.serviceidentity.empty()) { proton.getMetricManager().init(params.serviceidentity, proton.getThreadPool()); diff --git a/searchlib/CMakeLists.txt b/searchlib/CMakeLists.txt index 33b78d517a3..10aa5825f3f 100644 --- a/searchlib/CMakeLists.txt +++ b/searchlib/CMakeLists.txt @@ -229,7 +229,6 @@ vespa_define_module( src/tests/util/bufferwriter src/tests/util/ioerrorhandler src/tests/util/searchable_stats - src/tests/util/sigbushandler src/tests/util/slime_output_raw_buf_adapter src/tests/util/statebuf src/tests/util/statefile diff --git a/searchlib/src/tests/util/sigbushandler/.gitignore b/searchlib/src/tests/util/sigbushandler/.gitignore deleted file mode 100644 index ab5a59f3296..00000000000 --- a/searchlib/src/tests/util/sigbushandler/.gitignore +++ /dev/null @@ -1 +0,0 @@ -searchlib_sigbushandler_test_app diff --git a/searchlib/src/tests/util/sigbushandler/CMakeLists.txt b/searchlib/src/tests/util/sigbushandler/CMakeLists.txt deleted file mode 100644 index 31978a5aa75..00000000000 --- a/searchlib/src/tests/util/sigbushandler/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -vespa_add_executable(searchlib_sigbushandler_test_app TEST - SOURCES - sigbushandler_test.cpp - DEPENDS - searchlib_test - searchlib -) -vespa_add_test(NAME searchlib_sigbushandler_test_app COMMAND searchlib_sigbushandler_test_app) diff --git a/searchlib/src/tests/util/sigbushandler/sigbushandler_test.cpp b/searchlib/src/tests/util/sigbushandler/sigbushandler_test.cpp deleted file mode 100644 index e687eff3ca7..00000000000 --- a/searchlib/src/tests/util/sigbushandler/sigbushandler_test.cpp +++ /dev/null @@ -1,137 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include <vespa/vespalib/testkit/testapp.h> -#include <vespa/vespalib/stllike/string.h> -#include <vespa/searchlib/util/statefile.h> -#include <vespa/searchlib/util/sigbushandler.h> -#include <iostream> -#include <fstream> -#include <vespa/searchlib/test/statefile.h> -#include <vespa/searchlib/test/statestring.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/mman.h> - -#include <vespa/log/log.h> -LOG_SETUP("sigbushandler_test"); - -using namespace search::test::statefile; -using namespace search::test::statestring; - -namespace search -{ - -using strvec = std::vector<vespalib::string>; - -namespace -{ - -bool -assertHistory(std::vector<vespalib::string> &exp, - std::vector<vespalib::string> &act) -{ - if (!EXPECT_EQUAL(exp.size(), act.size())) { - return false; - } - for (size_t i = 0; i < exp.size(); ++i) { - if (!EXPECT_EQUAL(exp[i], act[i])) { - return false; - } - } - return true; -} - -} - - -TEST("Test that sigbus handler can be instantated") -{ - StateFile::erase("state"); - StateFile sf("state"); - SigBusHandler sbh(&sf); - EXPECT_FALSE(sbh.fired()); -} - - -TEST("Test that sigbus handler can trap synthetic sigbus") -{ - StateFile::erase("state"); - StateFile sf("state"); - SigBusHandler sbh(&sf); - EXPECT_FALSE(sbh.fired()); - sigjmp_buf sjb; - if (sigsetjmp(sjb, 1) == 0) { - sbh.setUnwind(&sjb); - kill(getpid(), SIGBUS); - LOG_ABORT("Should never get here"); - } - EXPECT_TRUE(sbh.fired()); -#ifdef __APPLE__ - vespalib::string exp_state = "state=down ts=0.0 operation=sigbus errno=0 code=2 addr=0x0000000000000000\n"; -#else - vespalib::string exp_state = "state=down ts=0.0 operation=sigbus errno=0 code=0\n"; -#endif - { - vespalib::string act = readState(sf); - normalizeTimestamp(act); - normalizeAddr(act, nullptr); - EXPECT_EQUAL(exp_state, act); - } - { - strvec exp({exp_state}); - std::vector<vespalib::string> act(readHistory("state.history")); - normalizeTimestamps(act); - normalizeAddrs(act, nullptr); - TEST_DO(assertHistory(exp, act)); - } -} - -TEST("Test that sigbus handler can trap normal sigbus") -{ - StateFile::erase("state"); - StateFile sf("state"); - SigBusHandler sbh(&sf); - EXPECT_FALSE(sbh.fired()); - - int fd = open("mmapfile", O_CREAT | O_TRUNC | O_RDWR, 0644); - assert(fd >= 0); - void *mmapres = mmap(nullptr, 4096, PROT_READ | PROT_WRITE, - MAP_SHARED, fd, 0); - assert(mmapres != nullptr); - assert(mmapres != reinterpret_cast<void *>(-1l)); - char *p = reinterpret_cast<char *>(mmapres) + 42; - volatile char r = 0; - sigjmp_buf sjb; - if (sigsetjmp(sjb, 1) == 0) { - sbh.setUnwind(&sjb); - r = *p; - LOG_ABORT("Should never get here"); - } - EXPECT_TRUE(sbh.fired()); - EXPECT_TRUE(r == '\0'); - { - vespalib::string act = readState(sf); - vespalib::string exp ="state=down ts=0.0 operation=sigbus errno=0 " - "code=2 addr=0x0000000000000000\n"; - normalizeAddr(exp, p); - normalizeTimestamp(act); - EXPECT_EQUAL(exp, act); - } - { - strvec exp({"state=down ts=0.0 operation=sigbus errno=0 code=2 " - "addr=0x0000000000000000\n" }); - normalizeAddrs(exp, p); - std::vector<vespalib::string> act(readHistory("state.history")); - normalizeTimestamps(act); - TEST_DO(assertHistory(exp, act)); - } -} - -} - -TEST_MAIN() -{ - TEST_RUN_ALL(); - search::StateFile::erase("state"); - unlink("mmapfile"); -} diff --git a/searchlib/src/vespa/searchlib/util/CMakeLists.txt b/searchlib/src/vespa/searchlib/util/CMakeLists.txt index 68dee99339f..c28aed83971 100644 --- a/searchlib/src/vespa/searchlib/util/CMakeLists.txt +++ b/searchlib/src/vespa/searchlib/util/CMakeLists.txt @@ -15,7 +15,6 @@ vespa_add_library(searchlib_util OBJECT ioerrorhandler.cpp logutil.cpp rawbuf.cpp - sigbushandler.cpp slime_output_raw_buf_adapter.cpp state_explorer_utils.cpp statebuf.cpp diff --git a/searchlib/src/vespa/searchlib/util/sigbushandler.cpp b/searchlib/src/vespa/searchlib/util/sigbushandler.cpp deleted file mode 100644 index 9d54a45dcc9..00000000000 --- a/searchlib/src/vespa/searchlib/util/sigbushandler.cpp +++ /dev/null @@ -1,155 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include "sigbushandler.h" -#include "statefile.h" -#include "statebuf.h" -#include <unistd.h> -#include <cstring> - -namespace search { - -SigBusHandler *SigBusHandler::_instance = nullptr; - -namespace { - -std::atomic<int> sigBusNesting; - -class TryLockGuard -{ - bool _gotLock; -public: - TryLockGuard() noexcept - : _gotLock(false) - { - int expzero = 0; - _gotLock = sigBusNesting.compare_exchange_strong(expzero, 1); - } - - ~TryLockGuard() noexcept { - if (_gotLock) { - sigBusNesting = 0; - } - } - - bool gotLock() const noexcept { return _gotLock; } -}; - - -/* - * Write string to standard error using only async signal safe methods. - */ -void -mystderr(const char *msg) noexcept -{ - const char *p = msg; - while (*p != '\0') { - ++p; - } - [[maybe_unused]] auto writeRes = write(STDERR_FILENO, msg, static_cast<size_t>(p - msg)); -} - -} - -void -SigBusHandler::trap() -{ - struct sigaction sa; - _instance = this; - memset(&sa, 0, sizeof(sa)); - sa.sa_sigaction = SigBusHandler::forward; - sa.sa_flags = SA_SIGINFO; - sigemptyset(&sa.sa_mask); - sigaddset(&sa.sa_mask, SIGBUS); - sigaction(SIGBUS, &sa, nullptr); - _trapped = true; -} - - -void -SigBusHandler::untrap() -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = SIG_DFL; - sa.sa_flags = 0; - sigemptyset(&sa.sa_mask); - sigaction(SIGBUS, &sa, nullptr); - _trapped = false; - _instance = nullptr; -} - - -void -SigBusHandler::forward(int sig, siginfo_t *si, void *ucv) -{ - _instance->handle(sig, si, ucv); -} - - -void -SigBusHandler::handle(int sig, siginfo_t *si, void *ucv) -{ - (void) sig; - (void) ucv; - - StateBuf sb(_buf, sizeof(_buf)); - bool raced = false; - do { - // Protect against multiple threads. - TryLockGuard guard; - if (!guard.gotLock() || _fired) { - raced = true; - break; - } - sb.appendKey("state") << "down"; - sb.appendTimestamp(); - sb.appendKey("operation") << "sigbus"; - sb.appendKey("errno") << static_cast<long>(si->si_errno); - sb.appendKey("code") << static_cast<long>(si->si_code); - if (si->si_code != 0) { - sb.appendAddr(si->si_addr); - } - sb << '\n'; - // TODO: Report backing store file, for quick diagnostics. - if (_stateFile != nullptr) { - _stateFile->addState(sb.base(), sb.size(), true); - } - _fired = true; - } while (0); - if (raced) { - mystderr("SIGBUS handler call race, ignoring signal\n"); - sleep(5); - return; - } - - if (_unwind != nullptr) { - // Unit test is using siglongjmp based unwinding - sigjmp_buf *unwind = _unwind; - _unwind = nullptr; - untrap(); // Further bus errors will trigger core dump - siglongjmp(*unwind, 1); - } else { - // Normal case, sleep 3 seconds (i.e. allow main thread to detect - // issue and notify cluster controller) before returning and - // likely core dumping. - sleep(3); - untrap(); // Further bus errors will trigger core dump - } -} - - -SigBusHandler::SigBusHandler(StateFile *stateFile) - : _stateFile(stateFile), - _unwind(nullptr), - _trapped(false), - _fired(false) -{ - trap(); -} - -SigBusHandler::~SigBusHandler() -{ - untrap(); -} - -} diff --git a/searchlib/src/vespa/searchlib/util/sigbushandler.h b/searchlib/src/vespa/searchlib/util/sigbushandler.h deleted file mode 100644 index f432c133839..00000000000 --- a/searchlib/src/vespa/searchlib/util/sigbushandler.h +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include <csetjmp> -#include <csignal> - -namespace search { - -class StateFile; - -/* - * Class used to handle SIGBUS signals, which are generated on IO errors - * on backing file for a memory map. - */ -class SigBusHandler -{ - static SigBusHandler *_instance; - StateFile *_stateFile; - sigjmp_buf *_unwind; - bool _trapped; - bool _fired; - char _buf[2048]; - - void trap(); - void untrap(); - static void forward(int sig, siginfo_t *si, void *ucv); - void handle(int sig, siginfo_t *si, void *ucv); -public: - SigBusHandler(StateFile *stateFile); - ~SigBusHandler(); - - bool fired() const { return _fired; } - - /* - * Setup siglongjmp based unwinding, used by unit tests. - */ - void setUnwind(sigjmp_buf *unwind) { _unwind = unwind; } -}; - -} |