root/src/simh/backtrace_func.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. error_callback
  2. full_callback
  3. backtrace_handler

   1 /*
   2  * vim: filetype=c:tabstop=4:ai:expandtab
   3  * SPDX-License-Identifier: BSD-2-Clause
   4  * scspell-id: 9722a7c6-3c33-11ed-9dc5-80ee73e9b8e7
   5  *
   6  * -------------------------------------------------------------------------
   7  *
   8  * backtrace_func.c
   9  *
  10  * libbacktrace (https://github.com/ianlancetaylor/libbacktrace) helpers.
  11  *
  12  * -------------------------------------------------------------------------
  13  *
  14  * Copyright (c) 2021-2023 Jeffrey H. Johnson
  15  * Copyright (c) 2022-2024 The DPS8M Development Team
  16  *
  17  * All rights reserved.
  18  *
  19  * Redistribution and use in source and binary forms, with or without
  20  * modification, are permitted provided that the following conditions are
  21  * met:
  22  *
  23  *  *  Redistributions of source code must retain the above copyright
  24  *     notice, this list of conditions and the following disclaimer.
  25  *
  26  *  *  Redistributions in binary form must reproduce the above copyright
  27  *     notice, this list of conditions and the following disclaimer in the
  28  *     documentation and/or other materials provided with the distribution.
  29  *
  30  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  31  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  32  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  33  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  34  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  35  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  36  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  37  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  38  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  39  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  40  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  41  *
  42  * -------------------------------------------------------------------------
  43  */
  44 
  45 #if defined(USE_BACKTRACE)
  46 # if !defined(_INC_BACKTRACE_FUNC)
  47 #  define _INC_BACKTRACE_FUNC
  48 #  if !defined(BACKTRACE_SKIP)
  49 #   define BACKTRACE_SKIP 1
  50 #  endif /* if !defined(BACKTRACE_SKIP) */
  51 
  52 #  include <signal.h>
  53 
  54 static struct backtrace_state *state = NULL;
  55 static volatile long bt_pid;
  56 static int stopbt, function_count, hidden_function_count,
  57            unknown_function_count, backtrace_reported = 0;
  58 
  59 _Noreturn static void
  60 error_callback(void *data, const char *message, int error_number)
     /* [previous][next][first][last][top][bottom][index][help] */
  61 {
  62   sigset_t block; sigset_t block_n;
  63   sigfillset(&block); sigfillset(&block_n);
  64   sigprocmask(SIG_SETMASK, &block, &block_n);
  65   (void)data; (void)error_number;
  66   (void)fprintf(stderr, "\r No backtrace: %s\r\n", message);
  67   (void)fprintf(stderr,
  68     "\r\n***********************************************************\r\n\r\n");
  69   abort();
  70 }
  71 
  72 static int
  73 full_callback(void *data, uintptr_t pc, const char *pathname,
     /* [previous][next][first][last][top][bottom][index][help] */
  74               int line_number, const char *function)
  75 {
  76   (void)data; (void)pc;
  77   function_count++;
  78   if (pathname != NULL || function != NULL || line_number != 0)
  79     {
  80       if (!stopbt)
  81         {
  82           (void)fprintf(stderr, "\r %-.3d: %s()\r\n       %s:%d\r\n",
  83             function_count, function, pathname, line_number);
  84           backtrace_reported++;
  85           int n = strcmp(function, BACKTRACE_MAIN);
  86           if (n == 0)
  87             {
  88               stopbt = 1;
  89             }
  90         }
  91       else
  92         {
  93           return 0;
  94         }
  95     }
  96   else
  97     {
  98       if (function_count > 1)
  99         {
 100           if (!stopbt)
 101             {
 102               (void)fprintf(stderr, "\r %-.3d: ???\r\n", function_count);
 103             }
 104           else
 105             {
 106               hidden_function_count++;
 107             }
 108           unknown_function_count++;
 109         }
 110       else
 111         {
 112           function_count--;
 113         }
 114     }
 115   return 0;
 116 }
 117 
 118 _Noreturn static void
 119 backtrace_handler(int number)
     /* [previous][next][first][last][top][bottom][index][help] */
 120 {
 121   sigset_t block; sigset_t block_n;
 122   sigfillset(&block); sigfillset(&block_n);
 123   sigprocmask(SIG_SETMASK, &block, &block_n);
 124 #  if defined(SIGUSR2)
 125   if (number != SIGUSR2)
 126     {
 127       (void)fprintf(stderr,
 128         "\r\n****** BUG REPORTING **************************************\r\n\r\n");
 129       (void)fprintf(stderr,
 130         " URL: https://gitlab.com/dps8m/dps8m/-/wikis/Bug-Reporting");
 131     }
 132   else
 133     {
 134       (void)fprintf(stderr,
 135         "\r\n****** SIGUSR2 RAISED *************************************\r\n\r\n");
 136       (void)fprintf(stderr,
 137         " SIGUSR2 manually raised or available memory exhausted.");
 138     }
 139 #  endif /* if defined(SIGUSR2) */
 140   (void)fprintf(stderr,
 141     "\r\n\r\n****** FATAL ERROR ****************************************\r\n");
 142   if (bt_pid > 1)
 143     {
 144 #  if defined(SIGUSR2)
 145       if (number == SIGUSR2)
 146         {
 147           (void)fprintf(stderr,
 148                 "\r\n   PID %ld raised SIGUSR2 (signal %d) ... :(\r\n\r\n",
 149                 (long)bt_pid, number);
 150         }
 151       else
 152         {
 153 #  endif /* if defined(SIGUSR2) */
 154           (void)fprintf(stderr,
 155                 "\r\n   PID %ld caught fatal signal %d ... :(\r\n\r\n",
 156                 (long)bt_pid, number);
 157 #  if defined(SIGUSR2)
 158         }
 159 #  endif /* if defined(SIGUSR2) */
 160     }
 161   else
 162     {
 163       (void)fprintf(stderr,
 164               "\r\n   Caught fatal signal %d ... :(\r\n\r\n",
 165               number);
 166     }
 167   backtrace_full(state, BACKTRACE_SKIP, full_callback, error_callback, NULL);
 168   if (backtrace_reported)
 169     {
 170       (void)fprintf(stderr,
 171         "\r        (%d earlier caller%s not shown)\r\n",
 172         hidden_function_count, hidden_function_count > 1 ? "s" : "");
 173     }
 174   (void)fprintf(stderr,
 175     "\r\n***********************************************************\r\n\r\n");
 176 #  if defined(USE_DUMA)
 177   DUMA_CHECKALL();
 178 #  endif /* if defined(USE_DUMA) */
 179   abort();
 180 }
 181 # endif /* if !defined(_INC_BACKTRACE_FUNC) */
 182 #endif /* if defined(USE_BACKTRACE) */

/* [previous][next][first][last][top][bottom][index][help] */