Mercurial > hg > xemacs-beta
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 |