3 * Copyright (C) 1997-2014 Adam Williams <broadcast at earthling dot net>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 // debugging functions go here
27 #include "arraylist.h"
28 #include "bcsignals.inc"
34 #define TRON(x) BC_Signals::new_function(x);
35 #define TROFF(x) BC_Signals::delete_function(x);
37 // BC_Signals must be initialized at the start of every program using
39 //#define ENABLE_TRACE
44 //#define TRACE_MEMORY
47 // Need to use structs to avoid the memory manager.
48 // One of these tables is created every time someone locks a lock.
49 // After successfully locking, the table is flagged as being the owner of the lock.
50 // In the unlock function, the table flagged as the owner of the lock is deleted.
63 int (*old_err_handler)(Display *, XErrorEvent *);
64 static int x_error_handler(Display *display, XErrorEvent *event);
73 virtual void signal_handler(int signum);
75 static void dump_stack(FILE *fp=stdout);
79 #define TRACE(text) BC_Signals::new_trace(text);
80 #define SET_TRACE BC_Signals::new_trace(__FILE__, __FUNCTION__, __LINE__);
81 #define PRINT_TRACE { printf("%s: %d\n", __FILE__, __LINE__); fflush(stdout); }
83 #define UNTRACE BC_Signals::delete_traces();
89 #define PRINT_TRACE { printf("%s: %d\n", __FILE__, __LINE__); fflush(stdout); }
90 //#define PRINT_TRACE ;
98 // Before user acquires
99 #define SET_LOCK(ptr, title, location) int table_id = BC_Signals::set_lock(ptr, title, location);
100 // After successful acquisition of a mutex, the table is flagged
101 #define SET_LOCK2 BC_Signals::set_lock2(table_id);
102 // After successful acquisition of a condition, the table is removed because
103 // the user never unlocks a condition after locking it.
104 // Release current lock table after failing to acquire
105 #define UNSET_LOCK2 BC_Signals::unset_lock2(table_id);
107 // Release current owner of lock
108 #define UNSET_LOCK(ptr) BC_Signals::unset_lock(ptr);
111 #define UNSET_ALL_LOCKS(ptr) BC_Signals::unset_all_locks(ptr);
113 #define LOCK_LOCKS(s) BC_Signals::lock_locks(s);
114 #define UNLOCK_LOCKS BC_Signals::unlock_locks();
115 #define CLEAR_LOCKS_TID(tid) BC_Signals::clear_locks_tid(tid);
119 #define SET_LOCK(ptr, title, location) ;
121 #define SET_LOCK2_CONDITION ;
122 #define UNSET_LOCK(ptr) ;
123 #define UNSET_LOCK2 ;
124 #define UNSET_ALL_LOCKS(ptr) ;
126 #define LOCK_LOCKS(s) ;
127 #define UNLOCK_LOCKS ;
128 #define CLEAR_LOCKS_TID(tid) ;
134 #define ENABLE_BUFFER BC_Signals::enable_memory();
135 #define DISABLE_BUFFER BC_Signals::disable_memory();
136 // Note the size, pointer, and location of an allocation
137 #define BUFFER(size, ptr, location) BC_Signals::set_buffer(size, ptr, location);
138 // Note the pointer and location of an allocation
139 #define BUFFER2(ptr, location) BC_Signals::set_buffer(0, ptr, location);
140 // Remove a pointer from the allocation table
141 #define UNBUFFER(ptr) BC_Signals::unset_buffer(ptr);
145 #define ENABLE_BUFFER ;
146 #define DISABLE_BUFFER ;
147 #define BUFFER(size, ptr, location);
148 #define UNBUFFER(ptr);
152 // Handling of temporary files in crash
153 #define SET_TEMP BC_Signals::set_temp
154 #define UNSET_TEMP BC_Signals::unset_temp
156 // Forks need to reset the lock status in case they forked when a lock was held.
157 static void reset_locks();
160 static void delete_temps();
161 static void set_temp(char *string);
162 static void unset_temp(char *string);
163 static void signal_dump(int signum);
166 static void kill_subs();
168 static int set_lock(void *ptr, const char *title, const char *location);
169 static void set_lock2(int table_id);
170 static void set_lock2_condition(int table_id);
171 static void unset_lock2(int table_id);
172 static void unset_lock(void *ptr);
173 // Used in lock destructors so takes away all references
174 static void unset_all_locks(void *ptr);
175 static void clear_locks_tid(pthread_t tid);
177 static void new_trace(const char *text);
178 static void new_trace(const char *file, const char *function, int line);
179 static void delete_traces();
181 static void enable_memory();
182 static void disable_memory();
183 static void set_buffer(int size, void *ptr, const char* location);
184 // This one returns 1 if the buffer wasn't found.
185 static int unset_buffer(void *ptr);
186 static void lock_locks(const char *s);
187 static void unlock_locks();
189 static void dump_traces(FILE *fp=stdout);
190 static void dump_locks(FILE *fp=stdout);
191 static void dump_buffers(FILE *fp=stdout);
192 static void set_sighup_exit(int enable);
194 static void set_trap_path(const char *path);
195 static void set_trap_hook(void (*hook)(FILE *fp, void *data), void *data);
196 static void set_catch_segv(bool v);
197 static void set_catch_intr(bool v);
199 // Convert signum to text
200 static const char* sig_to_str(int number);
202 static BC_Signals *global_signals;
203 static const char *trap_path;
204 static void *trap_data;
205 static void (*trap_hook)(FILE *fp, void *vp);
206 static bool trap_sigsegv, trap_sigintr;