diff options
| author | Joakim Verona | 2012-09-10 16:03:53 +0200 |
|---|---|---|
| committer | Joakim Verona | 2012-09-10 16:03:53 +0200 |
| commit | b035a30e5cd2f34fedc04c253eeb5a11afed8145 (patch) | |
| tree | b9350cce389602f4967bdc1beed745929155ad5d /src/emacs.c | |
| parent | 4a37733c693d59a9b83a3fb2d0c7f9461d149f60 (diff) | |
| parent | a31a4cdacb196cc96dcb9bd229edb1d635e01344 (diff) | |
| download | emacs-b035a30e5cd2f34fedc04c253eeb5a11afed8145.tar.gz emacs-b035a30e5cd2f34fedc04c253eeb5a11afed8145.zip | |
upstream
Diffstat (limited to 'src/emacs.c')
| -rw-r--r-- | src/emacs.c | 153 |
1 files changed, 81 insertions, 72 deletions
diff --git a/src/emacs.c b/src/emacs.c index b454e2423fb..d0e2f1e021d 100644 --- a/src/emacs.c +++ b/src/emacs.c | |||
| @@ -20,7 +20,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 20 | 20 | ||
| 21 | 21 | ||
| 22 | #include <config.h> | 22 | #include <config.h> |
| 23 | #include <signal.h> | ||
| 24 | #include <errno.h> | 23 | #include <errno.h> |
| 25 | #include <stdio.h> | 24 | #include <stdio.h> |
| 26 | 25 | ||
| @@ -278,14 +277,6 @@ static int fatal_error_code; | |||
| 278 | /* True if handling a fatal error already. */ | 277 | /* True if handling a fatal error already. */ |
| 279 | bool fatal_error_in_progress; | 278 | bool fatal_error_in_progress; |
| 280 | 279 | ||
| 281 | #ifdef FORWARD_SIGNAL_TO_MAIN_THREAD | ||
| 282 | /* When compiled with GTK and running under Gnome, | ||
| 283 | multiple threads may be created. Keep track of our main | ||
| 284 | thread to make sure signals are delivered to it (see syssignal.h). */ | ||
| 285 | |||
| 286 | pthread_t main_thread; | ||
| 287 | #endif | ||
| 288 | |||
| 289 | #ifdef HAVE_NS | 280 | #ifdef HAVE_NS |
| 290 | /* NS autrelease pool, for memory management. */ | 281 | /* NS autrelease pool, for memory management. */ |
| 291 | static void *ns_pool; | 282 | static void *ns_pool; |
| @@ -294,13 +285,23 @@ static void *ns_pool; | |||
| 294 | 285 | ||
| 295 | 286 | ||
| 296 | /* Handle bus errors, invalid instruction, etc. */ | 287 | /* Handle bus errors, invalid instruction, etc. */ |
| 297 | #ifndef FLOAT_CATCH_SIGILL | 288 | static void |
| 298 | static | 289 | handle_fatal_signal (int sig) |
| 299 | #endif | 290 | { |
| 300 | void | 291 | fatal_error_backtrace (sig, 10); |
| 301 | fatal_error_signal (int sig) | 292 | } |
| 293 | |||
| 294 | static void | ||
| 295 | deliver_fatal_signal (int sig) | ||
| 296 | { | ||
| 297 | handle_on_main_thread (sig, handle_fatal_signal); | ||
| 298 | } | ||
| 299 | |||
| 300 | /* Report a fatal error due to signal SIG, output a backtrace of at | ||
| 301 | most BACKTRACE_LIMIT lines, and exit. */ | ||
| 302 | _Noreturn void | ||
| 303 | fatal_error_backtrace (int sig, int backtrace_limit) | ||
| 302 | { | 304 | { |
| 303 | SIGNAL_THREAD_CHECK (sig); | ||
| 304 | fatal_error_code = sig; | 305 | fatal_error_code = sig; |
| 305 | signal (sig, SIG_DFL); | 306 | signal (sig, SIG_DFL); |
| 306 | 307 | ||
| @@ -315,6 +316,7 @@ fatal_error_signal (int sig) | |||
| 315 | Fkill_emacs (make_number (sig)); | 316 | Fkill_emacs (make_number (sig)); |
| 316 | 317 | ||
| 317 | shut_down_emacs (sig, Qnil); | 318 | shut_down_emacs (sig, Qnil); |
| 319 | emacs_backtrace (backtrace_limit); | ||
| 318 | } | 320 | } |
| 319 | 321 | ||
| 320 | /* Signal the same code; this time it will really be fatal. | 322 | /* Signal the same code; this time it will really be fatal. |
| @@ -322,43 +324,44 @@ fatal_error_signal (int sig) | |||
| 322 | going to send is probably blocked, so we have to unblock it if we | 324 | going to send is probably blocked, so we have to unblock it if we |
| 323 | want to really receive it. */ | 325 | want to really receive it. */ |
| 324 | #ifndef MSDOS | 326 | #ifndef MSDOS |
| 325 | sigunblock (sigmask (fatal_error_code)); | 327 | { |
| 328 | sigset_t unblocked; | ||
| 329 | sigemptyset (&unblocked); | ||
| 330 | sigaddset (&unblocked, fatal_error_code); | ||
| 331 | pthread_sigmask (SIG_UNBLOCK, &unblocked, 0); | ||
| 332 | } | ||
| 326 | #endif | 333 | #endif |
| 327 | 334 | ||
| 328 | kill (getpid (), fatal_error_code); | 335 | kill (getpid (), fatal_error_code); |
| 336 | |||
| 337 | /* This shouldn't be executed, but it prevents a warning. */ | ||
| 338 | exit (1); | ||
| 329 | } | 339 | } |
| 330 | 340 | ||
| 331 | #ifdef SIGDANGER | 341 | #ifdef SIGDANGER |
| 332 | 342 | ||
| 333 | /* Handler for SIGDANGER. */ | 343 | /* Handler for SIGDANGER. */ |
| 334 | void | 344 | static void deliver_danger_signal (int); |
| 335 | memory_warning_signal (int sig) | 345 | |
| 346 | static void | ||
| 347 | handle_danger_signal (int sig) | ||
| 336 | { | 348 | { |
| 337 | signal (sig, memory_warning_signal); | 349 | struct sigaction action; |
| 338 | SIGNAL_THREAD_CHECK (sig); | 350 | emacs_sigaction_init (&action, deliver_danger_signal); |
| 351 | sigaction (sig, &action, 0); | ||
| 339 | 352 | ||
| 340 | malloc_warning ("Operating system warns that virtual memory is running low.\n"); | 353 | malloc_warning ("Operating system warns that virtual memory is running low.\n"); |
| 341 | 354 | ||
| 342 | /* It might be unsafe to call do_auto_save now. */ | 355 | /* It might be unsafe to call do_auto_save now. */ |
| 343 | force_auto_save_soon (); | 356 | force_auto_save_soon (); |
| 344 | } | 357 | } |
| 345 | #endif | ||
| 346 | 358 | ||
| 347 | /* We define abort, rather than using it from the library, | 359 | static void |
| 348 | so that GDB can return from a breakpoint here. | 360 | deliver_danger_signal (int sig) |
| 349 | MSDOS has its own definition in msdos.c. */ | ||
| 350 | |||
| 351 | #if ! defined (DOS_NT) && ! defined (NO_ABORT) | ||
| 352 | |||
| 353 | void | ||
| 354 | abort (void) | ||
| 355 | { | 361 | { |
| 356 | kill (getpid (), SIGABRT); | 362 | handle_on_main_thread (sig, handle_danger_signal); |
| 357 | /* This shouldn't be executed, but it prevents a warning. */ | ||
| 358 | exit (1); | ||
| 359 | } | 363 | } |
| 360 | #endif | 364 | #endif |
| 361 | |||
| 362 | 365 | ||
| 363 | /* Code for dealing with Lisp access to the Unix command line. */ | 366 | /* Code for dealing with Lisp access to the Unix command line. */ |
| 364 | 367 | ||
| @@ -690,6 +693,7 @@ main (int argc, char **argv) | |||
| 690 | char dname_arg2[80]; | 693 | char dname_arg2[80]; |
| 691 | #endif | 694 | #endif |
| 692 | char *ch_to_dir; | 695 | char *ch_to_dir; |
| 696 | struct sigaction fatal_error_action; | ||
| 693 | 697 | ||
| 694 | #if GC_MARK_STACK | 698 | #if GC_MARK_STACK |
| 695 | stack_base = &dummy; | 699 | stack_base = &dummy; |
| @@ -858,10 +862,6 @@ main (int argc, char **argv) | |||
| 858 | # endif /* not SYNC_INPUT */ | 862 | # endif /* not SYNC_INPUT */ |
| 859 | #endif /* not SYSTEM_MALLOC */ | 863 | #endif /* not SYSTEM_MALLOC */ |
| 860 | 864 | ||
| 861 | #ifdef FORWARD_SIGNAL_TO_MAIN_THREAD | ||
| 862 | main_thread = pthread_self (); | ||
| 863 | #endif /* FORWARD_SIGNAL_TO_MAIN_THREAD */ | ||
| 864 | |||
| 865 | #if defined (MSDOS) || defined (WINDOWSNT) | 865 | #if defined (MSDOS) || defined (WINDOWSNT) |
| 866 | /* We do all file input/output as binary files. When we need to translate | 866 | /* We do all file input/output as binary files. When we need to translate |
| 867 | newlines, we do that manually. */ | 867 | newlines, we do that manually. */ |
| @@ -1114,6 +1114,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem | |||
| 1114 | } | 1114 | } |
| 1115 | 1115 | ||
| 1116 | init_signals (); | 1116 | init_signals (); |
| 1117 | emacs_sigaction_init (&fatal_error_action, deliver_fatal_signal); | ||
| 1117 | 1118 | ||
| 1118 | /* Don't catch SIGHUP if dumping. */ | 1119 | /* Don't catch SIGHUP if dumping. */ |
| 1119 | if (1 | 1120 | if (1 |
| @@ -1122,13 +1123,17 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem | |||
| 1122 | #endif | 1123 | #endif |
| 1123 | ) | 1124 | ) |
| 1124 | { | 1125 | { |
| 1125 | sigblock (sigmask (SIGHUP)); | ||
| 1126 | /* In --batch mode, don't catch SIGHUP if already ignored. | 1126 | /* In --batch mode, don't catch SIGHUP if already ignored. |
| 1127 | That makes nohup work. */ | 1127 | That makes nohup work. */ |
| 1128 | if (! noninteractive | 1128 | bool catch_SIGHUP = !noninteractive; |
| 1129 | || signal (SIGHUP, SIG_IGN) != SIG_IGN) | 1129 | if (!catch_SIGHUP) |
| 1130 | signal (SIGHUP, fatal_error_signal); | 1130 | { |
| 1131 | sigunblock (sigmask (SIGHUP)); | 1131 | struct sigaction old_action; |
| 1132 | sigaction (SIGHUP, 0, &old_action); | ||
| 1133 | catch_SIGHUP = old_action.sa_handler != SIG_IGN; | ||
| 1134 | } | ||
| 1135 | if (catch_SIGHUP) | ||
| 1136 | sigaction (SIGHUP, &fatal_error_action, 0); | ||
| 1132 | } | 1137 | } |
| 1133 | 1138 | ||
| 1134 | if ( | 1139 | if ( |
| @@ -1142,9 +1147,9 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem | |||
| 1142 | /* Don't catch these signals in batch mode if dumping. | 1147 | /* Don't catch these signals in batch mode if dumping. |
| 1143 | On some machines, this sets static data that would make | 1148 | On some machines, this sets static data that would make |
| 1144 | signal fail to work right when the dumped Emacs is run. */ | 1149 | signal fail to work right when the dumped Emacs is run. */ |
| 1145 | signal (SIGQUIT, fatal_error_signal); | 1150 | sigaction (SIGQUIT, &fatal_error_action, 0); |
| 1146 | signal (SIGILL, fatal_error_signal); | 1151 | sigaction (SIGILL, &fatal_error_action, 0); |
| 1147 | signal (SIGTRAP, fatal_error_signal); | 1152 | sigaction (SIGTRAP, &fatal_error_action, 0); |
| 1148 | #ifdef SIGUSR1 | 1153 | #ifdef SIGUSR1 |
| 1149 | add_user_signal (SIGUSR1, "sigusr1"); | 1154 | add_user_signal (SIGUSR1, "sigusr1"); |
| 1150 | #endif | 1155 | #endif |
| @@ -1152,68 +1157,73 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem | |||
| 1152 | add_user_signal (SIGUSR2, "sigusr2"); | 1157 | add_user_signal (SIGUSR2, "sigusr2"); |
| 1153 | #endif | 1158 | #endif |
| 1154 | #ifdef SIGABRT | 1159 | #ifdef SIGABRT |
| 1155 | signal (SIGABRT, fatal_error_signal); | 1160 | sigaction (SIGABRT, &fatal_error_action, 0); |
| 1156 | #endif | 1161 | #endif |
| 1157 | #ifdef SIGHWE | 1162 | #ifdef SIGHWE |
| 1158 | signal (SIGHWE, fatal_error_signal); | 1163 | sigaction (SIGHWE, &fatal_error_action, 0); |
| 1159 | #endif | 1164 | #endif |
| 1160 | #ifdef SIGPRE | 1165 | #ifdef SIGPRE |
| 1161 | signal (SIGPRE, fatal_error_signal); | 1166 | sigaction (SIGPRE, &fatal_error_action, 0); |
| 1162 | #endif | 1167 | #endif |
| 1163 | #ifdef SIGORE | 1168 | #ifdef SIGORE |
| 1164 | signal (SIGORE, fatal_error_signal); | 1169 | sigaction (SIGORE, &fatal_error_action, 0); |
| 1165 | #endif | 1170 | #endif |
| 1166 | #ifdef SIGUME | 1171 | #ifdef SIGUME |
| 1167 | signal (SIGUME, fatal_error_signal); | 1172 | sigaction (SIGUME, &fatal_error_action, 0); |
| 1168 | #endif | 1173 | #endif |
| 1169 | #ifdef SIGDLK | 1174 | #ifdef SIGDLK |
| 1170 | signal (SIGDLK, fatal_error_signal); | 1175 | sigaction (SIGDLK, &fatal_error_action, 0); |
| 1171 | #endif | 1176 | #endif |
| 1172 | #ifdef SIGCPULIM | 1177 | #ifdef SIGCPULIM |
| 1173 | signal (SIGCPULIM, fatal_error_signal); | 1178 | sigaction (SIGCPULIM, &fatal_error_action, 0); |
| 1174 | #endif | 1179 | #endif |
| 1175 | #ifdef SIGIOT | 1180 | #ifdef SIGIOT |
| 1176 | /* This is missing on some systems - OS/2, for example. */ | 1181 | /* This is missing on some systems - OS/2, for example. */ |
| 1177 | signal (SIGIOT, fatal_error_signal); | 1182 | sigaction (SIGIOT, &fatal_error_action, 0); |
| 1178 | #endif | 1183 | #endif |
| 1179 | #ifdef SIGEMT | 1184 | #ifdef SIGEMT |
| 1180 | signal (SIGEMT, fatal_error_signal); | 1185 | sigaction (SIGEMT, &fatal_error_action, 0); |
| 1181 | #endif | 1186 | #endif |
| 1182 | signal (SIGFPE, fatal_error_signal); | 1187 | sigaction (SIGFPE, &fatal_error_action, 0); |
| 1183 | #ifdef SIGBUS | 1188 | #ifdef SIGBUS |
| 1184 | signal (SIGBUS, fatal_error_signal); | 1189 | sigaction (SIGBUS, &fatal_error_action, 0); |
| 1185 | #endif | 1190 | #endif |
| 1186 | signal (SIGSEGV, fatal_error_signal); | 1191 | sigaction (SIGSEGV, &fatal_error_action, 0); |
| 1187 | #ifdef SIGSYS | 1192 | #ifdef SIGSYS |
| 1188 | signal (SIGSYS, fatal_error_signal); | 1193 | sigaction (SIGSYS, &fatal_error_action, 0); |
| 1189 | #endif | 1194 | #endif |
| 1190 | /* May need special treatment on MS-Windows. See | 1195 | /* May need special treatment on MS-Windows. See |
| 1191 | http://lists.gnu.org/archive/html/emacs-devel/2010-09/msg01062.html | 1196 | http://lists.gnu.org/archive/html/emacs-devel/2010-09/msg01062.html |
| 1192 | Please update the doc of kill-emacs, kill-emacs-hook, and | 1197 | Please update the doc of kill-emacs, kill-emacs-hook, and |
| 1193 | NEWS if you change this. | 1198 | NEWS if you change this. |
| 1194 | */ | 1199 | */ |
| 1195 | if (noninteractive) signal (SIGINT, fatal_error_signal); | 1200 | if (noninteractive) |
| 1196 | signal (SIGTERM, fatal_error_signal); | 1201 | sigaction (SIGINT, &fatal_error_action, 0); |
| 1202 | sigaction (SIGTERM, &fatal_error_action, 0); | ||
| 1197 | #ifdef SIGXCPU | 1203 | #ifdef SIGXCPU |
| 1198 | signal (SIGXCPU, fatal_error_signal); | 1204 | sigaction (SIGXCPU, &fatal_error_action, 0); |
| 1199 | #endif | 1205 | #endif |
| 1200 | #ifdef SIGXFSZ | 1206 | #ifdef SIGXFSZ |
| 1201 | signal (SIGXFSZ, fatal_error_signal); | 1207 | sigaction (SIGXFSZ, &fatal_error_action, 0); |
| 1202 | #endif /* SIGXFSZ */ | 1208 | #endif /* SIGXFSZ */ |
| 1203 | 1209 | ||
| 1204 | #ifdef SIGDANGER | 1210 | #ifdef SIGDANGER |
| 1205 | /* This just means available memory is getting low. */ | 1211 | /* This just means available memory is getting low. */ |
| 1206 | signal (SIGDANGER, memory_warning_signal); | 1212 | { |
| 1213 | struct sigaction action; | ||
| 1214 | emacs_sigaction_init (&action, deliver_danger_signal); | ||
| 1215 | sigaction (SIGDANGER, &action, 0); | ||
| 1216 | } | ||
| 1207 | #endif | 1217 | #endif |
| 1208 | 1218 | ||
| 1209 | #ifdef AIX | 1219 | #ifdef AIX |
| 1210 | /* 20 is SIGCHLD, 21 is SIGTTIN, 22 is SIGTTOU. */ | 1220 | /* 20 is SIGCHLD, 21 is SIGTTIN, 22 is SIGTTOU. */ |
| 1211 | signal (SIGXCPU, fatal_error_signal); | 1221 | sigaction (SIGXCPU, &fatal_error_action, 0); |
| 1212 | signal (SIGIOINT, fatal_error_signal); | 1222 | sigaction (SIGIOINT, &fatal_error_action, 0); |
| 1213 | signal (SIGGRANT, fatal_error_signal); | 1223 | sigaction (SIGGRANT, &fatal_error_action, 0); |
| 1214 | signal (SIGRETRACT, fatal_error_signal); | 1224 | sigaction (SIGRETRACT, &fatal_error_action, 0); |
| 1215 | signal (SIGSOUND, fatal_error_signal); | 1225 | sigaction (SIGSOUND, &fatal_error_action, 0); |
| 1216 | signal (SIGMSG, fatal_error_signal); | 1226 | sigaction (SIGMSG, &fatal_error_action, 0); |
| 1217 | #endif /* AIX */ | 1227 | #endif /* AIX */ |
| 1218 | } | 1228 | } |
| 1219 | 1229 | ||
| @@ -1583,7 +1593,6 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem | |||
| 1583 | init_fringe (); | 1593 | init_fringe (); |
| 1584 | #endif /* HAVE_WINDOW_SYSTEM */ | 1594 | #endif /* HAVE_WINDOW_SYSTEM */ |
| 1585 | init_macros (); | 1595 | init_macros (); |
| 1586 | init_floatfns (); | ||
| 1587 | init_window (); | 1596 | init_window (); |
| 1588 | init_font (); | 1597 | init_font (); |
| 1589 | 1598 | ||
| @@ -1898,7 +1907,7 @@ sort_args (int argc, char **argv) | |||
| 1898 | } | 1907 | } |
| 1899 | 1908 | ||
| 1900 | if (best < 0) | 1909 | if (best < 0) |
| 1901 | abort (); | 1910 | emacs_abort (); |
| 1902 | 1911 | ||
| 1903 | /* Copy the highest priority remaining option, with its args, to NEW. | 1912 | /* Copy the highest priority remaining option, with its args, to NEW. |
| 1904 | Unless it is a duplicate of the previous one. */ | 1913 | Unless it is a duplicate of the previous one. */ |
| @@ -2014,7 +2023,7 @@ shut_down_emacs (int sig, Lisp_Object stuff) | |||
| 2014 | { | 2023 | { |
| 2015 | reset_all_sys_modes (); | 2024 | reset_all_sys_modes (); |
| 2016 | if (sig && sig != SIGTERM) | 2025 | if (sig && sig != SIGTERM) |
| 2017 | fprintf (stderr, "Fatal error (%d)", sig); | 2026 | fprintf (stderr, "Fatal error %d: %s", sig, strsignal (sig)); |
| 2018 | } | 2027 | } |
| 2019 | } | 2028 | } |
| 2020 | #else | 2029 | #else |