blob: 893440ae6b492bdbed2ee905404f56bf663ee4f1 [file] [log] [blame]
// 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