Line data Source code
1 : #include "source/common/watchdog/abort_action.h" 2 : 3 : #include "envoy/thread/thread.h" 4 : 5 : #include "source/common/common/assert.h" 6 : #include "source/common/common/fmt.h" 7 : #include "source/common/common/logger.h" 8 : #include "source/common/protobuf/utility.h" 9 : #include "source/common/thread/terminate_thread.h" 10 : 11 : namespace Envoy { 12 : namespace Watchdog { 13 : namespace { 14 : constexpr uint64_t DefaultWaitDurationMs = 5000; 15 : } // end namespace 16 : 17 : AbortAction::AbortAction(envoy::watchdog::v3::AbortActionConfig& config, 18 : Server::Configuration::GuardDogActionFactoryContext& /*context*/) 19 : : wait_duration_(absl::Milliseconds( 20 0 : PROTOBUF_GET_MS_OR_DEFAULT(config, wait_duration, DefaultWaitDurationMs))) {} 21 : 22 : void AbortAction::run( 23 : envoy::config::bootstrap::v3::Watchdog::WatchdogAction::WatchdogEvent /*event*/, 24 : const std::vector<std::pair<Thread::ThreadId, MonotonicTime>>& thread_last_checkin_pairs, 25 0 : MonotonicTime /*now*/) { 26 : 27 0 : if (thread_last_checkin_pairs.empty()) { 28 0 : ENVOY_LOG_MISC(warn, "Watchdog AbortAction called without any thread."); 29 0 : return; 30 0 : } 31 : 32 : // The following lines of code won't be considered covered by code coverage 33 : // tools since they would run in DEATH tests. 34 0 : const auto& thread_id = thread_last_checkin_pairs[0].first; 35 0 : const std::string tid_string = thread_id.debugString(); 36 0 : ENVOY_LOG_MISC(error, "Watchdog AbortAction terminating thread with tid {}.", tid_string); 37 : 38 0 : if (Thread::terminateThread(thread_id)) { 39 : // Successfully signaled to thread to terminate, sleep for wait_duration. 40 0 : absl::SleepFor(wait_duration_); 41 0 : } else { 42 0 : ENVOY_LOG_MISC(error, "Failed to terminate tid {}", tid_string); 43 0 : } 44 : 45 : // Abort from the action since the signaled thread hasn't yet crashed the process. 46 : // Panicing in the action gives flexibility since it doesn't depend on 47 : // external code to kill the process if the signal fails. 48 0 : PANIC(fmt::format( 49 0 : "Failed to terminate thread with id {}, aborting from Watchdog AbortAction instead.", 50 0 : tid_string)); 51 0 : } 52 : 53 : } // namespace Watchdog 54 : } // namespace Envoy