// 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.
#ifndef KUDU_UTIL_PSTACK_WATCHER_H
#define KUDU_UTIL_PSTACK_WATCHER_H

#include <sys/types.h>

#include <string>
#include <vector>

#include "kudu/gutil/ref_counted.h"
#include "kudu/util/condition_variable.h"
#include "kudu/util/monotime.h"
#include "kudu/util/mutex.h"
#include "kudu/util/status.h"

namespace kudu {

class Thread;

// PstackWatcher is an object which will pstack the current process and print
// the results to stdout.  It does this after a certain timeout has occured.
class PstackWatcher {
 public:

  enum Flags {
    NO_FLAGS = 0,

    // Run 'thread apply all bt full', which is very verbose output
    DUMP_FULL = 1
  };

  // Static method to collect and write stack dump output to stdout of the current
  // process.
  static Status DumpStacks(int flags = NO_FLAGS);

  // Like the above but for any process, not just the current one.
  static Status DumpPidStacks(pid_t pid, int flags = NO_FLAGS);

  // Instantiate a watcher that writes a pstack to stdout after the given
  // timeout expires.
  explicit PstackWatcher(MonoDelta timeout);

  ~PstackWatcher();

  // Shut down the watcher and do not log a pstack.
  // This method is not thread-safe.
  void Shutdown();

  // Test whether the watcher is still running or has shut down.
  // Thread-safe.
  bool IsRunning() const;

  // Wait until the timeout expires and the watcher logs a pstack.
  // Thread-safe.
  void Wait() const;

 private:
  // Test for the existence of the given program in the system path.
  static Status HasProgram(const char* progname);

  // Check whether the system path has 'gdb' and whether it is modern enough
  // for safe stack dump usage.
  static Status HasGoodGdb();

  // Get a stack dump using GDB directly.
  static Status RunGdbStackDump(pid_t pid, int flags);

  // Get a stack dump using the pstack or gstack program.
  static Status RunPstack(const std::string& progname, pid_t pid);

#if defined(__APPLE__)
  // Check whether the system path has 'sample'
  static Status HasGoodSample();

  // Get a stack dump using sample directly.
  static Status RunSampleStackDump(pid_t pid);
#endif

  // Invoke and wait for the stack dump program.
  static Status RunStackDump(const std::vector<std::string>& argv);

  // Run the thread that waits for the specified duration before logging a
  // pstack.
  void Run();

  const MonoDelta timeout_;
  bool running_;
  scoped_refptr<Thread> thread_;
  mutable Mutex lock_;
  mutable ConditionVariable cond_;
};

} // namespace kudu
#endif
