2001-03-17 12:20:36 +00:00
|
|
|
|
/* Debugging extensions for Guile
|
2018-06-17 19:46:33 +02:00
|
|
|
|
* Copyright (C) 1995-2003,2006,2008-2013,2018
|
|
|
|
|
|
* Free Software Foundation
|
1996-09-12 23:39:37 +00:00
|
|
|
|
*
|
2003-04-05 19:15:35 +00:00
|
|
|
|
* This library is free software; you can redistribute it and/or
|
2009-06-17 00:22:09 +01:00
|
|
|
|
* modify it under the terms of the GNU Lesser General Public License
|
|
|
|
|
|
* as published by the Free Software Foundation; either version 3 of
|
|
|
|
|
|
* the License, or (at your option) any later version.
|
1996-09-12 23:39:37 +00:00
|
|
|
|
*
|
2009-06-17 00:22:09 +01:00
|
|
|
|
* This library is distributed in the hope that it will be useful, but
|
|
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
2003-04-05 19:15:35 +00:00
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
|
|
* Lesser General Public License for more details.
|
1996-09-12 23:39:37 +00:00
|
|
|
|
*
|
2003-04-05 19:15:35 +00:00
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
|
|
* License along with this library; if not, write to the Free Software
|
2009-06-17 00:22:09 +01:00
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
|
|
|
|
* 02110-1301 USA
|
2003-04-05 19:15:35 +00:00
|
|
|
|
*/
|
1996-08-20 17:08:46 +00:00
|
|
|
|
|
1999-12-12 02:36:16 +00:00
|
|
|
|
|
2008-09-13 15:35:27 +02:00
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
|
|
# include <config.h>
|
|
|
|
|
|
#endif
|
1999-12-12 02:36:16 +00:00
|
|
|
|
|
2018-06-17 19:46:33 +02:00
|
|
|
|
#include <errno.h>
|
|
|
|
|
|
|
2009-03-27 15:44:17 -07:00
|
|
|
|
#ifdef HAVE_GETRLIMIT
|
|
|
|
|
|
#include <sys/time.h>
|
|
|
|
|
|
#include <sys/resource.h>
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
2014-07-03 19:26:21 +03:00
|
|
|
|
#ifdef __MINGW32__
|
|
|
|
|
|
# define WIN32_LEAN_AND_MEAN
|
|
|
|
|
|
# include <windows.h>
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
2018-06-20 17:19:31 +02:00
|
|
|
|
#include "gsubr.h"
|
|
|
|
|
|
#include "async.h"
|
|
|
|
|
|
#include "eval.h"
|
|
|
|
|
|
#include "list.h"
|
|
|
|
|
|
#include "stackchk.h"
|
|
|
|
|
|
#include "throw.h"
|
|
|
|
|
|
#include "macros.h"
|
|
|
|
|
|
#include "smob.h"
|
|
|
|
|
|
#include "struct.h"
|
|
|
|
|
|
#include "pairs.h"
|
|
|
|
|
|
#include "procprop.h"
|
|
|
|
|
|
#include "srcprop.h"
|
|
|
|
|
|
#include "alist.h"
|
|
|
|
|
|
#include "continuations.h"
|
|
|
|
|
|
#include "strports.h"
|
|
|
|
|
|
#include "read.h"
|
|
|
|
|
|
#include "feature.h"
|
|
|
|
|
|
#include "dynwind.h"
|
|
|
|
|
|
#include "modules.h"
|
|
|
|
|
|
#include "ports.h"
|
|
|
|
|
|
#include "fluids.h"
|
|
|
|
|
|
#include "programs.h"
|
|
|
|
|
|
#include "memoize.h"
|
|
|
|
|
|
#include "variable.h"
|
|
|
|
|
|
#include "vm.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include "debug.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include "private-options.h"
|
1996-08-20 17:08:46 +00:00
|
|
|
|
|
|
|
|
|
|
|
* backtrace.c, debug.c, debug.h, deprecation.c, eq.c, eval.c
eval.h, gsubr.c, init.c, macros.c, print.c, print.h, read.c,
read.h, stacks.c, symbols.c, throw.c: use private-options.h
* private-options.h: new file: contain hardcoded option
definitions.
2007-01-22 15:14:40 +00:00
|
|
|
|
|
2010-10-01 13:11:51 +02:00
|
|
|
|
/*
|
|
|
|
|
|
* Debugging options.
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
scm_t_option scm_debug_opts[] = {
|
|
|
|
|
|
{ SCM_OPTION_BOOLEAN, "backwards", 0,
|
|
|
|
|
|
"Display backtrace in anti-chronological order." },
|
|
|
|
|
|
{ SCM_OPTION_INTEGER, "width", 79, "Maximal width of backtrace." },
|
|
|
|
|
|
{ SCM_OPTION_INTEGER, "depth", 20, "Maximal length of printed backtrace." },
|
|
|
|
|
|
{ SCM_OPTION_BOOLEAN, "backtrace", 1, "Show backtrace on error." },
|
|
|
|
|
|
/* This default stack limit will be overridden by init_stack_limit(),
|
|
|
|
|
|
if we have getrlimit() and the stack limit is not INFINITY. But it is still
|
|
|
|
|
|
important, as some systems have both the soft and the hard limits set to
|
|
|
|
|
|
INFINITY; in that case we fall back to this value.
|
|
|
|
|
|
|
|
|
|
|
|
The situation is aggravated by certain compilers, which can consume
|
|
|
|
|
|
"beaucoup de stack", as they say in France.
|
|
|
|
|
|
|
|
|
|
|
|
See http://thread.gmane.org/gmane.lisp.guile.devel/8599/focus=8662 for
|
|
|
|
|
|
more discussion. This setting is 640 KB on 32-bit arches (should be enough
|
|
|
|
|
|
for anyone!) or a whoppin' 1280 KB on 64-bit arches.
|
|
|
|
|
|
*/
|
|
|
|
|
|
{ SCM_OPTION_INTEGER, "stack", 160000, "Stack size limit (measured in words; 0 = no check)." },
|
allow iflags to be constant expressions with typing-strictness==2
* libguile/tags.h (SCM_MAKE_ITAG8_BITS): New helper, produces a
scm_t_bits instead of a SCM, because SCM_UNPACK is not a constant
expression with SCM_DEBUG_TYPING_STRICTNESS==2.
(SCM_MAKIFLAG_BITS): Remove SCM_MAKIFLAG, and replace with this, which
returns bits.
(SCM_BOOL_F_BITS, SCM_ELISP_NIL_BITS, SCM_EOL_BITS, SCM_BOOL_T_BITS):
(SCM_UNSPECIFIED_BITS, SCM_UNDEFINED_BITS, SCM_EOF_VAL_BITS):
(SCM_UNBOUND_BITS): New definitions. Defined SCM_BOOL_F, etc in terms
of them.
(SCM_XXX_ANOTHER_BOOLEAN_DONT_USE_0):
(SCM_XXX_ANOTHER_BOOLEAN_DONT_USE_1):
(SCM_XXX_ANOTHER_BOOLEAN_DONT_USE_2):
(SCM_XXX_ANOTHER_LISP_FALSE_DONT_USE): Be bits instead of SCM values.
(SCM_BITS_DIFFER_IN_EXACTLY_ONE_BIT_POSITION):
(SCM_BITS_DIFFER_IN_EXACTLY_TWO_BIT_POSITIONS): Rename from
SCM_VALUES_DIFFER_..., and take unpacked bits as the args.
* libguile/boolean.c: Update verify block to use
SCM_BITS_DIFFER_IN_EXACTLY_TWO_BIT_POSITIONS et al.
* libguile/debug.c (scm_debug_opts):
* libguile/print.c (scm_print_opts):
* libguile/read.c (scm_read_opts): Use iflags bits for initializers.
* libguile/hash.c (scm_hasher): Use _BITS for iflags as case labels.
* libguile/pairs.c: Nil/null compile-time check uses
SCM_ELISP_NIL_BITS.
2011-05-13 10:19:48 +02:00
|
|
|
|
{ SCM_OPTION_SCM, "show-file-name", SCM_BOOL_T_BITS,
|
2010-10-01 13:11:51 +02:00
|
|
|
|
"Show file names and line numbers "
|
|
|
|
|
|
"in backtraces when not `#f'. A value of `base' "
|
|
|
|
|
|
"displays only base names, while `#t' displays full names."},
|
|
|
|
|
|
{ SCM_OPTION_BOOLEAN, "warn-deprecated", 0,
|
|
|
|
|
|
"Warn when deprecated features are used." },
|
|
|
|
|
|
{ 0 },
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
1996-08-20 17:08:46 +00:00
|
|
|
|
/* {Run time control of the debugging evaluator}
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
2000-01-05 19:05:23 +00:00
|
|
|
|
SCM_DEFINE (scm_debug_options, "debug-options-interface", 0, 1, 0,
|
1999-12-12 02:36:16 +00:00
|
|
|
|
(SCM setting),
|
(scm_with_traps, scm_memoized_p, scm_make_gloc, scm_gloc_p,
scm_make_iloc, scm_iloc_p, scm_memcons, scm_mem_to_proc,
scm_proc_to_mem, scm_unmemoize, scm_memoized_environment,
scm_procedure_name, scm_procedure_source, scm_procedure_environment,
scm_debug_hang): Added docstrings.
2001-02-16 15:00:41 +00:00
|
|
|
|
"Option interface for the debug options. Instead of using\n"
|
|
|
|
|
|
"this procedure directly, use the procedures @code{debug-enable},\n"
|
2002-03-15 09:40:57 +00:00
|
|
|
|
"@code{debug-disable}, @code{debug-set!} and @code{debug-options}.")
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#define FUNC_NAME s_scm_debug_options
|
1996-08-20 17:08:46 +00:00
|
|
|
|
{
|
|
|
|
|
|
SCM ans;
|
2005-03-07 21:33:18 +00:00
|
|
|
|
|
2007-01-19 19:26:36 +00:00
|
|
|
|
ans = scm_options (setting, scm_debug_opts, FUNC_NAME);
|
1998-11-13 15:58:00 +00:00
|
|
|
|
scm_stack_checking_enabled_p = SCM_STACK_CHECKING_P;
|
2005-03-07 21:33:18 +00:00
|
|
|
|
|
1996-08-20 17:08:46 +00:00
|
|
|
|
return ans;
|
|
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1998-08-21 08:13:36 +00:00
|
|
|
|
|
2009-03-29 17:15:25 -07:00
|
|
|
|
|
1996-10-14 03:25:21 +00:00
|
|
|
|
|
1996-08-20 17:08:46 +00:00
|
|
|
|
|
1999-07-29 21:11:37 +00:00
|
|
|
|
#if 0
|
1999-12-12 02:36:16 +00:00
|
|
|
|
SCM_REGISTER_PROC (s_reverse_lookup, "reverse-lookup", 2, 0, 0, scm_reverse_lookup);
|
1999-07-29 21:11:37 +00:00
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
SCM
|
|
|
|
|
|
scm_reverse_lookup (SCM env, SCM data)
|
|
|
|
|
|
{
|
2004-09-22 17:41:37 +00:00
|
|
|
|
while (scm_is_pair (env) && scm_is_pair (SCM_CAR (env)))
|
1999-07-29 21:11:37 +00:00
|
|
|
|
{
|
2001-03-30 15:03:23 +00:00
|
|
|
|
SCM names = SCM_CAAR (env);
|
|
|
|
|
|
SCM values = SCM_CDAR (env);
|
2004-09-22 17:41:37 +00:00
|
|
|
|
while (scm_is_pair (names))
|
1999-07-29 21:11:37 +00:00
|
|
|
|
{
|
2004-07-27 15:41:49 +00:00
|
|
|
|
if (scm_is_eq (SCM_CAR (values), data))
|
1999-07-29 21:11:37 +00:00
|
|
|
|
return SCM_CAR (names);
|
|
|
|
|
|
names = SCM_CDR (names);
|
|
|
|
|
|
values = SCM_CDR (values);
|
|
|
|
|
|
}
|
2004-09-22 17:41:37 +00:00
|
|
|
|
if (!scm_is_null (names) && scm_is_eq (values, data))
|
1999-07-29 21:11:37 +00:00
|
|
|
|
return names;
|
|
|
|
|
|
env = SCM_CDR (env);
|
|
|
|
|
|
}
|
|
|
|
|
|
return SCM_BOOL_F;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
1996-08-20 17:08:46 +00:00
|
|
|
|
|
|
|
|
|
|
|
1997-03-08 14:43:29 +00:00
|
|
|
|
/* Undocumented debugging procedure */
|
|
|
|
|
|
#ifdef GUILE_DEBUG
|
2000-01-05 19:05:23 +00:00
|
|
|
|
SCM_DEFINE (scm_debug_hang, "debug-hang", 0, 1, 0,
|
1999-12-12 02:36:16 +00:00
|
|
|
|
(SCM obj),
|
(scm_with_traps, scm_memoized_p, scm_make_gloc, scm_gloc_p,
scm_make_iloc, scm_iloc_p, scm_memcons, scm_mem_to_proc,
scm_proc_to_mem, scm_unmemoize, scm_memoized_environment,
scm_procedure_name, scm_procedure_source, scm_procedure_environment,
scm_debug_hang): Added docstrings.
2001-02-16 15:00:41 +00:00
|
|
|
|
"Go into an endless loop, which can be only terminated with\n"
|
|
|
|
|
|
"a debugger.")
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#define FUNC_NAME s_scm_debug_hang
|
1996-11-02 20:53:18 +00:00
|
|
|
|
{
|
|
|
|
|
|
int go = 0;
|
|
|
|
|
|
while (!go) ;
|
|
|
|
|
|
return SCM_UNSPECIFIED;
|
|
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1997-03-08 14:43:29 +00:00
|
|
|
|
#endif
|
1996-11-02 20:53:18 +00:00
|
|
|
|
|
2014-01-23 11:37:36 -05:00
|
|
|
|
static SCM local_eval_var;
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
|
init_local_eval_var (void)
|
|
|
|
|
|
{
|
|
|
|
|
|
local_eval_var = scm_c_public_variable ("ice-9 local-eval", "local-eval");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2012-01-03 04:02:08 -05:00
|
|
|
|
SCM
|
|
|
|
|
|
scm_local_eval (SCM exp, SCM env)
|
|
|
|
|
|
{
|
2014-01-23 11:37:36 -05:00
|
|
|
|
static scm_i_pthread_once_t once = SCM_I_PTHREAD_ONCE_INIT;
|
|
|
|
|
|
scm_i_pthread_once (&once, init_local_eval_var);
|
2012-01-03 04:02:08 -05:00
|
|
|
|
|
2014-01-23 11:37:36 -05:00
|
|
|
|
return scm_call_2 (scm_variable_ref (local_eval_var), exp, env);
|
2012-01-03 04:02:08 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
2009-03-27 15:44:17 -07:00
|
|
|
|
static void
|
|
|
|
|
|
init_stack_limit (void)
|
|
|
|
|
|
{
|
2014-07-03 19:26:21 +03:00
|
|
|
|
#if defined HAVE_GETRLIMIT
|
2009-03-27 15:44:17 -07:00
|
|
|
|
struct rlimit lim;
|
|
|
|
|
|
if (getrlimit (RLIMIT_STACK, &lim) == 0)
|
|
|
|
|
|
{
|
2009-04-03 10:38:30 -07:00
|
|
|
|
rlim_t bytes = lim.rlim_cur;
|
2009-03-27 15:44:17 -07:00
|
|
|
|
|
2009-04-03 10:38:30 -07:00
|
|
|
|
/* set our internal stack limit to 80% of the rlimit. */
|
2009-03-27 15:44:17 -07:00
|
|
|
|
if (bytes == RLIM_INFINITY)
|
|
|
|
|
|
bytes = lim.rlim_max;
|
|
|
|
|
|
|
2009-04-03 10:38:30 -07:00
|
|
|
|
if (bytes != RLIM_INFINITY)
|
|
|
|
|
|
SCM_STACK_LIMIT = bytes * 8 / 10 / sizeof (scm_t_bits);
|
2009-03-27 15:44:17 -07:00
|
|
|
|
}
|
|
|
|
|
|
errno = 0;
|
2014-07-03 19:26:21 +03:00
|
|
|
|
#elif defined __MINGW32__
|
|
|
|
|
|
MEMORY_BASIC_INFORMATION m;
|
|
|
|
|
|
uintptr_t bytes;
|
|
|
|
|
|
|
|
|
|
|
|
if (VirtualQuery ((LPCVOID) &m, &m, sizeof m))
|
|
|
|
|
|
{
|
|
|
|
|
|
bytes = (DWORD_PTR) m.BaseAddress + m.RegionSize
|
|
|
|
|
|
- (DWORD_PTR) m.AllocationBase;
|
|
|
|
|
|
SCM_STACK_LIMIT = bytes * 8 / 10 / sizeof (scm_t_bits);
|
|
|
|
|
|
}
|
2009-03-27 15:44:17 -07:00
|
|
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
|
|
|
1996-11-02 20:53:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
1996-08-20 17:08:46 +00:00
|
|
|
|
void
|
|
|
|
|
|
scm_init_debug ()
|
|
|
|
|
|
{
|
2009-03-27 15:44:17 -07:00
|
|
|
|
init_stack_limit ();
|
2007-01-19 19:26:36 +00:00
|
|
|
|
scm_init_opts (scm_debug_options, scm_debug_opts);
|
1996-09-12 23:39:37 +00:00
|
|
|
|
|
1996-08-20 17:08:46 +00:00
|
|
|
|
scm_add_feature ("debug-extensions");
|
|
|
|
|
|
|
2018-06-20 17:19:31 +02:00
|
|
|
|
#include "debug.x"
|
1996-08-20 17:08:46 +00:00
|
|
|
|
}
|