Freeciv-3.2: /fast/freeciv/nightly/S3_2/utility/fcbacktrace.c Source File

Freeciv-3.2

Loading...
Searching...
No Matches
fcbacktrace.c
Go to the documentation of this file.
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.
7
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***********************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif /* HAVE_CONFIG_H */
17
18#include "fc_prehdrs.h"
19
20#ifdef HAVE_EXECINFO_H
21#include <execinfo.h>
22#endif
23
24/* utility */
25#include "log.h"
26#include "shared.h"
27
28#include "fcbacktrace.h"
29
30/* We don't want backtrace-spam to testmatic logs */
31#if defined(FREECIV_DEBUG) && defined(HAVE_BACKTRACE) && !defined(FREECIV_TESTMATIC)
32#define BACKTRACE_ACTIVE 1
33#endif
34
35#ifdef BACKTRACE_ACTIVE
36
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
41
42#define MAX_NUM_FRAMES 256
43
44static log_pre_callback_fn previous = NULL;
45
46static void write_backtrace_line(enum log_level level, bool print_from_where,
47 const char *where, const char *msg);
48static void backtrace_log(enum log_level level, bool print_from_where,
49 const char *where, const char *msg);
50#endif /* BACKTRACE_ACTIVE */
51
52/********************************************************************/
55 void backtrace_init(void)
56{
57#ifdef BACKTRACE_ACTIVE
58 previous = log_set_pre_callback(backtrace_log);
59#endif
60}
61
62/********************************************************************/
65 void backtrace_deinit(void)
66{
67#ifdef BACKTRACE_ACTIVE
68 log_pre_callback_fn active;
69
70 active = log_set_pre_callback(previous);
71
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");
77 }
78#endif /* BACKTRACE_ACTIVE */
79}
80
81#ifdef BACKTRACE_ACTIVE
82/********************************************************************/
85static void write_backtrace_line(enum log_level level, bool print_from_where,
86 const char *where, const char *msg)
87{
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);
92 }
93}
94
95/********************************************************************/
98static void backtrace_log(enum log_level level, bool print_from_where,
99 const char *where, const char *msg)
100{
101 if (previous != NULL) {
102 /* Call chained callback first */
103 previous(level, print_from_where, where, msg);
104 }
105
106 if (level <= LOG_ERROR) {
107 backtrace_print(LOG_BACKTRACE);
108 }
109}
110
111#endif /* BACKTRACE_ACTIVE */
112
113/********************************************************************/
116 void backtrace_print(enum log_level level)
117{
118#ifdef BACKTRACE_ACTIVE
119 void *buffer[MAX_NUM_FRAMES];
120 int frames;
121 char **names;
122
123 frames = backtrace(buffer, ARRAY_SIZE(buffer));
124 names = backtrace_symbols(buffer, frames);
125
126 if (names == NULL) {
127 write_backtrace_line(level, FALSE, NULL, "No backtrace");
128 } else {
129 int i;
130
131 write_backtrace_line(level, FALSE, NULL, "Backtrace:");
132
133 for (i = 0; i < MIN(frames, MAX_NUM_FRAMES); i++) {
134 char linestr[256];
135
136 fc_snprintf(linestr, sizeof(linestr), "%5d: %s", i, names[i]);
137
138 write_backtrace_line(level, FALSE, NULL, linestr);
139 }
140
141 free(names);
142 }
143#endif /* BACKTRACE_ACTIVE */
144}
incite_cost
char * incite_cost
Definition comments.c:74
fc_prehdrs.h
backtrace_deinit
void backtrace_deinit(void)
Definition fcbacktrace.c:65
backtrace_init
void backtrace_init(void)
Definition fcbacktrace.c:55
backtrace_print
void backtrace_print(enum log_level level)
Definition fcbacktrace.c:116
fcbacktrace.h
log_set_pre_callback
log_pre_callback_fn log_set_pre_callback(log_pre_callback_fn precallback)
Definition log.c:278
log.h
log_pre_callback_fn
void(* log_pre_callback_fn)(enum log_level, bool print_from_where, const char *where, const char *msg)
Definition log.h:47
log_level
log_level
Definition log.h:28
LOG_ERROR
@ LOG_ERROR
Definition log.h:30
log_error
#define log_error(message,...)
Definition log.h:103
level
struct setting_list * level[OLEVELS_NUM]
Definition settings.c:190
shared.h
ARRAY_SIZE
#define ARRAY_SIZE(x)
Definition shared.h:85
MIN
#define MIN(x, y)
Definition shared.h:55
fc_snprintf
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:974
FALSE
#define FALSE
Definition support.h:47