Mercurial > hg > xemacs-beta
comparison src/eval.c @ 1292:f3437b56874d
[xemacs-hg @ 2003-02-13 09:57:04 by ben]
profile updates
profile.c: Major reworking. Keep track of new information -- total
function timing (includes descendants), GC usage, total GC usage
(includes descendants). New functions to be called appropriately
from eval.c, alloc.c to keep track of this information. Keep track
of when we're actually in a function vs. in its profile, for more
accurate timing counts. Track profile overhead separately. Create
new mechanism for specifying "internal sections" that are tracked
just like regular Lisp functions and even appear in the backtrace
if `backtrace-with-internal-sections' is non-nil (t by default
for error-checking builds). Add some KKCC information for the
straight (non-Elisp) hash table used by profile, which contains
Lisp objects in its keys -- but not used yet. Remove old ad-hoc
methods for tracking garbage collection, redisplay (which was
incorrect anyway when Lisp was called within these sections).
Don't record any tick info when blocking under MS Windows, since
the timer there is in real time rather than in process time.
Make `start-profiling', `stop-profiling' interactive. Be consistent
wrt. recursive functions and functions currently on the stack when
starting or stopping -- together these make implementing the
`total' values extremely difficult. When we start profiling, we
act as if we just entered all the functions currently on the stack.
Likewise when exiting. Create vars in_profile for tracking
time spent inside of profiling, and profiling_lock for setting
exclusive access to the main hash table when reading from it or
modifying it. (protects against getting screwed up by the signal
handle going off at the same time.
profile.h: New file.
Create macros for declaring internal profiling sections.
lisp.h: Move profile-related stuff to profile.h.
alloc.c: Keep track of total consing, for profile.
Tell profile when we are consing.
Use new profile-section method for noting garbage-collection.
alloc.c: Abort if we attempt to call the allocator reentrantly.
backtrace.h, eval.c: Add info for use by profile in the backtrace frame and transfer
PUSH_BACKTRACE/POP_BACKTRACE from eval.c, for use with profile.
elhash.c: Author comment.
eval.c, lisp.h: New Lisp var `backtrace-with-internal-sections'. Set to t when
error-checking is on.
eval.c: When unwinding,
eval.c: Report to profile when we are about-to-call and just-called wrt. a
function.
alloc.c, eval.c: Allow for "fake" backtrace frames, for internal sections (used by
profile and `backtrace-with-internal-sections'.
event-Xt.c, event-gtk.c, event-msw.c, event-tty.c: Record when we are actually blocking on an event, for profile's sake.
event-stream.c: Record internal profiling sections for getting, dispatching events.
extents.c: Record internal profiling sections for map_extents.
hash.c, hash.h: Add pregrow_hash_table_if_necessary(). (Used in profile code
since the signal handler is the main grower but can't allow
a realloc(). We make sure, at critical points, that the table
is large enough.)
lread.c: Create internal profiling sections for `load' (which may be triggered
internally by autoload, etc.).
redisplay.c: Remove old profile_redisplay_flag. Use new macros to declare
internal profiling section for redisplay.
text.c: Use new macros to declare internal profiling sections for
char-byte conversion and internal-external conversion.
SEMI-UNRELATED CHANGES:
-----------------------
text.c: Update the long comments.
author | ben |
---|---|
date | Thu, 13 Feb 2003 09:57:08 +0000 |
parents | 465bd3c7d932 |
children | 671b65f2b075 |
comparison
equal
deleted
inserted
replaced
1291:3d99b5e6c6ec | 1292:f3437b56874d |
---|---|
1 /* Evaluator for XEmacs Lisp interpreter. | 1 /* Evaluator for XEmacs Lisp interpreter. |
2 Copyright (C) 1985-1987, 1992-1994 Free Software Foundation, Inc. | 2 Copyright (C) 1985-1987, 1992-1994 Free Software Foundation, Inc. |
3 Copyright (C) 1995 Sun Microsystems, Inc. | 3 Copyright (C) 1995 Sun Microsystems, Inc. |
4 Copyright (C) 2000, 2001, 2002 Ben Wing. | 4 Copyright (C) 2000, 2001, 2002, 2003 Ben Wing. |
5 | 5 |
6 This file is part of XEmacs. | 6 This file is part of XEmacs. |
7 | 7 |
8 XEmacs is free software; you can redistribute it and/or modify it | 8 XEmacs is free software; you can redistribute it and/or modify it |
9 under the terms of the GNU General Public License as published by the | 9 under the terms of the GNU General Public License as published by the |
145 #include "console-impl.h" | 145 #include "console-impl.h" |
146 #include "device.h" | 146 #include "device.h" |
147 #include "frame.h" | 147 #include "frame.h" |
148 #include "lstream.h" | 148 #include "lstream.h" |
149 #include "opaque.h" | 149 #include "opaque.h" |
150 #include "profile.h" | |
150 #include "window.h" | 151 #include "window.h" |
151 | 152 |
152 struct backtrace *backtrace_list; | 153 struct backtrace *backtrace_list; |
153 | |
154 /* Note: you must always fill in all of the fields in a backtrace structure | |
155 before pushing them on the backtrace_list. The profiling code depends | |
156 on this. */ | |
157 | |
158 #define PUSH_BACKTRACE(bt) do { \ | |
159 (bt).next = backtrace_list; \ | |
160 backtrace_list = &(bt); \ | |
161 } while (0) | |
162 | |
163 #define POP_BACKTRACE(bt) do { \ | |
164 backtrace_list = (bt).next; \ | |
165 } while (0) | |
166 | 154 |
167 /* Macros for calling subrs with an argument list whose length is only | 155 /* Macros for calling subrs with an argument list whose length is only |
168 known at runtime. See EXFUN and DEFUN for similar hackery. */ | 156 known at runtime. See EXFUN and DEFUN for similar hackery. */ |
169 | 157 |
170 #define AV_0(av) | 158 #define AV_0(av) |
290 | 278 |
291 /* Maximum size allowed for specpdl allocation */ | 279 /* Maximum size allowed for specpdl allocation */ |
292 Fixnum max_specpdl_size; | 280 Fixnum max_specpdl_size; |
293 | 281 |
294 /* Depth in Lisp evaluations and function calls. */ | 282 /* Depth in Lisp evaluations and function calls. */ |
295 static int lisp_eval_depth; | 283 int lisp_eval_depth; |
296 | 284 |
297 /* Maximum allowed depth in Lisp evaluations and function calls. */ | 285 /* Maximum allowed depth in Lisp evaluations and function calls. */ |
298 Fixnum max_lisp_eval_depth; | 286 Fixnum max_lisp_eval_depth; |
299 | 287 |
300 /* Nonzero means enter debugger before next function call */ | 288 /* Nonzero means enter debugger before next function call */ |
301 static int debug_on_next_call; | 289 static int debug_on_next_call; |
290 | |
291 int backtrace_with_internal_sections; | |
302 | 292 |
303 /* List of conditions (non-nil atom means all) which cause a backtrace | 293 /* List of conditions (non-nil atom means all) which cause a backtrace |
304 if an error is handled by the command loop's error handler. */ | 294 if an error is handled by the command loop's error handler. */ |
305 Lisp_Object Vstack_trace_on_error; | 295 Lisp_Object Vstack_trace_on_error; |
306 | 296 |
1593 catchlist = c->next; | 1583 catchlist = c->next; |
1594 check_catchlist_sanity (); | 1584 check_catchlist_sanity (); |
1595 #endif /* Former code */ | 1585 #endif /* Former code */ |
1596 | 1586 |
1597 UNWIND_GCPRO_TO (c->gcpro); | 1587 UNWIND_GCPRO_TO (c->gcpro); |
1598 backtrace_list = c->backlist; | 1588 if (profiling_active) |
1589 { | |
1590 while (backtrace_list != c->backlist) | |
1591 { | |
1592 profile_record_unwind (backtrace_list); | |
1593 backtrace_list = backtrace_list->next; | |
1594 } | |
1595 } | |
1596 else | |
1597 backtrace_list = c->backlist; | |
1599 lisp_eval_depth = c->lisp_eval_depth; | 1598 lisp_eval_depth = c->lisp_eval_depth; |
1600 | 1599 |
1601 #ifdef DEFEND_AGAINST_THROW_RECURSION | 1600 #ifdef DEFEND_AGAINST_THROW_RECURSION |
1602 throw_level = 0; | 1601 throw_level = 0; |
1603 #endif | 1602 #endif |
1704 return unbind_to_1 (speccount, Feval (XCAR (args))); | 1703 return unbind_to_1 (speccount, Feval (XCAR (args))); |
1705 } | 1704 } |
1706 | 1705 |
1707 | 1706 |
1708 /************************************************************************/ | 1707 /************************************************************************/ |
1709 /* Signalling and trapping errors */ | 1708 /* Trapping errors */ |
1710 /************************************************************************/ | 1709 /************************************************************************/ |
1711 | 1710 |
1712 static Lisp_Object | 1711 static Lisp_Object |
1713 condition_bind_unwind (Lisp_Object loser) | 1712 condition_bind_unwind (Lisp_Object loser) |
1714 { | 1713 { |
3090 { | 3089 { |
3091 backtrace.function = &Qcall_interactively; | 3090 backtrace.function = &Qcall_interactively; |
3092 backtrace.args = &cmd; | 3091 backtrace.args = &cmd; |
3093 backtrace.nargs = 1; | 3092 backtrace.nargs = 1; |
3094 backtrace.evalargs = 0; | 3093 backtrace.evalargs = 0; |
3095 backtrace.pdlcount = specpdl_depth(); | 3094 backtrace.pdlcount = specpdl_depth (); |
3096 backtrace.debug_on_exit = 0; | 3095 backtrace.debug_on_exit = 0; |
3096 backtrace.function_being_called = 0; | |
3097 PUSH_BACKTRACE (backtrace); | 3097 PUSH_BACKTRACE (backtrace); |
3098 | 3098 |
3099 PROFILE_ENTER_FUNCTION (); | |
3099 final = Fcall_interactively (cmd, record_flag, keys); | 3100 final = Fcall_interactively (cmd, record_flag, keys); |
3101 PROFILE_EXIT_FUNCTION (); | |
3100 | 3102 |
3101 POP_BACKTRACE (backtrace); | 3103 POP_BACKTRACE (backtrace); |
3102 return final; | 3104 return final; |
3103 } | 3105 } |
3104 else if (STRINGP (final) || VECTORP (final)) | 3106 else if (STRINGP (final) || VECTORP (final)) |
3533 backtrace.function = &original_fun; /* This also protects them from gc */ | 3535 backtrace.function = &original_fun; /* This also protects them from gc */ |
3534 backtrace.args = &original_args; | 3536 backtrace.args = &original_args; |
3535 backtrace.nargs = UNEVALLED; | 3537 backtrace.nargs = UNEVALLED; |
3536 backtrace.evalargs = 1; | 3538 backtrace.evalargs = 1; |
3537 backtrace.debug_on_exit = 0; | 3539 backtrace.debug_on_exit = 0; |
3540 backtrace.function_being_called = 0; | |
3538 PUSH_BACKTRACE (backtrace); | 3541 PUSH_BACKTRACE (backtrace); |
3539 | 3542 |
3540 if (debug_on_next_call) | 3543 if (debug_on_next_call) |
3541 do_debug_on_call (Qt); | 3544 do_debug_on_call (Qt); |
3542 | |
3543 if (profiling_active) | |
3544 profile_increase_call_count (original_fun); | |
3545 | 3545 |
3546 /* At this point, only original_fun and original_args | 3546 /* At this point, only original_fun and original_args |
3547 have values that will be used below. */ | 3547 have values that will be used below. */ |
3548 retry: | 3548 retry: |
3549 fun = indirect_function (original_fun, 1); | 3549 fun = indirect_function (original_fun, 1); |
3557 goto wrong_number_of_arguments; | 3557 goto wrong_number_of_arguments; |
3558 | 3558 |
3559 if (max_args == UNEVALLED) /* Optimize for the common case */ | 3559 if (max_args == UNEVALLED) /* Optimize for the common case */ |
3560 { | 3560 { |
3561 backtrace.evalargs = 0; | 3561 backtrace.evalargs = 0; |
3562 PROFILE_ENTER_FUNCTION (); | |
3562 val = (((Lisp_Object (*) (Lisp_Object)) subr_function (subr)) | 3563 val = (((Lisp_Object (*) (Lisp_Object)) subr_function (subr)) |
3563 (original_args)); | 3564 (original_args)); |
3565 PROFILE_EXIT_FUNCTION (); | |
3564 } | 3566 } |
3565 else if (nargs <= max_args) | 3567 else if (nargs <= max_args) |
3566 { | 3568 { |
3567 struct gcpro gcpro1; | 3569 struct gcpro gcpro1; |
3568 Lisp_Object args[SUBR_MAX_ARGS]; | 3570 Lisp_Object args[SUBR_MAX_ARGS]; |
3584 *p++ = Qnil; | 3586 *p++ = Qnil; |
3585 | 3587 |
3586 backtrace.args = args; | 3588 backtrace.args = args; |
3587 backtrace.nargs = nargs; | 3589 backtrace.nargs = nargs; |
3588 | 3590 |
3591 PROFILE_ENTER_FUNCTION (); | |
3589 FUNCALL_SUBR (val, subr, args, max_args); | 3592 FUNCALL_SUBR (val, subr, args, max_args); |
3593 PROFILE_EXIT_FUNCTION (); | |
3590 | 3594 |
3591 UNGCPRO; | 3595 UNGCPRO; |
3592 } | 3596 } |
3593 else if (max_args == MANY) | 3597 else if (max_args == MANY) |
3594 { | 3598 { |
3609 } | 3613 } |
3610 | 3614 |
3611 backtrace.args = args; | 3615 backtrace.args = args; |
3612 backtrace.nargs = nargs; | 3616 backtrace.nargs = nargs; |
3613 | 3617 |
3618 PROFILE_ENTER_FUNCTION (); | |
3614 val = (((Lisp_Object (*) (int, Lisp_Object *)) subr_function (subr)) | 3619 val = (((Lisp_Object (*) (int, Lisp_Object *)) subr_function (subr)) |
3615 (nargs, args)); | 3620 (nargs, args)); |
3621 PROFILE_EXIT_FUNCTION (); | |
3616 | 3622 |
3617 UNGCPRO; | 3623 UNGCPRO; |
3618 } | 3624 } |
3619 else | 3625 else |
3620 { | 3626 { |
3641 | 3647 |
3642 backtrace.args = args; | 3648 backtrace.args = args; |
3643 backtrace.nargs = nargs; | 3649 backtrace.nargs = nargs; |
3644 backtrace.evalargs = 0; | 3650 backtrace.evalargs = 0; |
3645 | 3651 |
3652 PROFILE_ENTER_FUNCTION (); | |
3646 val = funcall_compiled_function (fun, nargs, args); | 3653 val = funcall_compiled_function (fun, nargs, args); |
3654 PROFILE_EXIT_FUNCTION (); | |
3647 | 3655 |
3648 /* Do the debug-on-exit now, while args is still GCPROed. */ | 3656 /* Do the debug-on-exit now, while args is still GCPROed. */ |
3649 if (backtrace.debug_on_exit) | 3657 if (backtrace.debug_on_exit) |
3650 val = do_debug_on_exit (val); | 3658 val = do_debug_on_exit (val); |
3651 /* Don't do it again when we return to eval. */ | 3659 /* Don't do it again when we return to eval. */ |
3663 do_autoload (fun, original_fun); | 3671 do_autoload (fun, original_fun); |
3664 goto retry; | 3672 goto retry; |
3665 } | 3673 } |
3666 else if (EQ (funcar, Qmacro)) | 3674 else if (EQ (funcar, Qmacro)) |
3667 { | 3675 { |
3676 PROFILE_ENTER_FUNCTION (); | |
3668 val = Feval (apply1 (XCDR (fun), original_args)); | 3677 val = Feval (apply1 (XCDR (fun), original_args)); |
3678 PROFILE_EXIT_FUNCTION (); | |
3669 } | 3679 } |
3670 else if (EQ (funcar, Qlambda)) | 3680 else if (EQ (funcar, Qlambda)) |
3671 { | 3681 { |
3672 struct gcpro gcpro1; | 3682 struct gcpro gcpro1; |
3673 Lisp_Object *args = alloca_array (Lisp_Object, nargs); | 3683 Lisp_Object *args = alloca_array (Lisp_Object, nargs); |
3688 | 3698 |
3689 backtrace.args = args; /* this also GCPROs `args' */ | 3699 backtrace.args = args; /* this also GCPROs `args' */ |
3690 backtrace.nargs = nargs; | 3700 backtrace.nargs = nargs; |
3691 backtrace.evalargs = 0; | 3701 backtrace.evalargs = 0; |
3692 | 3702 |
3703 PROFILE_ENTER_FUNCTION (); | |
3693 val = funcall_lambda (fun, nargs, args); | 3704 val = funcall_lambda (fun, nargs, args); |
3705 PROFILE_EXIT_FUNCTION (); | |
3694 | 3706 |
3695 /* Do the debug-on-exit now, while args is still GCPROed. */ | 3707 /* Do the debug-on-exit now, while args is still GCPROed. */ |
3696 if (backtrace.debug_on_exit) | 3708 if (backtrace.debug_on_exit) |
3697 val = do_debug_on_exit (val); | 3709 val = do_debug_on_exit (val); |
3698 /* Don't do it again when we return to eval. */ | 3710 /* Don't do it again when we return to eval. */ |
3743 Lisp_Object fun; | 3755 Lisp_Object fun; |
3744 Lisp_Object val; | 3756 Lisp_Object val; |
3745 struct backtrace backtrace; | 3757 struct backtrace backtrace; |
3746 int fun_nargs = nargs - 1; | 3758 int fun_nargs = nargs - 1; |
3747 Lisp_Object *fun_args = args + 1; | 3759 Lisp_Object *fun_args = args + 1; |
3760 Lisp_Object orig_fun; | |
3748 | 3761 |
3749 QUIT; | 3762 QUIT; |
3750 | 3763 |
3751 if (funcall_allocation_flag) | 3764 if (funcall_allocation_flag) |
3752 { | 3765 { |
3779 if (lisp_eval_depth > max_lisp_eval_depth) | 3792 if (lisp_eval_depth > max_lisp_eval_depth) |
3780 stack_overflow ("Lisp nesting exceeds `max-lisp-eval-depth'", | 3793 stack_overflow ("Lisp nesting exceeds `max-lisp-eval-depth'", |
3781 Qunbound); | 3794 Qunbound); |
3782 } | 3795 } |
3783 | 3796 |
3784 backtrace.pdlcount = specpdl_depth(); | 3797 backtrace.pdlcount = specpdl_depth (); |
3785 backtrace.function = &args[0]; | 3798 backtrace.function = &args[0]; |
3786 backtrace.args = fun_args; | 3799 backtrace.args = fun_args; |
3787 backtrace.nargs = fun_nargs; | 3800 backtrace.nargs = fun_nargs; |
3788 backtrace.evalargs = 0; | 3801 backtrace.evalargs = 0; |
3789 backtrace.debug_on_exit = 0; | 3802 backtrace.debug_on_exit = 0; |
3803 backtrace.function_being_called = 0; | |
3790 PUSH_BACKTRACE (backtrace); | 3804 PUSH_BACKTRACE (backtrace); |
3791 | 3805 |
3792 if (debug_on_next_call) | 3806 if (debug_on_next_call) |
3793 do_debug_on_call (Qlambda); | 3807 do_debug_on_call (Qlambda); |
3794 | 3808 |
3809 orig_fun = args[0]; | |
3810 | |
3795 retry: | 3811 retry: |
3796 | 3812 |
3797 fun = args[0]; | 3813 fun = args[0]; |
3798 | |
3799 /* It might be useful to place this *after* all the checks. */ | |
3800 if (profiling_active) | |
3801 profile_increase_call_count (fun); | |
3802 | 3814 |
3803 /* We could call indirect_function directly, but profiling shows | 3815 /* We could call indirect_function directly, but profiling shows |
3804 this is worth optimizing by partially unrolling the loop. */ | 3816 this is worth optimizing by partially unrolling the loop. */ |
3805 if (SYMBOLP (fun)) | 3817 if (SYMBOLP (fun)) |
3806 { | 3818 { |
3820 Lisp_Object spacious_args[SUBR_MAX_ARGS]; | 3832 Lisp_Object spacious_args[SUBR_MAX_ARGS]; |
3821 | 3833 |
3822 if (fun_nargs == max_args) /* Optimize for the common case */ | 3834 if (fun_nargs == max_args) /* Optimize for the common case */ |
3823 { | 3835 { |
3824 funcall_subr: | 3836 funcall_subr: |
3837 PROFILE_ENTER_FUNCTION (); | |
3825 FUNCALL_SUBR (val, subr, fun_args, max_args); | 3838 FUNCALL_SUBR (val, subr, fun_args, max_args); |
3839 PROFILE_EXIT_FUNCTION (); | |
3826 } | 3840 } |
3827 else if (fun_nargs < subr->min_args) | 3841 else if (fun_nargs < subr->min_args) |
3828 { | 3842 { |
3829 goto wrong_number_of_arguments; | 3843 goto wrong_number_of_arguments; |
3830 } | 3844 } |
3841 fun_args = spacious_args; | 3855 fun_args = spacious_args; |
3842 goto funcall_subr; | 3856 goto funcall_subr; |
3843 } | 3857 } |
3844 else if (max_args == MANY) | 3858 else if (max_args == MANY) |
3845 { | 3859 { |
3860 PROFILE_ENTER_FUNCTION (); | |
3846 val = SUBR_FUNCTION (subr, MANY) (fun_nargs, fun_args); | 3861 val = SUBR_FUNCTION (subr, MANY) (fun_nargs, fun_args); |
3862 PROFILE_EXIT_FUNCTION (); | |
3847 } | 3863 } |
3848 else if (max_args == UNEVALLED) /* Can't funcall a special form */ | 3864 else if (max_args == UNEVALLED) /* Can't funcall a special form */ |
3849 { | 3865 { |
3850 goto invalid_function; | 3866 goto invalid_function; |
3851 } | 3867 } |
3855 val = signal_wrong_number_of_arguments_error (fun, fun_nargs); | 3871 val = signal_wrong_number_of_arguments_error (fun, fun_nargs); |
3856 } | 3872 } |
3857 } | 3873 } |
3858 else if (COMPILED_FUNCTIONP (fun)) | 3874 else if (COMPILED_FUNCTIONP (fun)) |
3859 { | 3875 { |
3876 PROFILE_ENTER_FUNCTION (); | |
3860 val = funcall_compiled_function (fun, fun_nargs, fun_args); | 3877 val = funcall_compiled_function (fun, fun_nargs, fun_args); |
3878 PROFILE_EXIT_FUNCTION (); | |
3861 } | 3879 } |
3862 else if (CONSP (fun)) | 3880 else if (CONSP (fun)) |
3863 { | 3881 { |
3864 Lisp_Object funcar = XCAR (fun); | 3882 Lisp_Object funcar = XCAR (fun); |
3865 | 3883 |
3866 if (EQ (funcar, Qlambda)) | 3884 if (EQ (funcar, Qlambda)) |
3867 { | 3885 { |
3886 PROFILE_ENTER_FUNCTION (); | |
3868 val = funcall_lambda (fun, fun_nargs, fun_args); | 3887 val = funcall_lambda (fun, fun_nargs, fun_args); |
3888 PROFILE_EXIT_FUNCTION (); | |
3869 } | 3889 } |
3870 else if (EQ (funcar, Qautoload)) | 3890 else if (EQ (funcar, Qautoload)) |
3871 { | 3891 { |
3872 /* do_autoload GCPROs both arguments */ | 3892 /* do_autoload GCPROs both arguments */ |
3873 do_autoload (fun, args[0]); | 3893 do_autoload (fun, args[0]); |
6054 } | 6074 } |
6055 } | 6075 } |
6056 if (printing_bindings) write_c_string (stream, ")\n"); | 6076 if (printing_bindings) write_c_string (stream, ")\n"); |
6057 } | 6077 } |
6058 | 6078 |
6079 static Lisp_Object | |
6080 backtrace_unevalled_args (Lisp_Object *args) | |
6081 { | |
6082 if (args) | |
6083 return *args; | |
6084 else | |
6085 return list1 (build_string ("[internal]")); | |
6086 } | |
6087 | |
6059 DEFUN ("backtrace", Fbacktrace, 0, 2, "", /* | 6088 DEFUN ("backtrace", Fbacktrace, 0, 2, "", /* |
6060 Print a trace of Lisp function calls currently active. | 6089 Print a trace of Lisp function calls currently active. |
6061 Optional arg STREAM specifies the output stream to send the backtrace to, | 6090 Optional arg STREAM specifies the output stream to send the backtrace to, |
6062 and defaults to the value of `standard-output'. | 6091 and defaults to the value of `standard-output'. |
6063 Optional second arg DETAILED non-nil means show places where currently | 6092 Optional second arg DETAILED non-nil means show places where currently |
6133 speccount = backlist->pdlcount; | 6162 speccount = backlist->pdlcount; |
6134 } | 6163 } |
6135 write_c_string (stream, backlist->debug_on_exit ? "* " : " "); | 6164 write_c_string (stream, backlist->debug_on_exit ? "* " : " "); |
6136 if (backlist->nargs == UNEVALLED) | 6165 if (backlist->nargs == UNEVALLED) |
6137 { | 6166 { |
6138 Fprin1 (Fcons (*backlist->function, *backlist->args), stream); | 6167 Fprin1 (Fcons (*backlist->function, |
6168 backtrace_unevalled_args (backlist->args)), | |
6169 stream); | |
6139 write_c_string (stream, "\n"); /* from FSFmacs 19.30 */ | 6170 write_c_string (stream, "\n"); /* from FSFmacs 19.30 */ |
6140 } | 6171 } |
6141 else | 6172 else |
6142 { | 6173 { |
6143 Lisp_Object tem = *backlist->function; | 6174 Lisp_Object tem = *backlist->function; |
6211 backlist = backlist->next; | 6242 backlist = backlist->next; |
6212 | 6243 |
6213 if (!backlist) | 6244 if (!backlist) |
6214 return Qnil; | 6245 return Qnil; |
6215 if (backlist->nargs == UNEVALLED) | 6246 if (backlist->nargs == UNEVALLED) |
6216 return Fcons (Qnil, Fcons (*backlist->function, *backlist->args)); | 6247 return Fcons (Qnil, Fcons (*backlist->function, |
6248 backtrace_unevalled_args (backlist->args))); | |
6217 else | 6249 else |
6218 { | 6250 { |
6219 if (backlist->nargs == MANY) | 6251 if (backlist->nargs == MANY) |
6220 tem = *backlist->args; | 6252 tem = *backlist->args; |
6221 else | 6253 else |
6512 | 6544 |
6513 DEFVAR_BOOL ("debug-on-next-call", &debug_on_next_call /* | 6545 DEFVAR_BOOL ("debug-on-next-call", &debug_on_next_call /* |
6514 Non-nil means enter debugger before next `eval', `apply' or `funcall'. | 6546 Non-nil means enter debugger before next `eval', `apply' or `funcall'. |
6515 */ ); | 6547 */ ); |
6516 | 6548 |
6549 DEFVAR_BOOL ("backtrace-with-interal-sections", | |
6550 &backtrace_with_internal_sections /* | |
6551 Non-nil means backtraces will contain additional information indicating | |
6552 when particular sections of the C code have been entered, e.g. redisplay(), | |
6553 byte-char conversion, internal-external conversion, etc. This can be | |
6554 particularly useful when XEmacs crashes, in helping to pinpoint the problem. | |
6555 */ ); | |
6556 #ifdef ERROR_CHECK_STRUCTURES | |
6557 backtrace_with_internal_sections = 1; | |
6558 #else | |
6559 backtrace_with_internal_sections = 0; | |
6560 #endif | |
6561 | |
6517 DEFVAR_LISP ("debugger", &Vdebugger /* | 6562 DEFVAR_LISP ("debugger", &Vdebugger /* |
6518 Function to call to invoke debugger. | 6563 Function to call to invoke debugger. |
6519 If due to frame exit, args are `exit' and the value being returned; | 6564 If due to frame exit, args are `exit' and the value being returned; |
6520 this function's value will be returned instead of that. | 6565 this function's value will be returned instead of that. |
6521 If due to error, args are `error' and a list of the args to `signal'. | 6566 If due to error, args are `error' and a list of the args to `signal'. |