diff options
| author | Richard M. Stallman | 2005-06-25 14:37:47 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 2005-06-25 14:37:47 +0000 |
| commit | 9f5903bb77b7f1f1e7a6598b3c496961e0ee02ea (patch) | |
| tree | beed15f824cc18d2b0eaf9a4604fcd6181ccf485 /src/eval.c | |
| parent | 7bbae30c23e8fc44bc3202c5e30ac593baca659b (diff) | |
| download | emacs-9f5903bb77b7f1f1e7a6598b3c496961e0ee02ea.tar.gz emacs-9f5903bb77b7f1f1e7a6598b3c496961e0ee02ea.zip | |
(call_debugger): Take full care of extending stack limits
to make space for the debugger, and restore the change afterward.
Bind debug-on-error to nil.
(restore_stack_limits): New subroutine.
(Fsignal): Extend specpdl bound along with eval depth bound,
for calling edebug. Don't do either one, for calling debugger.
(find_handler_clause): Don't bind debug-on-error here.
Don't unbind anything either.
Temporarily advance max_specpdl_size for calling
internal_with_output_to_temp_buffer.
(grow_specpdl): Don't alter max_specpdl_size before signaling an error.
(syms_of_eval) <max-specpdl-size>: Doc fix.
Diffstat (limited to 'src/eval.c')
| -rw-r--r-- | src/eval.c | 71 |
1 files changed, 48 insertions, 23 deletions
diff --git a/src/eval.c b/src/eval.c index 8ad289fd51f..c33021da7b7 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -227,6 +227,18 @@ init_eval () | |||
| 227 | when_entered_debugger = -1; | 227 | when_entered_debugger = -1; |
| 228 | } | 228 | } |
| 229 | 229 | ||
| 230 | /* unwind-protect function used by call_debugger. */ | ||
| 231 | |||
| 232 | static Lisp_Object | ||
| 233 | restore_stack_limits (data) | ||
| 234 | Lisp_Object data; | ||
| 235 | { | ||
| 236 | max_specpdl_size = XINT (XCAR (data)); | ||
| 237 | max_lisp_eval_depth = XINT (XCDR (data)); | ||
| 238 | } | ||
| 239 | |||
| 240 | /* Call the Lisp debugger, giving it argument ARG. */ | ||
| 241 | |||
| 230 | Lisp_Object | 242 | Lisp_Object |
| 231 | call_debugger (arg) | 243 | call_debugger (arg) |
| 232 | Lisp_Object arg; | 244 | Lisp_Object arg; |
| @@ -234,12 +246,22 @@ call_debugger (arg) | |||
| 234 | int debug_while_redisplaying; | 246 | int debug_while_redisplaying; |
| 235 | int count = SPECPDL_INDEX (); | 247 | int count = SPECPDL_INDEX (); |
| 236 | Lisp_Object val; | 248 | Lisp_Object val; |
| 249 | int old_max = max_specpdl_size; | ||
| 237 | 250 | ||
| 238 | if (lisp_eval_depth + 20 > max_lisp_eval_depth) | 251 | /* Temporarily bump up the stack limits, |
| 239 | max_lisp_eval_depth = lisp_eval_depth + 20; | 252 | so the debugger won't run out of stack. */ |
| 240 | 253 | ||
| 241 | if (specpdl_size + 40 > max_specpdl_size) | 254 | max_specpdl_size += 1; |
| 242 | max_specpdl_size = specpdl_size + 40; | 255 | record_unwind_protect (restore_stack_limits, |
| 256 | Fcons (make_number (old_max), | ||
| 257 | make_number (max_lisp_eval_depth))); | ||
| 258 | max_specpdl_size = old_max; | ||
| 259 | |||
| 260 | if (lisp_eval_depth + 40 > max_lisp_eval_depth) | ||
| 261 | max_lisp_eval_depth = lisp_eval_depth + 40; | ||
| 262 | |||
| 263 | if (SPECPDL_INDEX () + 100 > max_specpdl_size) | ||
| 264 | max_specpdl_size = SPECPDL_INDEX () + 100; | ||
| 243 | 265 | ||
| 244 | #ifdef HAVE_X_WINDOWS | 266 | #ifdef HAVE_X_WINDOWS |
| 245 | if (display_hourglass_p) | 267 | if (display_hourglass_p) |
| @@ -256,6 +278,7 @@ call_debugger (arg) | |||
| 256 | specbind (intern ("debugger-may-continue"), | 278 | specbind (intern ("debugger-may-continue"), |
| 257 | debug_while_redisplaying ? Qnil : Qt); | 279 | debug_while_redisplaying ? Qnil : Qt); |
| 258 | specbind (Qinhibit_redisplay, Qnil); | 280 | specbind (Qinhibit_redisplay, Qnil); |
| 281 | specbind (Qdebug_on_error, Qnil); | ||
| 259 | 282 | ||
| 260 | #if 0 /* Binding this prevents execution of Lisp code during | 283 | #if 0 /* Binding this prevents execution of Lisp code during |
| 261 | redisplay, which necessarily leads to display problems. */ | 284 | redisplay, which necessarily leads to display problems. */ |
| @@ -1533,7 +1556,16 @@ See also the function `condition-case'. */) | |||
| 1533 | /* This hook is used by edebug. */ | 1556 | /* This hook is used by edebug. */ |
| 1534 | if (! NILP (Vsignal_hook_function) | 1557 | if (! NILP (Vsignal_hook_function) |
| 1535 | && ! NILP (error_symbol)) | 1558 | && ! NILP (error_symbol)) |
| 1536 | call2 (Vsignal_hook_function, error_symbol, data); | 1559 | { |
| 1560 | /* Edebug takes care of restoring these variables when it exits. */ | ||
| 1561 | if (lisp_eval_depth + 20 > max_lisp_eval_depth) | ||
| 1562 | max_lisp_eval_depth = lisp_eval_depth + 20; | ||
| 1563 | |||
| 1564 | if (SPECPDL_INDEX () + 40 > max_specpdl_size) | ||
| 1565 | max_specpdl_size = SPECPDL_INDEX () + 40; | ||
| 1566 | |||
| 1567 | call2 (Vsignal_hook_function, error_symbol, data); | ||
| 1568 | } | ||
| 1537 | 1569 | ||
| 1538 | conditions = Fget (real_error_symbol, Qerror_conditions); | 1570 | conditions = Fget (real_error_symbol, Qerror_conditions); |
| 1539 | 1571 | ||
| @@ -1555,12 +1587,6 @@ See also the function `condition-case'. */) | |||
| 1555 | { | 1587 | { |
| 1556 | register Lisp_Object clause; | 1588 | register Lisp_Object clause; |
| 1557 | 1589 | ||
| 1558 | if (lisp_eval_depth + 20 > max_lisp_eval_depth) | ||
| 1559 | max_lisp_eval_depth = lisp_eval_depth + 20; | ||
| 1560 | |||
| 1561 | if (specpdl_size + 40 > max_specpdl_size) | ||
| 1562 | max_specpdl_size = specpdl_size + 40; | ||
| 1563 | |||
| 1564 | clause = find_handler_clause (handlerlist->handler, conditions, | 1590 | clause = find_handler_clause (handlerlist->handler, conditions, |
| 1565 | error_symbol, data, &debugger_value); | 1591 | error_symbol, data, &debugger_value); |
| 1566 | 1592 | ||
| @@ -1673,7 +1699,11 @@ skip_debugger (conditions, data) | |||
| 1673 | = SIG is nil, and DATA is (SYMBOL . REST-OF-DATA). | 1699 | = SIG is nil, and DATA is (SYMBOL . REST-OF-DATA). |
| 1674 | This is for memory-full errors only. | 1700 | This is for memory-full errors only. |
| 1675 | 1701 | ||
| 1676 | Store value returned from debugger into *DEBUGGER_VALUE_PTR. */ | 1702 | Store value returned from debugger into *DEBUGGER_VALUE_PTR. |
| 1703 | |||
| 1704 | We need to increase max_specpdl_size temporarily around | ||
| 1705 | anything we do that can push on the specpdl, so as not to get | ||
| 1706 | a second error here in case we're handling specpdl overflow. */ | ||
| 1677 | 1707 | ||
| 1678 | static Lisp_Object | 1708 | static Lisp_Object |
| 1679 | find_handler_clause (handlers, conditions, sig, data, debugger_value_ptr) | 1709 | find_handler_clause (handlers, conditions, sig, data, debugger_value_ptr) |
| @@ -1691,7 +1721,6 @@ find_handler_clause (handlers, conditions, sig, data, debugger_value_ptr) | |||
| 1691 | || !NILP (Vdebug_on_signal)) /* This says call debugger even if | 1721 | || !NILP (Vdebug_on_signal)) /* This says call debugger even if |
| 1692 | there is a handler. */ | 1722 | there is a handler. */ |
| 1693 | { | 1723 | { |
| 1694 | int count = SPECPDL_INDEX (); | ||
| 1695 | int debugger_called = 0; | 1724 | int debugger_called = 0; |
| 1696 | Lisp_Object sig_symbol, combined_data; | 1725 | Lisp_Object sig_symbol, combined_data; |
| 1697 | /* This is set to 1 if we are handling a memory-full error, | 1726 | /* This is set to 1 if we are handling a memory-full error, |
| @@ -1713,6 +1742,7 @@ find_handler_clause (handlers, conditions, sig, data, debugger_value_ptr) | |||
| 1713 | 1742 | ||
| 1714 | if (wants_debugger (Vstack_trace_on_error, conditions)) | 1743 | if (wants_debugger (Vstack_trace_on_error, conditions)) |
| 1715 | { | 1744 | { |
| 1745 | max_specpdl_size++; | ||
| 1716 | #ifdef PROTOTYPES | 1746 | #ifdef PROTOTYPES |
| 1717 | internal_with_output_to_temp_buffer ("*Backtrace*", | 1747 | internal_with_output_to_temp_buffer ("*Backtrace*", |
| 1718 | (Lisp_Object (*) (Lisp_Object)) Fbacktrace, | 1748 | (Lisp_Object (*) (Lisp_Object)) Fbacktrace, |
| @@ -1721,6 +1751,7 @@ find_handler_clause (handlers, conditions, sig, data, debugger_value_ptr) | |||
| 1721 | internal_with_output_to_temp_buffer ("*Backtrace*", | 1751 | internal_with_output_to_temp_buffer ("*Backtrace*", |
| 1722 | Fbacktrace, Qnil); | 1752 | Fbacktrace, Qnil); |
| 1723 | #endif | 1753 | #endif |
| 1754 | max_specpdl_size--; | ||
| 1724 | } | 1755 | } |
| 1725 | if (! no_debugger | 1756 | if (! no_debugger |
| 1726 | && (EQ (sig_symbol, Qquit) | 1757 | && (EQ (sig_symbol, Qquit) |
| @@ -1729,7 +1760,6 @@ find_handler_clause (handlers, conditions, sig, data, debugger_value_ptr) | |||
| 1729 | && ! skip_debugger (conditions, combined_data) | 1760 | && ! skip_debugger (conditions, combined_data) |
| 1730 | && when_entered_debugger < num_nonmacro_input_events) | 1761 | && when_entered_debugger < num_nonmacro_input_events) |
| 1731 | { | 1762 | { |
| 1732 | specbind (Qdebug_on_error, Qnil); | ||
| 1733 | *debugger_value_ptr | 1763 | *debugger_value_ptr |
| 1734 | = call_debugger (Fcons (Qerror, | 1764 | = call_debugger (Fcons (Qerror, |
| 1735 | Fcons (combined_data, Qnil))); | 1765 | Fcons (combined_data, Qnil))); |
| @@ -1739,7 +1769,7 @@ find_handler_clause (handlers, conditions, sig, data, debugger_value_ptr) | |||
| 1739 | if (EQ (handlers, Qerror)) | 1769 | if (EQ (handlers, Qerror)) |
| 1740 | { | 1770 | { |
| 1741 | if (debugger_called) | 1771 | if (debugger_called) |
| 1742 | return unbind_to (count, Qlambda); | 1772 | return Qlambda; |
| 1743 | return Qt; | 1773 | return Qt; |
| 1744 | } | 1774 | } |
| 1745 | } | 1775 | } |
| @@ -3019,13 +3049,8 @@ grow_specpdl () | |||
| 3019 | if (max_specpdl_size < 400) | 3049 | if (max_specpdl_size < 400) |
| 3020 | max_specpdl_size = 400; | 3050 | max_specpdl_size = 400; |
| 3021 | if (specpdl_size >= max_specpdl_size) | 3051 | if (specpdl_size >= max_specpdl_size) |
| 3022 | { | 3052 | Fsignal (Qerror, |
| 3023 | if (!NILP (Vdebug_on_error)) | 3053 | Fcons (build_string ("Variable binding depth exceeds max-specpdl-size"), Qnil)); |
| 3024 | /* Leave room for some specpdl in the debugger. */ | ||
| 3025 | max_specpdl_size = specpdl_size + 100; | ||
| 3026 | Fsignal (Qerror, | ||
| 3027 | Fcons (build_string ("Variable binding depth exceeds max-specpdl-size"), Qnil)); | ||
| 3028 | } | ||
| 3029 | } | 3054 | } |
| 3030 | specpdl_size *= 2; | 3055 | specpdl_size *= 2; |
| 3031 | if (specpdl_size > max_specpdl_size) | 3056 | if (specpdl_size > max_specpdl_size) |
| @@ -3333,7 +3358,7 @@ syms_of_eval () | |||
| 3333 | { | 3358 | { |
| 3334 | DEFVAR_INT ("max-specpdl-size", &max_specpdl_size, | 3359 | DEFVAR_INT ("max-specpdl-size", &max_specpdl_size, |
| 3335 | doc: /* *Limit on number of Lisp variable bindings & unwind-protects. | 3360 | doc: /* *Limit on number of Lisp variable bindings & unwind-protects. |
| 3336 | If Lisp code tries to make more than this many at once, | 3361 | If Lisp code tries to increase the total number past this amount, |
| 3337 | an error is signaled. | 3362 | an error is signaled. |
| 3338 | You can safely use a value considerably larger than the default value, | 3363 | You can safely use a value considerably larger than the default value, |
| 3339 | if that proves inconveniently small. However, if you increase it too far, | 3364 | if that proves inconveniently small. However, if you increase it too far, |