Please consider the patch below, which fixes the following: * When starting a shell with both $BASHOPTS in the environment and -O optname options, processing of environmental $BASHOPTS was blocked due to the variable already being present and readonly by this time. * When extdebug was toggled, it caused toggling only of functrace, not of both functrace and errtrace, as described in the docs * When extdebug was toggled, SHELLOPTS were not being updated to reflect the new err/functrace state * When the shell did not enable extdebug due to the debugger init file not being present, $BASHOPTS was not being updated to reflect this change.
diff --git a/builtins/shopt.def b/builtins/shopt.def index c4a75ea..dacdf01 100644 --- a/builtins/shopt.def +++ b/builtins/shopt.def @@ -361,6 +361,7 @@ toggle_shopts (mode, list, quiet) { WORD_LIST *l; int ind, rval; + SHELL_VAR *v; for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next) { @@ -377,8 +378,15 @@ toggle_shopts (mode, list, quiet) (*shopt_vars[ind].set_func) (shopt_vars[ind].name, mode); } } + + /* don't run set_bashopts here if $BASHOPTS has not been set yet + because that means we have not yet called initialize_shell_variables + followed by initialize_bashopts. The latter will take care of + setting up $BASHOPTS after the environment has been parsed */ + v = find_variable ("BASHOPTS"); + if (v) + set_bashopts (); - set_bashopts (); return (rval); } @@ -529,7 +537,8 @@ shopt_set_debug_mode (option_name, mode) int mode; { #if defined (DEBUGGER) - function_trace_mode = debugging_mode; + error_trace_mode = function_trace_mode = debugging_mode; + set_shellopts (); #endif return (0); } diff --git a/shell.c b/shell.c index 0c83f63..d76b8e8 100644 --- a/shell.c +++ b/shell.c @@ -1456,10 +1456,11 @@ start_debugger () if (r < 0) { internal_warning ("cannot start debugger; debugging mode disabled"); - debugging_mode = function_trace_mode = 0; + debugging_mode = 0; } - else - function_trace_mode = 1; + error_trace_mode = function_trace_mode = debugging_mode; + set_shellopts (); + set_bashopts (); exit_immediately_on_error += old_errexit; #endif