Removed silencing of gtk warning logs from gtk3.22-client.
[freeciv.git] / utility / fcbacktrace.c
blobfe5d88864d5a13a4ff182045b7a55990378a3e6b
1 /**********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12 ***********************************************************************/
14 #ifdef HAVE_CONFIG_H
15 #include <fc_config.h>
16 #endif /* HAVE_CONFIG_H */
18 #include "fc_prehdrs.h"
20 #ifdef HAVE_EXECINFO_H
21 #include <execinfo.h>
22 #endif
24 /* utility */
25 #include "log.h"
26 #include "shared.h"
28 #include "fcbacktrace.h"
30 /* We don't want backtrace-spam to testmatic logs */
31 #if defined(DEBUG) && defined(HAVE_BACKTRACE) && !defined(FREECIV_TESTMATIC)
32 #define BACKTRACE_ACTIVE 1
33 #endif
35 #ifdef BACKTRACE_ACTIVE
37 /* We write always in level LOG_NORMAL and not in higher one since those
38 * interact badly with server callback to send error messages to local
39 * client. */
40 #define LOG_BACKTRACE LOG_NORMAL
42 #define MAX_NUM_FRAMES 64
44 static log_pre_callback_fn previous = NULL;
46 static void write_backtrace_line(enum log_level level, bool print_from_where,
47 const char *where, const char *msg);
48 static void backtrace_log(enum log_level level, bool print_from_where,
49 const char *where, const char *msg);
50 #endif /* BACKTRACE_ACTIVE */
52 /************************************************************************
53 Take backtrace log callback to use
54 ************************************************************************/
55 void backtrace_init(void)
57 #ifdef BACKTRACE_ACTIVE
58 previous = log_set_pre_callback(backtrace_log);
59 #endif
62 /************************************************************************
63 Remove backtrace log callback from use
64 ************************************************************************/
65 void backtrace_deinit(void)
67 #ifdef BACKTRACE_ACTIVE
68 log_pre_callback_fn active;
70 active = log_set_pre_callback(previous);
72 if (active != backtrace_log) {
73 /* We were not the active callback!
74 * Restore the active callback and log error */
75 log_set_pre_callback(active);
76 log_error("Backtrace log (pre)callback cannot be removed");
78 #endif /* BACKTRACE_ACTIVE */
81 #ifdef BACKTRACE_ACTIVE
82 /************************************************************************
83 Write one line of backtrace
84 ************************************************************************/
85 static void write_backtrace_line(enum log_level level, bool print_from_where,
86 const char *where, const char *msg)
88 /* Current behavior of this function is to write to chained callback,
89 * nothing more, nothing less. */
90 if (previous != NULL) {
91 previous(level, print_from_where, where, msg);
95 /*****************************************************************************
96 Main backtrace callback called from logging code.
97 *****************************************************************************/
98 static void backtrace_log(enum log_level level, bool print_from_where,
99 const char *where, const char *msg)
101 if (previous != NULL) {
102 /* Call chained callback first */
103 previous(level, print_from_where, where, msg);
106 if (level <= LOG_ERROR) {
107 backtrace_print(LOG_BACKTRACE);
111 #endif /* BACKTRACE_ACTIVE */
113 /*****************************************************************************
114 Print backtrace
115 *****************************************************************************/
116 void backtrace_print(enum log_level level)
118 #ifdef BACKTRACE_ACTIVE
119 void *buffer[MAX_NUM_FRAMES];
120 int frames;
121 char **names;
123 frames = backtrace(buffer, ARRAY_SIZE(buffer));
124 names = backtrace_symbols(buffer, frames);
126 if (names == NULL) {
127 write_backtrace_line(level, FALSE, NULL, "No backtrace");
128 } else {
129 int i;
131 write_backtrace_line(level, FALSE, NULL, "Backtrace:");
133 for (i = 0; i < MIN(frames, MAX_NUM_FRAMES); i++) {
134 char linestr[256];
136 fc_snprintf(linestr, sizeof(linestr), "%5d: %s", i, names[i]);
138 write_backtrace_line(level, FALSE, NULL, linestr);
141 free(names);
143 #endif /* BACKTRACE_ACTIVE */