| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| |
| #pragma once |
| |
| #include <atomic> |
| #include <memory> |
| #include <string> |
| |
| #include "kudu/gutil/ref_counted.h" |
| |
| namespace google_breakpad { |
| class ExceptionHandler; |
| } // namespace google_breakpad |
| |
| namespace kudu { |
| |
| class Env; |
| class Status; |
| class Thread; |
| |
| // While an instance of this class is in scope, a Breakpad minidump handler |
| // will generate a minidump for the current program if it crashes or if it |
| // received a USR1 signal. This class must be instantiated after initializing |
| // the gflags library. When used in conjuction with glog, or other signal |
| // handling facilities, this class must be invoked after installing those |
| // signal handlers. |
| // |
| // The BlockSigUSR1() function should be called before spawning any threads in |
| // order to block the USR1 signal from crashing the process. This class relies |
| // on that signal being blocked by all threads in order to safely generate |
| // minidumps in response to the USR1 signal. |
| // |
| // Only one instance of this class may be instantiated at a time. |
| // |
| // For more information on Google Breakpad, see its documentation at: |
| // http://chromium.googlesource.com/breakpad/breakpad/+/master/docs/getting_started_with_breakpad.md |
| class MinidumpExceptionHandler { |
| public: |
| MinidumpExceptionHandler(); |
| ~MinidumpExceptionHandler(); |
| |
| // Write a minidump immediately. Can be used to generate a minidump |
| // independently of a crash. Should not be called from a signal handler or a |
| // crash context because it uses the heap. |
| bool WriteMinidump(); |
| |
| // Deletes excess minidump files beyond the configured max of |
| // 'FLAGS_max_minidumps'. Uses the file's modified time to determine recency. |
| // Does nothing if 'FLAGS_enabled_minidumps' is false. |
| Status DeleteExcessMinidumpFiles(Env* env); |
| |
| // Get the path to the directory that will be used for writing minidumps. |
| std::string minidump_dir() const; |
| |
| private: |
| Status InitMinidumpExceptionHandler(); |
| Status RegisterMinidumpExceptionHandler(); |
| void UnregisterMinidumpExceptionHandler(); |
| |
| Status StartUserSignalHandlerThread(); |
| void StopUserSignalHandlerThread(); |
| void RunUserSignalHandlerThread(); |
| |
| // The number of instnaces of this class that are currently in existence. |
| // We keep this counter in order to force a crash if more than one is running |
| // at a time, as a sanity check. |
| static std::atomic<int> current_num_instances_; |
| |
| #ifndef __APPLE__ |
| std::atomic<bool> user_signal_handler_thread_running_;// Unused in macOS build. |
| #endif |
| |
| scoped_refptr<Thread> user_signal_handler_thread_; |
| |
| // Breakpad ExceptionHandler. It registers its own signal handlers to write |
| // minidump files during process crashes, but can also be used to write |
| // minidumps directly. |
| std::unique_ptr<google_breakpad::ExceptionHandler> breakpad_handler_; |
| |
| // Directory in which we store our minidumps. |
| std::string minidump_dir_; |
| }; |
| |
| // Block SIGUSR1 from threads handling it. |
| // This should be called by the process before spawning any threads so that a |
| // USR1 signal will cause a minidump to be generated instead of a crash. |
| Status BlockSigUSR1(); |
| |
| } // namespace kudu |