comparison src/signal.c @ 2518:cc24b630b1d6

[xemacs-hg @ 2005-01-26 10:33:40 by ben] Fix some race conditions in redisplay/signal redisplay.c, redisplay.h, signal.c: Move backtraces to internals manual. Fix some race conditions leading to crashes due to incomplete protection of critical sections. In signal.c, be more aggressive in catching incomplete critical section protection -- we cannot even check for QUIT, *EVER*, in a critical section.
author ben
date Wed, 26 Jan 2005 10:33:42 +0000
parents 3d8143fc88e1
children c2e0c3af5fe3
comparison
equal deleted inserted replaced
2517:9b0afdac688e 2518:cc24b630b1d6
1 /* Handling asynchronous signals. 1 /* Handling asynchronous signals.
2 Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. 2 Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
3 Copyright (C) 1995, 1996, 2001, 2002 Ben Wing. 3 Copyright (C) 1995, 1996, 2001, 2002, 2004 Ben Wing.
4 4
5 This file is part of XEmacs. 5 This file is part of XEmacs.
6 6
7 XEmacs is free software; you can redistribute it and/or modify it 7 XEmacs is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the 8 under the terms of the GNU General Public License as published by the
691 user pressed C-g or Sh-C-g. After this function finishes, Vquit_flag 691 user pressed C-g or Sh-C-g. After this function finishes, Vquit_flag
692 will be Qt for C-g, Qcritical for Sh-C-g, and unchanged otherwise. 692 will be Qt for C-g, Qcritical for Sh-C-g, and unchanged otherwise.
693 The C-g or Sh-C-g is discarded, so it won't be noticed again. 693 The C-g or Sh-C-g is discarded, so it won't be noticed again.
694 */ 694 */
695 695
696
697
696 void 698 void
697 check_quit (void) 699 check_quit (void)
698 { 700 {
699 /* dont_check_for_quit is set in three circumstances:
700
701 (1) when we are in the process of changing the window
702 configuration. The frame might be in an inconsistent state,
703 which will cause assertion failures if we check for QUIT.
704
705 (2) when we are reading events, and want to read the C-g
706 as an event. The normal check for quit will discard the C-g,
707 which would be bad.
708
709 (3) when we're going down with a fatal error. we're most likely
710 in an inconsistent state, and we definitely don't want to be
711 interrupted. */
712
713 /* We should *not* conditionalize on Vinhibit_quit, or
714 critical-quit (Control-Shift-G) won't work right. */
715
716 /* WARNING: Even calling check_quit(), without actually dispatching
717 a quit signal, can result in arbitrary Lisp code getting executed
718 -- at least under Windows. (Not to mention obvious Lisp
719 invocations like asynchronous timer callbacks.) Here's a sample
720 stack trace to demonstrate:
721
722 NTDLL! DbgBreakPoint@0 address 0x77f9eea9
723 assert_failed(const char * 0x012d036c, int 4596, const char * 0x012d0354) line 3478
724 re_match_2_internal(re_pattern_buffer * 0x012d6780, const unsigned char * 0x00000000, int 0, const unsigned char * 0x022f9328, int 34, int 0, re_registers * 0x012d53d0 search_regs, int 34) line 4596 + 41 bytes
725 re_search_2(re_pattern_buffer * 0x012d6780, const char * 0x00000000, int 0, const char * 0x022f9328, int 34, int 0, int 34, re_registers * 0x012d53d0 search_regs, int 34) line 4269 + 37 bytes
726 re_search(re_pattern_buffer * 0x012d6780, const char * 0x022f9328, int 34, int 0, int 34, re_registers * 0x012d53d0 search_regs) line 4031 + 37 bytes
727 string_match_1(long 31222628, long 30282164, long 28377092, buffer * 0x022fde00, int 0) line 413 + 69 bytes
728 Fstring_match(long 31222628, long 30282164, long 28377092, long 28377092) line 436 + 34 bytes
729 Ffuncall(int 3, long * 0x008297f8) line 3488 + 168 bytes
730 execute_optimized_program(const unsigned char * 0x020ddc50, int 6, long * 0x020ddf50) line 744 + 16 bytes
731 funcall_compiled_function(long 34407748, int 1, long * 0x00829aec) line 516 + 53 bytes
732 Ffuncall(int 2, long * 0x00829ae8) line 3523 + 17 bytes
733 execute_optimized_program(const unsigned char * 0x020ddc90, int 4, long * 0x020ddf90) line 744 + 16 bytes
734 funcall_compiled_function(long 34407720, int 1, long * 0x00829e28) line 516 + 53 bytes
735 Ffuncall(int 2, long * 0x00829e24) line 3523 + 17 bytes
736 mapcar1(long 15, long * 0x00829e48, long 34447820, long 34187868) line 2929 + 11 bytes
737 Fmapcar(long 34447820, long 34187868) line 3035 + 21 bytes
738 Ffuncall(int 3, long * 0x00829f20) line 3488 + 93 bytes
739 execute_optimized_program(const unsigned char * 0x020c2b70, int 7, long * 0x020dd010) line 744 + 16 bytes
740 funcall_compiled_function(long 34407580, int 2, long * 0x0082a210) line 516 + 53 bytes
741 Ffuncall(int 3, long * 0x0082a20c) line 3523 + 17 bytes
742 execute_optimized_program(const unsigned char * 0x020cf810, int 6, long * 0x020cfb10) line 744 + 16 bytes
743 funcall_compiled_function(long 34407524, int 0, long * 0x0082a580) line 516 + 53 bytes
744 Ffuncall(int 1, long * 0x0082a57c) line 3523 + 17 bytes
745 run_hook_with_args_in_buffer(buffer * 0x022fde00, int 1, long * 0x0082a57c, int 0) line 3980 + 13 bytes
746 run_hook_with_args(int 1, long * 0x0082a57c, int 0) line 3993 + 23 bytes
747 Frun_hooks(int 1, long * 0x0082a57c) line 3847 + 19 bytes
748 run_hook(long 34447484) line 4094 + 11 bytes
749 unsafe_handle_wm_initmenu_1(frame * 0x01dbb000) line 736 + 11 bytes
750 unsafe_handle_wm_initmenu(long 28377092) line 807 + 11 bytes
751 condition_case_1(long 28377116, long (long)* 0x0101c827 unsafe_handle_wm_initmenu(long), long 28377092, long (long, long)* 0x01005fa4 mswindows_modal_loop_error_handler(long, long), long 28377092) line 1692 + 7 bytes
752 mswindows_protect_modal_loop(long (long)* 0x0101c827 unsafe_handle_wm_initmenu(long), long 28377092) line 1194 + 32 bytes
753 mswindows_handle_wm_initmenu(HMENU__ * 0x00010199, frame * 0x01dbb000) line 826 + 17 bytes
754 mswindows_wnd_proc(HWND__ * 0x000501da, unsigned int 278, unsigned int 65945, long 0) line 3089 + 31 bytes
755 USER32! UserCallWinProc@20 + 24 bytes
756 USER32! DispatchClientMessage@20 + 47 bytes
757 USER32! __fnDWORD@4 + 34 bytes
758 NTDLL! KiUserCallbackDispatcher@12 + 19 bytes
759 USER32! DispatchClientMessage@20 address 0x77e163cc
760 USER32! DefWindowProcW@16 + 34 bytes
761 qxeDefWindowProc(HWND__ * 0x000501da, unsigned int 274, unsigned int 61696, long 98) line 1188 + 22 bytes
762 mswindows_wnd_proc(HWND__ * 0x000501da, unsigned int 274, unsigned int 61696, long 98) line 3362 + 21 bytes
763 USER32! UserCallWinProc@20 + 24 bytes
764 USER32! DispatchClientMessage@20 + 47 bytes
765 USER32! __fnDWORD@4 + 34 bytes
766 NTDLL! KiUserCallbackDispatcher@12 + 19 bytes
767 USER32! DispatchClientMessage@20 address 0x77e163cc
768 USER32! DefWindowProcW@16 + 34 bytes
769 qxeDefWindowProc(HWND__ * 0x000501da, unsigned int 262, unsigned int 98, long 540016641) line 1188 + 22 bytes
770 mswindows_wnd_proc(HWND__ * 0x000501da, unsigned int 262, unsigned int 98, long 540016641) line 3362 + 21 bytes
771 USER32! UserCallWinProc@20 + 24 bytes
772 USER32! DispatchMessageWorker@8 + 244 bytes
773 USER32! DispatchMessageW@4 + 11 bytes
774 qxeDispatchMessage(const tagMSG * 0x0082c684 {msg=0x00000106 wp=0x00000062 lp=0x20300001}) line 989 + 10 bytes
775 mswindows_drain_windows_queue() line 1345 + 9 bytes
776 emacs_mswindows_quit_p() line 3947
777 event_stream_quit_p() line 666
778 check_quit() line 686
779 check_what_happened() line 437
780 re_match_2_internal(re_pattern_buffer * 0x012d5a18, const unsigned char * 0x00000000, int 0, const unsigned char * 0x02235000, int 23486, int 14645, re_registers * 0x012d53d0 search_regs, int 23486) line 4717 + 14 bytes
781 re_search_2(re_pattern_buffer * 0x012d5a18, const char * 0x02235000, int 23486, const char * 0x0223b38e, int 0, int 14645, int 8841, re_registers * 0x012d53d0 search_regs, int 23486) line 4269 + 37 bytes
782 search_buffer(buffer * 0x022fde00, long 29077572, long 13789, long 23487, long 1, int 1, long 28377092, long 28377092, int 0) line 1224 + 89 bytes
783 search_command(long 29077572, long 46975, long 28377116, long 28377092, long 28377092, int 1, int 1, int 0) line 1054 + 151 bytes
784 Fre_search_forward(long 29077572, long 46975, long 28377116, long 28377092, long 28377092) line 2147 + 31 bytes
785 Ffuncall(int 4, long * 0x0082ceb0) line 3488 + 216 bytes
786 execute_optimized_program(const unsigned char * 0x02047810, int 13, long * 0x02080c10) line 744 + 16 bytes
787 funcall_compiled_function(long 34187208, int 3, long * 0x0082d1b8) line 516 + 53 bytes
788 Ffuncall(int 4, long * 0x0082d1b4) line 3523 + 17 bytes
789 execute_optimized_program(const unsigned char * 0x01e96a10, int 6, long * 0x020ae510) line 744 + 16 bytes
790 funcall_compiled_function(long 34186676, int 3, long * 0x0082d4a0) line 516 + 53 bytes
791 Ffuncall(int 4, long * 0x0082d49c) line 3523 + 17 bytes
792 execute_optimized_program(const unsigned char * 0x02156b50, int 4, long * 0x020c2db0) line 744 + 16 bytes
793 funcall_compiled_function(long 34186564, int 2, long * 0x0082d780) line 516 + 53 bytes
794 Ffuncall(int 3, long * 0x0082d77c) line 3523 + 17 bytes
795 execute_optimized_program(const unsigned char * 0x0082d964, int 3, long * 0x020c2d70) line 744 + 16 bytes
796 Fbyte_code(long 29405156, long 34352480, long 7) line 2392 + 38 bytes
797 Feval(long 34354440) line 3290 + 187 bytes
798 condition_case_1(long 34354572, long (long)* 0x01087232 Feval(long), long 34354440, long (long, long)* 0x01084764 run_condition_case_handlers(long, long), long 28377092) line 1692 + 7 bytes
799 condition_case_3(long 34354440, long 28377092, long 34354572) line 1779 + 27 bytes
800 execute_rare_opcode(long * 0x0082dc7c, const unsigned char * 0x01b090af, int 143) line 1269 + 19 bytes
801 execute_optimized_program(const unsigned char * 0x01b09090, int 6, long * 0x020ae590) line 654 + 17 bytes
802 funcall_compiled_function(long 34186620, int 0, long * 0x0082df68) line 516 + 53 bytes
803 Ffuncall(int 1, long * 0x0082df64) line 3523 + 17 bytes
804 execute_optimized_program(const unsigned char * 0x02195470, int 1, long * 0x020c2df0) line 744 + 16 bytes
805 funcall_compiled_function(long 34186508, int 0, long * 0x0082e23c) line 516 + 53 bytes
806 Ffuncall(int 1, long * 0x0082e238) line 3523 + 17 bytes
807 execute_optimized_program(const unsigned char * 0x01e5d410, int 6, long * 0x0207d410) line 744 + 16 bytes
808 funcall_compiled_function(long 34186312, int 1, long * 0x0082e524) line 516 + 53 bytes
809 Ffuncall(int 2, long * 0x0082e520) line 3523 + 17 bytes
810 execute_optimized_program(const unsigned char * 0x02108fb0, int 2, long * 0x020c2e30) line 744 + 16 bytes
811 funcall_compiled_function(long 34186340, int 0, long * 0x0082e7fc) line 516 + 53 bytes
812 Ffuncall(int 1, long * 0x0082e7f8) line 3523 + 17 bytes
813 execute_optimized_program(const unsigned char * 0x020fe150, int 2, long * 0x01e6f510) line 744 + 16 bytes
814 funcall_compiled_function(long 31008124, int 0, long * 0x0082ebd8) line 516 + 53 bytes
815 Ffuncall(int 1, long * 0x0082ebd4) line 3523 + 17 bytes
816 run_hook_with_args_in_buffer(buffer * 0x022fde00, int 1, long * 0x0082ebd4, int 0) line 3980 + 13 bytes
817 run_hook_with_args(int 1, long * 0x0082ebd4, int 0) line 3993 + 23 bytes
818 Frun_hooks(int 1, long * 0x0082ebd4) line 3847 + 19 bytes
819 Ffuncall(int 2, long * 0x0082ebd0) line 3509 + 14 bytes
820 execute_optimized_program(const unsigned char * 0x01ef2210, int 5, long * 0x01da8e10) line 744 + 16 bytes
821 funcall_compiled_function(long 31020440, int 2, long * 0x0082eeb8) line 516 + 53 bytes
822 Ffuncall(int 3, long * 0x0082eeb4) line 3523 + 17 bytes
823 execute_optimized_program(const unsigned char * 0x0082f09c, int 3, long * 0x01d89390) line 744 + 16 bytes
824 Fbyte_code(long 31102388, long 30970752, long 7) line 2392 + 38 bytes
825 Feval(long 31087568) line 3290 + 187 bytes
826 condition_case_1(long 30961240, long (long)* 0x01087232 Feval(long), long 31087568, long (long, long)* 0x01084764 run_condition_case_handlers(long, long), long 28510180) line 1692 + 7 bytes
827 condition_case_3(long 31087568, long 28510180, long 30961240) line 1779 + 27 bytes
828 execute_rare_opcode(long * 0x0082f450, const unsigned char * 0x01ef23ec, int 143) line 1269 + 19 bytes
829 execute_optimized_program(const unsigned char * 0x01ef2310, int 6, long * 0x01da8f10) line 654 + 17 bytes
830 funcall_compiled_function(long 31020412, int 1, long * 0x0082f740) line 516 + 53 bytes
831 Ffuncall(int 2, long * 0x0082f73c) line 3523 + 17 bytes
832 execute_optimized_program(const unsigned char * 0x020fe650, int 3, long * 0x01d8c490) line 744 + 16 bytes
833 funcall_compiled_function(long 31020020, int 2, long * 0x0082fa14) line 516 + 53 bytes
834 Ffuncall(int 3, long * 0x0082fa10) line 3523 + 17 bytes
835 Fcall_interactively(long 29685180, long 28377092, long 28377092) line 1008 + 22 bytes
836 Fcommand_execute(long 29685180, long 28377092, long 28377092) line 2929 + 17 bytes
837 execute_command_event(command_builder * 0x01be1900, long 36626492) line 4048 + 25 bytes
838 Fdispatch_event(long 36626492) line 4341 + 70 bytes
839 Fcommand_loop_1() line 582 + 9 bytes
840 command_loop_1(long 28377092) line 495
841 condition_case_1(long 28377188, long (long)* 0x01064fb9 command_loop_1(long), long 28377092, long (long, long)* 0x010649d0 cmd_error(long, long), long 28377092) line 1692 + 7 bytes
842 command_loop_3() line 256 + 35 bytes
843 command_loop_2(long 28377092) line 269
844 internal_catch(long 28457612, long (long)* 0x01064b20 command_loop_2(long), long 28377092, int * volatile 0x00000000) line 1317 + 7 bytes
845 initial_command_loop(long 28377092) line 305 + 25 bytes
846 STACK_TRACE_EYE_CATCHER(int 1, char * * 0x01b63ff0, char * * 0x01ca5300, int 0) line 2501
847 main(int 1, char * * 0x01b63ff0, char * * 0x01ca5300) line 2938
848 XEMACS! mainCRTStartup + 180 bytes
849 _start() line 171
850 KERNEL32! BaseProcessStart@4 + 115547 bytes
851
852 */
853 int specdepth; 701 int specdepth;
854 702
855 if (dont_check_for_quit) 703 if (dont_check_for_quit)
856 return; 704 return;
857 705
858 if (quit_check_signal_happened) 706 if (quit_check_signal_happened)
859 { 707 {
860 #ifdef ERROR_CHECK_TRAPPING_PROBLEMS 708 #ifdef ERROR_CHECK_TRAPPING_PROBLEMS
861 /* Since the code below can call Lisp, make sure that proper wrapping is 709 /* Since the code below can call Lisp, make sure that proper wrapping is
862 in place during redisplay. */ 710 in place during redisplay. */
711 #if 0
863 assert_with_message 712 assert_with_message
864 (proper_redisplay_wrapping_in_place (), 713 (proper_redisplay_wrapping_in_place (),
865 "QUIT called from within redisplay without being properly wrapped"); 714 "QUIT called from within redisplay without being properly wrapped");
866 #endif 715 #else
716 /* FUCKME! It looks like we cannot even check for QUIT, *EVER*, during
717 redisplay. Checking for quit can dispatch events, which can enter
718 redisplay recursively, which can trip on
719
720 Fatal error: assertion failed, file c:\xemacs\build\src\redisplay.c, line 5532,
721 !dy->locked
722
723 Backtrace given in
724
725 (Info-goto-node "(internals)Nasty Bugs due to Reentrancy in Redisplay Structures handling QUIT")
726
727 */
728 assert_with_message
729 (!in_display,
730 "QUIT called from within redisplay without being properly wrapped");
731 #endif /* 0 */
732 #endif /* ERROR_CHECK_TRAPPING_PROBLEMS */
867 733
868 /* Since arbitrary Lisp code may be executed (e.g. through a menu 734 /* Since arbitrary Lisp code may be executed (e.g. through a menu
869 filter, see backtrace directly above), GC might happen, 735 filter, see backtrace directly above), GC might happen,
870 which would majorly fuck a lot of things, e.g. re_match() 736 which would majorly fuck a lot of things, e.g. re_match()
871 [string gets relocated] and lots of other code that's not 737 [string gets relocated] and lots of other code that's not