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-2022 Jeffrey H. Johnson <trnsz@pobox.com>
  15  * Copyright (c) 2022 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 #ifdef USE_BACKTRACE
  46 # ifndef _INC_BACKTRACE_FUNC
  47 #  define _INC_BACKTRACE_FUNC
  48 #  ifndef BACKTRACE_SKIP
  49 #   define BACKTRACE_SKIP 1
  50 #  endif /* ifndef BACKTRACE_SKIP */
  51 
  52 #  include <signal.h>
  53 
  54 struct backtrace_state *state = NULL;
  55 volatile long bt_pid;
  56 int stopbt, function_count, hidden_function_count,
  57     unknown_function_count, backtrace_reported = 0;
  58 
  59 _Noreturn 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 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 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   (void)fprintf(
 125     stderr, "\r\n\r\n****** FATAL ERROR *********************************\r\n");
 126   if (bt_pid > 1)
 127     {
 128 #  ifdef SIGUSR2
 129       if (number == SIGUSR2)
 130         {
 131           (void)fprintf(stderr,
 132                 "\r\n   PID %ld raised SIGUSR2 (signal %d) ... :(\r\n\r\n",
 133                 (long)bt_pid, number);
 134         }
 135       else
 136         {
 137 #  endif /* ifdef SIGUSR2 */
 138           (void)fprintf(stderr,
 139                 "\r\n   PID %ld caught fatal signal %d ... :(\r\n\r\n",
 140                 (long)bt_pid, number);
 141 #  ifdef SIGUSR2
 142         }
 143 #  endif /* ifdef SIGUSR2 */
 144     }
 145   else
 146     {
 147       (void)fprintf(stderr,
 148               "\r\n   Caught fatal signal %d ... :(\r\n\r\n",
 149               number);
 150     }
 151   backtrace_full(state, BACKTRACE_SKIP, full_callback, error_callback, NULL);
 152   if (backtrace_reported)
 153     {
 154       if (hidden_function_count > 1)
 155         {
 156           (void)fprintf(stderr,
 157             "\r        (%d earlier callers not shown)\r\n",
 158             hidden_function_count);
 159         }
 160       if (hidden_function_count == 1)
 161         {
 162           (void)fprintf(stderr,
 163             "\r        (%d earlier caller not shown)\r\n",
 164             hidden_function_count);
 165         }
 166     }
 167 #  ifdef SIGUSR2
 168   if (number != SIGUSR2)
 169     {
 170       (void)fprintf(stderr,
 171         "\r\n****** BUG REPORTING *******************************\r\n\r\n");
 172       (void)fprintf(stderr,
 173         " URL: https://dps8m.gitlab.io/dps8m/Bug_Reporting/\r\n");
 174     }
 175 #  endif /* ifdef SIGUSR2 */
 176   (void)fprintf(stderr,
 177     "\r\n****************************************************\r\n\r\n");
 178 #  ifdef USE_DUMA
 179   DUMA_CHECKALL();
 180 #  endif /* ifdef USE_DUMA */
 181   abort();
 182 }
 183 # endif /* ifndef _INC_BACKTRACE_FUNC */
 184 #endif /* ifdef USE_BACKTRACE */

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