/* Copyright (C) 2021-2024 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "bt-utils.h"
#include "command.h"
#include "cli/cli-cmds.h"
#include "ui.h"
#include "cli/cli-decode.h"

/* See bt-utils.h.  */

void
gdb_internal_backtrace_set_cmd (const char *args, int from_tty,
				cmd_list_element *c)
{
  gdb_assert (c->type == set_cmd);
  gdb_assert (c->var.has_value ());
  gdb_assert (c->var->type () == var_boolean);

#ifndef GDB_PRINT_INTERNAL_BACKTRACE
  if (c->var->get<bool> ())
    {
      c->var->set<bool> (false);
      error (_("support for this feature is not compiled into GDB"));
    }
#endif
}

#ifdef GDB_PRINT_INTERNAL_BACKTRACE
#ifdef GDB_PRINT_INTERNAL_BACKTRACE_USING_LIBBACKTRACE

/* Callback used by libbacktrace if it encounters an error.  */

static void
libbacktrace_error (void *data, const char *errmsg, int errnum)
{
  /* A negative errnum indicates no debug info was available, just
     skip printing a backtrace in this case.  */
  if (errnum < 0)
    return;

  const auto sig_write = [] (const char *msg) -> void
  {
    gdb_stderr->write_async_safe (msg, strlen (msg));
  };

  sig_write ("error creating backtrace: ");
  sig_write (errmsg);
  if (errnum > 0)
    {
      char buf[20];
      snprintf (buf, sizeof (buf), ": %d", errnum);
      buf[sizeof (buf) - 1] = '\0';

      sig_write (buf);
    }
  sig_write ("\n");
}

/* Callback used by libbacktrace to print a single stack frame.  */

static int
libbacktrace_print (void *data, uintptr_t pc, const char *filename,
		    int lineno, const char *function)
{
  const auto sig_write = [] (const char *msg) -> void
  {
    gdb_stderr->write_async_safe (msg, strlen (msg));
  };

  /* Buffer to print addresses and line numbers into.  An 8-byte address
     with '0x' prefix and a null terminator requires 20 characters.  This
     also feels like it should be enough to represent line numbers in most
     files.  We are also careful to ensure we don't overflow this buffer.  */
  char buf[20];

  snprintf (buf, sizeof (buf), "0x%" PRIxPTR " ", pc);
  buf[sizeof (buf) - 1] = '\0';
  sig_write (buf);
  sig_write (function == nullptr ? "???" : function);
  if (filename != nullptr)
    {
      sig_write ("\n\t");
      sig_write (filename);
      sig_write (":");
      snprintf (buf, sizeof (buf), "%d", lineno);
      buf[sizeof (buf) - 1] = '\0';
      sig_write (buf);
    }
  sig_write ("\n");

  return function != nullptr && strcmp (function, "main") == 0;
}

/* Write a backtrace to GDB's stderr in an async safe manner.  This is a
   backtrace of GDB, not any running inferior, and is to be used when GDB
   crashes or hits some other error condition.  */

static void
gdb_internal_backtrace_1 ()
{
  static struct backtrace_state *state = nullptr;

  if (state == nullptr)
    state = backtrace_create_state (nullptr, 0, libbacktrace_error, nullptr);

  backtrace_full (state, 0, libbacktrace_print, libbacktrace_error, nullptr);
}

#elif defined GDB_PRINT_INTERNAL_BACKTRACE_USING_EXECINFO

/* See the comment on previous version of this function.  */

static void
gdb_internal_backtrace_1 ()
{
  const auto sig_write = [] (const char *msg) -> void
  {
    gdb_stderr->write_async_safe (msg, strlen (msg));
  };

  /* Allow up to 25 frames of backtrace.  */
  void *buffer[25];
  int frames = backtrace (buffer, ARRAY_SIZE (buffer));

  backtrace_symbols_fd (buffer, frames, gdb_stderr->fd ());
  if (frames == ARRAY_SIZE (buffer))
    sig_write (_("Backtrace might be incomplete.\n"));
}

#else
#error "unexpected internal backtrace policy"
#endif
#endif /* GDB_PRINT_INTERNAL_BACKTRACE */

/* See bt-utils.h.  */

void
gdb_internal_backtrace ()
{
  if (current_ui == nullptr)
    return;

#ifdef GDB_PRINT_INTERNAL_BACKTRACE
  const auto sig_write = [] (const char *msg) -> void
  {
    gdb_stderr->write_async_safe (msg, strlen (msg));
  };

  sig_write (_("----- Backtrace -----\n"));

  if (gdb_stderr->fd () > -1)
    gdb_internal_backtrace_1 ();
  else
    sig_write (_("Backtrace unavailable\n"));

  sig_write ("---------------------\n");
#endif
}
