Mercurial > hg > xemacs-beta
comparison src/eval.c @ 1123:37bdd24225ef
[xemacs-hg @ 2002-11-27 07:15:02 by ben]
bug fixes, profiling debugging improvements
configure.in: Check for GCC version and only use -Wpacked in v3.
.cvsignore: Add .idb, .ilk for MS Windows VC++.
cl-macs.el: Document better.
cmdloop.el: Removed.
Remove nonworking breakpoint-on-error now that debug-on-error
works as documented.
help.el: Extract out with-displaying-help-buffer into a more general
mechanism.
lib-complete.el: Support thunks in find-library-source-path.
startup.el: Don't catch errors when noninteractive, because that makes
stack traces from stack-trace-on-error useless.
.cvsignore: Windows shit.
alloc.c: Better redisplay-related assert.
elhash.c: Comment change.
eval.c: Don't generate large warning strings (e.g. backtraces) when they will
be discarded.
Implement debug-on-error as documented -- it will enter the
debugger and crash when an uncaught signal happens noninteractively
and we are --debug.
Better redisplay-related asserts.
frame-msw.c, frame.c, lisp.h, redisplay.c, scrollbar-gtk.c, scrollbar-x.c, signal.c, sysdep.c: Fix up documentation related to QUIT (which CANNOT garbage-collect
under any circumstances), and to redisplay critical sections.
lread.c: Add load-ignore-out-of-date-elc-files,
load-always-display-messages, load-show-full-path-in-messages for
more robust package compilation and debugging.
profile.c: Overhaul profile code. Change format to include call count and be
extensible for further info. Remove call-count-profile-table.
Add set-profiling-info. See related profile.el changes (which
SHOULD ABSOLUTELY be in the core! Get rid of xemacs-devel and
xemacs-base packages *yesterday*!).
author | ben |
---|---|
date | Wed, 27 Nov 2002 07:15:36 +0000 |
parents | 184461bc8de4 |
children | ccd0667b4764 |
comparison
equal
deleted
inserted
replaced
1122:7abc2b15a990 | 1123:37bdd24225ef |
---|---|
411 #ifdef DEFEND_AGAINST_THROW_RECURSION | 411 #ifdef DEFEND_AGAINST_THROW_RECURSION |
412 /* Used for error catching purposes by throw_or_bomb_out */ | 412 /* Used for error catching purposes by throw_or_bomb_out */ |
413 static int throw_level; | 413 static int throw_level; |
414 #endif | 414 #endif |
415 | 415 |
416 static int warning_will_be_discarded (Lisp_Object level); | |
417 static void check_proper_critical_section_nonlocal_exit_protection (void); | |
418 | |
416 | 419 |
417 /************************************************************************/ | 420 /************************************************************************/ |
418 /* The subr object type */ | 421 /* The subr object type */ |
419 /************************************************************************/ | 422 /************************************************************************/ |
420 | 423 |
742 ? debug_on_quit | 745 ? debug_on_quit |
743 : wants_debugger (Vdebug_on_error, conditions)) | 746 : wants_debugger (Vdebug_on_error, conditions)) |
744 && !skip_debugger (conditions, temp_data)) | 747 && !skip_debugger (conditions, temp_data)) |
745 { | 748 { |
746 debug_on_quit &= ~2; /* reset critical bit */ | 749 debug_on_quit &= ~2; /* reset critical bit */ |
750 | |
751 #ifdef DEBUG_XEMACS | |
752 if (noninteractive) | |
753 Fforce_debugging_signal (Qt); | |
754 #endif | |
755 | |
747 specbind (Qdebug_on_error, Qnil); | 756 specbind (Qdebug_on_error, Qnil); |
748 specbind (Qstack_trace_on_error, Qnil); | 757 specbind (Qstack_trace_on_error, Qnil); |
749 specbind (Qdebug_on_signal, Qnil); | 758 specbind (Qdebug_on_signal, Qnil); |
750 specbind (Qstack_trace_on_signal, Qnil); | 759 specbind (Qstack_trace_on_signal, Qnil); |
751 | 760 |
777 && (EQ (sig, Qquit) | 786 && (EQ (sig, Qquit) |
778 ? debug_on_quit | 787 ? debug_on_quit |
779 : wants_debugger (Vdebug_on_signal, conditions))) | 788 : wants_debugger (Vdebug_on_signal, conditions))) |
780 { | 789 { |
781 debug_on_quit &= ~2; /* reset critical bit */ | 790 debug_on_quit &= ~2; /* reset critical bit */ |
791 | |
792 #ifdef DEBUG_XEMACS | |
793 if (noninteractive) | |
794 Fforce_debugging_signal (Qt); | |
795 #endif | |
796 | |
782 specbind (Qdebug_on_error, Qnil); | 797 specbind (Qdebug_on_error, Qnil); |
783 specbind (Qstack_trace_on_error, Qnil); | 798 specbind (Qstack_trace_on_error, Qnil); |
784 specbind (Qdebug_on_signal, Qnil); | 799 specbind (Qdebug_on_signal, Qnil); |
785 specbind (Qstack_trace_on_signal, Qnil); | 800 specbind (Qstack_trace_on_signal, Qnil); |
786 | 801 |
1590 /* die if we recurse more than is reasonable */ | 1605 /* die if we recurse more than is reasonable */ |
1591 if (++throw_level > 20) | 1606 if (++throw_level > 20) |
1592 abort (); | 1607 abort (); |
1593 #endif | 1608 #endif |
1594 | 1609 |
1610 check_proper_critical_section_nonlocal_exit_protection (); | |
1611 | |
1595 /* If bomb_out_p is t, this is being called from Fsignal as a | 1612 /* If bomb_out_p is t, this is being called from Fsignal as a |
1596 "last resort" when there is no handler for this error and | 1613 "last resort" when there is no handler for this error and |
1597 the debugger couldn't be invoked, so we are throwing to | 1614 the debugger couldn't be invoked, so we are throwing to |
1598 'top-level. If this tag doesn't exist (happens during the | 1615 'top-level. If this tag doesn't exist (happens during the |
1599 initialization stages) we would get in an infinite recursive | 1616 initialization stages) we would get in an infinite recursive |
2111 Qunbound); | 2128 Qunbound); |
2112 #endif | 2129 #endif |
2113 } | 2130 } |
2114 | 2131 |
2115 extern int in_display; | 2132 extern int in_display; |
2133 extern int gc_currently_forbidden; | |
2116 | 2134 |
2117 | 2135 |
2118 /************************************************************************/ | 2136 /************************************************************************/ |
2119 /* the workhorse error-signaling function */ | 2137 /* the workhorse error-signaling function */ |
2120 /************************************************************************/ | 2138 /************************************************************************/ |
2127 void signal_1 (void); | 2145 void signal_1 (void); |
2128 | 2146 |
2129 void | 2147 void |
2130 signal_1 (void) | 2148 signal_1 (void) |
2131 { | 2149 { |
2150 } | |
2151 | |
2152 static void | |
2153 check_proper_critical_section_gc_protection (void) | |
2154 { | |
2155 assert_with_message | |
2156 (!in_display || gc_currently_forbidden, | |
2157 "Potential GC from within redisplay without being properly wrapped"); | |
2158 } | |
2159 | |
2160 static void | |
2161 check_proper_critical_section_nonlocal_exit_protection (void) | |
2162 { | |
2163 assert_with_message | |
2164 (!in_display | |
2165 || ((get_inhibit_flags () & INTERNAL_INHIBIT_ERRORS) | |
2166 && (get_inhibit_flags () & INTERNAL_INHIBIT_THROWS)), | |
2167 "Attempted non-local exit from within redisplay without being properly wrapped"); | |
2132 } | 2168 } |
2133 | 2169 |
2134 /* #### This function has not been synched with FSF. It diverges | 2170 /* #### This function has not been synched with FSF. It diverges |
2135 significantly. */ | 2171 significantly. */ |
2136 | 2172 |
2179 just to bomb out immediately. */ | 2215 just to bomb out immediately. */ |
2180 stderr_out ("Error before initialization is complete!\n"); | 2216 stderr_out ("Error before initialization is complete!\n"); |
2181 abort (); | 2217 abort (); |
2182 } | 2218 } |
2183 | 2219 |
2184 if (gc_in_progress) | 2220 assert (!gc_in_progress); |
2185 /* We used to abort if in_display: | 2221 |
2186 | 2222 /* We abort if in_display and we are not protected, as garbage |
2187 [[This is one of many reasons why you can't run lisp code from | 2223 collections and non-local exits will invariably be fatal, but in |
2188 redisplay. There is no sensible way to handle errors there.]] | 2224 messy, difficult-to-debug ways. See enter_redisplay_critical_section(). |
2189 | 2225 */ |
2190 The above comment is not correct. | 2226 |
2191 | 2227 check_proper_critical_section_nonlocal_exit_protection (); |
2192 Inhibit GC until the redisplay code is careful enough to properly | |
2193 GCPRO their structures; | |
2194 | |
2195 Surround all calls to Lisp code with error-trapping wrappers that | |
2196 catch all errors. --ben */ | |
2197 abort (); | |
2198 | 2228 |
2199 conditions = Fget (error_symbol, Qerror_conditions, Qnil); | 2229 conditions = Fget (error_symbol, Qerror_conditions, Qnil); |
2200 | 2230 |
2201 for (handlers = Vcondition_handlers; | 2231 for (handlers = Vcondition_handlers; |
2202 CONSP (handlers); | 2232 CONSP (handlers); |
3460 else | 3490 else |
3461 return form; | 3491 return form; |
3462 } | 3492 } |
3463 | 3493 |
3464 QUIT; | 3494 QUIT; |
3495 #ifdef ERROR_CHECK_TRAPPING_PROBLEMS | |
3496 check_proper_critical_section_gc_protection (); | |
3497 #endif | |
3465 if (need_to_garbage_collect) | 3498 if (need_to_garbage_collect) |
3466 { | 3499 { |
3467 struct gcpro gcpro1; | 3500 struct gcpro gcpro1; |
3468 GCPRO1 (form); | 3501 GCPRO1 (form); |
3469 garbage_collect_1 (); | 3502 garbage_collect_1 (); |
3704 | 3737 |
3705 QUIT; | 3738 QUIT; |
3706 | 3739 |
3707 if (funcall_allocation_flag) | 3740 if (funcall_allocation_flag) |
3708 { | 3741 { |
3742 #ifdef ERROR_CHECK_TRAPPING_PROBLEMS | |
3743 check_proper_critical_section_gc_protection (); | |
3744 #endif | |
3709 if (need_to_garbage_collect) | 3745 if (need_to_garbage_collect) |
3710 /* Callers should gcpro lexpr args */ | 3746 /* Callers should gcpro lexpr args */ |
3711 garbage_collect_1 (); | 3747 garbage_collect_1 (); |
3712 if (need_to_check_c_alloca) | 3748 if (need_to_check_c_alloca) |
3713 { | 3749 { |
4748 struct gcpro gcpro1; | 4784 struct gcpro gcpro1; |
4749 Lisp_Object lstream = Qnil; | 4785 Lisp_Object lstream = Qnil; |
4750 Lisp_Object errstr; | 4786 Lisp_Object errstr; |
4751 int speccount = specpdl_depth (); | 4787 int speccount = specpdl_depth (); |
4752 | 4788 |
4753 if (! (inhibit_flags & INHIBIT_WARNING_ISSUE)) | 4789 if (!(inhibit_flags & INHIBIT_WARNING_ISSUE) |
4790 && !warning_will_be_discarded (current_warning_level ())) | |
4754 { | 4791 { |
4755 /* We're no longer protected against errors or quit here, so at | 4792 /* We're no longer protected against errors or quit here, so at |
4756 least let's temporarily inhibit quit. We definitely do not | 4793 least let's temporarily inhibit quit. We definitely do not |
4757 want to inhibit quit during the calling of the function | 4794 want to inhibit quit during the calling of the function |
4758 itself!!!!!!!!!!! */ | 4795 itself!!!!!!!!!!! */ |
4779 | 4816 |
4780 warn_when_safe_lispobj (p->warning_class, current_warning_level (), | 4817 warn_when_safe_lispobj (p->warning_class, current_warning_level (), |
4781 errstr); | 4818 errstr); |
4782 | 4819 |
4783 unbind_to (speccount); | 4820 unbind_to (speccount); |
4784 | |
4785 } | 4821 } |
4786 else | 4822 else |
4787 p->backtrace = Qnil; | 4823 p->backtrace = Qnil; |
4788 | 4824 |
4789 p->error_conditions = error_conditions; | 4825 p->error_conditions = error_conditions; |
4845 trapped and reported as an error, unless NO_INHIBIT_ERRORS is | 4881 trapped and reported as an error, unless NO_INHIBIT_ERRORS is |
4846 given.) This is useful when QUIT checking has been turned off by a | 4882 given.) This is useful when QUIT checking has been turned off by a |
4847 higher-level caller. | 4883 higher-level caller. |
4848 | 4884 |
4849 If FLAGS contains INHIBIT_GC, garbage collection is inhibited. | 4885 If FLAGS contains INHIBIT_GC, garbage collection is inhibited. |
4850 This is useful for Lisp called within redisplay or inside of the | 4886 This is useful for Lisp called within redisplay, for example. |
4851 QUIT macro (where GC is generally not expected), for example. | |
4852 | 4887 |
4853 If FLAGS contains INHIBIT_EXISTING_PERMANENT_DISPLAY_OBJECT_DELETION, | 4888 If FLAGS contains INHIBIT_EXISTING_PERMANENT_DISPLAY_OBJECT_DELETION, |
4854 Lisp code is not allowed to delete any window, buffers, frames, devices, | 4889 Lisp code is not allowed to delete any window, buffers, frames, devices, |
4855 or consoles that were already in existence at the time this function | 4890 or consoles that were already in existence at the time this function |
4856 was called. (However, it's perfectly legal for code to create a new | 4891 was called. (However, it's perfectly legal for code to create a new |
5020 else | 5055 else |
5021 /* Nothing special. */ | 5056 /* Nothing special. */ |
5022 tem = (fun) (arg); | 5057 tem = (fun) (arg); |
5023 | 5058 |
5024 if (thrown && !EQ (thrown_tag, package.catchtag) | 5059 if (thrown && !EQ (thrown_tag, package.catchtag) |
5025 && (!flags & INHIBIT_WARNING_ISSUE)) | 5060 && (!flags & INHIBIT_WARNING_ISSUE) |
5061 && !warning_will_be_discarded (current_warning_level ())) | |
5026 { | 5062 { |
5027 Lisp_Object errstr; | 5063 Lisp_Object errstr; |
5028 | 5064 |
5029 if (!(flags & INHIBIT_QUIT)) | 5065 if (!(flags & INHIBIT_QUIT)) |
5030 /* We're no longer protected against errors or quit here, so at | 5066 /* We're no longer protected against errors or quit here, so at |
6184 | 6220 |
6185 /************************************************************************/ | 6221 /************************************************************************/ |
6186 /* Warnings */ | 6222 /* Warnings */ |
6187 /************************************************************************/ | 6223 /************************************************************************/ |
6188 | 6224 |
6225 static int | |
6226 warning_will_be_discarded (Lisp_Object level) | |
6227 { | |
6228 /* Don't even generate debug warnings if they're going to be discarded, | |
6229 to avoid excessive consing. */ | |
6230 return (EQ (level, Qdebug) && !NILP (Vlog_warning_minimum_level) && | |
6231 !EQ (Vlog_warning_minimum_level, Qdebug)); | |
6232 } | |
6233 | |
6189 void | 6234 void |
6190 warn_when_safe_lispobj (Lisp_Object class, Lisp_Object level, | 6235 warn_when_safe_lispobj (Lisp_Object class, Lisp_Object level, |
6191 Lisp_Object obj) | 6236 Lisp_Object obj) |
6192 { | 6237 { |
6193 /* Don't even generate debug warnings if they're going to be discarded, | 6238 if (warning_will_be_discarded (level)) |
6194 to avoid excessive consing. */ | |
6195 if (EQ (level, Qdebug) && !NILP (Vlog_warning_minimum_level) && | |
6196 !EQ (Vlog_warning_minimum_level, Qdebug)) | |
6197 return; | 6239 return; |
6198 | 6240 |
6199 obj = list1 (list3 (class, level, obj)); | 6241 obj = list1 (list3 (class, level, obj)); |
6200 if (NILP (Vpending_warnings)) | 6242 if (NILP (Vpending_warnings)) |
6201 Vpending_warnings = Vpending_warnings_tail = obj; | 6243 Vpending_warnings = Vpending_warnings_tail = obj; |
6202 else | 6244 else |
6203 { | 6245 { |
6217 warn_when_safe (Lisp_Object class, Lisp_Object level, const CIbyte *fmt, ...) | 6259 warn_when_safe (Lisp_Object class, Lisp_Object level, const CIbyte *fmt, ...) |
6218 { | 6260 { |
6219 Lisp_Object obj; | 6261 Lisp_Object obj; |
6220 va_list args; | 6262 va_list args; |
6221 | 6263 |
6222 /* Don't even generate debug warnings if they're going to be discarded, | 6264 if (warning_will_be_discarded (level)) |
6223 to avoid excessive consing. */ | |
6224 if (EQ (level, Qdebug) && !NILP (Vlog_warning_minimum_level) && | |
6225 !EQ (Vlog_warning_minimum_level, Qdebug)) | |
6226 return; | 6265 return; |
6227 | 6266 |
6228 va_start (args, fmt); | 6267 va_start (args, fmt); |
6229 obj = emacs_vsprintf_string (CGETTEXT (fmt), args); | 6268 obj = emacs_vsprintf_string (CGETTEXT (fmt), args); |
6230 va_end (args); | 6269 va_end (args); |
6231 | 6270 |
6232 warn_when_safe_lispobj (class, level, obj); | 6271 warn_when_safe_lispobj (class, level, obj); |
6419 a `condition-case'. | 6458 a `condition-case'. |
6420 If the value is a list, an error only means to enter the debugger | 6459 If the value is a list, an error only means to enter the debugger |
6421 if one of its condition symbols appears in the list. | 6460 if one of its condition symbols appears in the list. |
6422 This variable is overridden by `debug-ignored-errors'. | 6461 This variable is overridden by `debug-ignored-errors'. |
6423 See also variables `debug-on-quit' and `debug-on-signal'. | 6462 See also variables `debug-on-quit' and `debug-on-signal'. |
6424 If this variable is set while XEmacs is running noninteractively, | 6463 |
6425 an unhandled error will cause a backtrace to be output and the C | 6464 If this variable is set while XEmacs is running noninteractively (using |
6426 debugger entered using `force-debugging-signal'. This can be very | 6465 `-batch'), and XEmacs was configured with `--debug' (#define XEMACS_DEBUG |
6427 useful when debugging noninteractive errors in tricky situations, | 6466 in the C code), instead of trying to invoke the Lisp debugger (which |
6428 e.g. makefiles, since you can set this variable using an environment | 6467 obviously won't work), XEmacs will break out to a C debugger using |
6429 variable, like this: | 6468 \(force-debugging-signal t). This is useful because debugging |
6469 noninteractive runs of XEmacs is often very difficult, since they typically | |
6470 happen as part of sometimes large and complex make suites (e.g. rebuilding | |
6471 the XEmacs packages). NOTE: This runs abort()!!! (As well as and after | |
6472 executing INT 3 under MS Windows, which should invoke a debugger if it's | |
6473 active.) This is guaranteed to kill XEmacs! (But in this situation, XEmacs | |
6474 is about to die anyway, and if no debugger is present, this will usefully | |
6475 dump core.) The most useful way to set this flag when debugging | |
6476 noninteractive runs, especially in makefiles, is using the environment | |
6477 variable XEMACSDEBUG, like this: | |
6430 | 6478 |
6431 \(using csh) setenv XEMACSDEBUG '(setq debug-on-error t)' | 6479 \(using csh) setenv XEMACSDEBUG '(setq debug-on-error t)' |
6432 \(using bash) export XEMACSDEBUG='(setq debug-on-error t)' | 6480 \(using bash) export XEMACSDEBUG='(setq debug-on-error t)' |
6433 */ ); | 6481 */ ); |
6434 Vdebug_on_error = Qnil; | 6482 Vdebug_on_error = Qnil; |
6438 The debugger will be entered whether or not the error is handled by | 6486 The debugger will be entered whether or not the error is handled by |
6439 a `condition-case'. | 6487 a `condition-case'. |
6440 If the value is a list, an error only means to enter the debugger | 6488 If the value is a list, an error only means to enter the debugger |
6441 if one of its condition symbols appears in the list. | 6489 if one of its condition symbols appears in the list. |
6442 See also variable `debug-on-quit'. | 6490 See also variable `debug-on-quit'. |
6491 | |
6492 This will attempt to enter a C debugger when XEmacs is run noninteractively | |
6493 and under the same conditions as described in `debug-on-error'. | |
6443 */ ); | 6494 */ ); |
6444 Vdebug_on_signal = Qnil; | 6495 Vdebug_on_signal = Qnil; |
6445 | 6496 |
6446 DEFVAR_BOOL ("debug-on-quit", &debug_on_quit /* | 6497 DEFVAR_BOOL ("debug-on-quit", &debug_on_quit /* |
6447 *Non-nil means enter debugger if quit is signalled (C-G, for example). | 6498 *Non-nil means enter debugger if quit is signalled (C-G, for example). |