From b880098d392930039c6f4cb076ef9750d5868791 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Wed, 18 Oct 2023 09:03:48 +0900 Subject: [PATCH] Add SIGUSR1 signal handler Currently, the launchpad-process-pool suddenly gets the SIGUSR1 signal. To debug the reason, the SIGUSR1 signal handler is added. While getting the signal, the launchpad-process-pool prints the sender pid and the backtrace. Change-Id: I842e374b836b83a635722baafa628bea10f072d0 Signed-off-by: Hwankyu Jhun --- src/launchpad-process-pool/signal_manager.cc | 70 ++++++++++++++++++++++++++++ src/launchpad-process-pool/signal_manager.hh | 19 ++++++++ 2 files changed, 89 insertions(+) diff --git a/src/launchpad-process-pool/signal_manager.cc b/src/launchpad-process-pool/signal_manager.cc index 493a75e..51fb638 100644 --- a/src/launchpad-process-pool/signal_manager.cc +++ b/src/launchpad-process-pool/signal_manager.cc @@ -16,10 +16,13 @@ #include "launchpad-process-pool/signal_manager.hh" +#include #include +#include #include #include +#include #include #include #include @@ -126,6 +129,8 @@ void SignalManager::Dispose() { return; _W("BEGIN"); + RestoreSignalAction(SIGUSR2); + RestoreSignalAction(SIGUSR1); #ifndef PRELOAD_ACTIVATE for (int signo = 0; signo < _NSIG; ++signo) signal(signo, SIG_DFL); @@ -174,6 +179,9 @@ void SignalManager::Init() { gc.DoAtFork(); }); + ChangeSignalAction(SIGUSR1); + ChangeSignalAction(SIGUSR2); + disposed_ = false; _W("END"); } @@ -231,4 +239,66 @@ void SignalManager::OnHydraSigchld(pid_t pid, int status) { HandleSigchld(pid, status); } +void SignalManager::ChangeSignalAction(int signo) { + struct sigaction old_action = { 0, }; + struct sigaction action = { 0, }; + sigemptyset(&action.sa_mask); + action.sa_sigaction = UnixSignalHandler; + action.sa_flags = SA_RESTART | SA_SIGINFO; + + int ret = sigaction(signo, &action, &old_action); + if (ret != 0) { + _W("sigaction() is failed. errno(%d)", errno); + return; + } + + sigaction_map_[signo] = std::make_unique(signo, old_action); +} + +void SignalManager::RestoreSignalAction(int signo) { + auto found = sigaction_map_.find(signo); + if (found == sigaction_map_.end()) { + _W("Failed to find signal action. signo(%d)", signo); + return; + } + + auto& signal_action = found->second; + auto old_action = signal_action->GetSigaction(); + sigaction(signo, &old_action, nullptr); + sigaction_map_.erase(found); +} + +void SignalManager::UnixSignalHandler(int signo, siginfo_t* info, void* arg) { +#define BT_BUF_SIZE 128 + sigset_t old_mask; + sigset_t mask; + sigfillset(&mask); + sigprocmask(SIG_BLOCK, &mask, &old_mask); + + _W("[UNIX_SIGNAL_HANDLER] signo: %d", signo); + if (info != nullptr) { + _W("[UNIX_SIGNAL_HANDLER] pid: %d, uid: %u", info->si_pid, info->si_uid); + if (info->si_pid > 0) { + std::ifstream stream("/proc/" + std::to_string(info->si_pid) + + "/cmdline"); + if (stream.is_open()) { + std::string cmdline; + std::getline(stream, cmdline); + stream.close(); + _W("[UNIX_SIGNAL_HANDLER] cmdline: %s", cmdline.c_str()); + } + } + } + + void* buffer[BT_BUF_SIZE]; + int nptrs = backtrace(buffer, BT_BUF_SIZE); + backtrace_symbols_fd(buffer, nptrs, STDERR_FILENO); + + sigprocmask(SIG_SETMASK, &old_mask, nullptr); + raise(signo); + + _W("Raise SIGABRT to make coredump"); + abort(); +} + } // namespace launchpad diff --git a/src/launchpad-process-pool/signal_manager.hh b/src/launchpad-process-pool/signal_manager.hh index 8cd8ffc..66acf22 100644 --- a/src/launchpad-process-pool/signal_manager.hh +++ b/src/launchpad-process-pool/signal_manager.hh @@ -22,6 +22,7 @@ #include #include +#include #include #include @@ -54,6 +55,19 @@ class SignalManager : public SigchldEvent::IEvent, void UnblockSigchld(); private: + class SignalAction { + public: + SignalAction(int signo, struct sigaction action) + : signo_(signo), action_(action) {} + + int GetSigno() const { return signo_; }; + struct sigaction GetSigaction() const { return action_; }; + + private: + int signo_; + struct sigaction action_; + }; + SignalManager() = default; ~SignalManager(); @@ -65,6 +79,10 @@ class SignalManager : public SigchldEvent::IEvent, void OnSigchld(pid_t pid, int status) override; void OnHydraSigchld(pid_t pid, int status) override; + void ChangeSignalAction(int signo); + void RestoreSignalAction(int signo); + static void UnixSignalHandler(int signo, siginfo_t* info, void* arg); + private: bool disposed_ = true; IEvent* listener_ = nullptr; @@ -73,6 +91,7 @@ class SignalManager : public SigchldEvent::IEvent, std::unique_ptr sigchld_event_; std::unique_ptr hydra_sigchld_event_; std::unique_ptr recycle_bin_; + std::unordered_map> sigaction_map_; }; } // namespace launchpad -- 2.7.4