1# -*- shell-script -*- 2# save-restore.sh - saves, sets and restores debugger vars on hook entry 3# 4# Copyright (C) 2002-2005, 2007-2011, 5# 2014, 2017 Rocky Bernstein <rocky@gnu.org> 6# 7# This program is free software; you can redistribute it and/or 8# modify it under the terms of the GNU General Public License as 9# published by the Free Software Foundation; either version 2, or 10# (at your option) any later version. 11# 12# This program is distributed in the hope that it will be useful, 13# but WITHOUT ANY WARRANTY; without even the implied warranty of 14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15# General Public License for more details. 16# 17# You should have received a copy of the GNU General Public License 18# along with this program; see the file COPYING. If not, write to 19# the Free Software Foundation, 59 Temple Place, Suite 330, Boston, 20# MA 02111 USA. 21 22# Does things to after on entry of after an eval to set some debugger 23# internal settings 24function _Dbg_set_debugger_internal { 25 IFS="$_Dbg_space_IFS"; 26 PS4='+ dbg (${BASH_SOURCE}:${LINENO}[$BASH_SUBSHELL]): ${FUNCNAME[0]}\n' 27} 28 29function _Dbg_restore_user_vars { 30 IFS="$_Dbg_space_IFS"; 31 (( _Dbg_old_set_nullglob == 0 )) && shopt -s nullglob 32 set -$_Dbg_old_set_opts 33 IFS="$_Dbg_old_IFS"; 34 PS4="$_Dbg_old_PS4" 35} 36 37_Dbg_save_args() { 38 39 # Save values of $1 $2 $3 when debugged program was stopped 40 # We use the loop below rather than _Dbg_set_args="(@)" because 41 # we want to preserve embedded blanks in the arguments. 42 typeset -i _Dbg_n=${#@} 43 typeset -i _Dbg_i 44 typeset -i _Dbg_arg_max=${#_Dbg_arg[@]} 45 46 # If there has been a shift since the last time we entered, 47 # it is possible that _Dbg_arg will contain too many values. 48 # So remove those that have disappeared. 49 for (( _Dbg_i=_Dbg_arg_max; _Dbg_i > _Dbg_n ; _Dbg_i-- )) ; do 50 unset _Dbg_arg[$_Dbg_i] 51 done 52 53 _Dbg_dollar_0=$0 54 # Populate _Dbg_arg with $1, $2, etc. 55 for (( _Dbg_i=1 ; _Dbg_n > 0; _Dbg_n-- )) ; do 56 _Dbg_arg[$_Dbg_i]="$1" 57 ((_Dbg_i++)) 58 shift 59 done 60 unset _Dbg_arg[0] # Get rid of line number; makes array count 61 # correct; also listing all _Dbg_arg works 62 # like $*. 63} 64 65# Do things for debugger entry. Set some global debugger variables 66# Remove trapping ourselves. 67# We assume that we are nested two calls deep from the point of debug 68# or signal fault. If this isn't the constant 2, then consider adding 69# a parameter to this routine. 70 71function _Dbg_set_debugger_entry { 72 # Nuke DEBUG trap 73 trap '' DEBUG 74 75 # How many function are on the stack that are part of the debugger? 76 # Normally this gets called from the trace hook. so this routine plus 77 # the trace hook should are on the FUNCNAME stack and should be ignored 78 typeset -li discard_top_fn_count=${1:-2} 79 80 _Dbg_cur_fn=${FUNCNAME[$discard_top_fn_count]} 81 _Dbg_frame_last_lineno=${BASH_LINENO[1]} 82 ((_Dbg_frame_last_lineno < 1)) && let _Dbg_frame_last_lineno=1 83 84 _Dbg_old_IFS="$IFS" 85 _Dbg_old_PS4="$PS4" 86 ((_Dbg_stack_size = ${#FUNCNAME[@]} + 1 - discard_top_fn_count)) 87 _Dbg_stack_pos=_0 88 _Dbg_listline=_Dbg_frame_last_lineno 89 _Dbg_set_debugger_internal 90 _Dbg_frame_last_filename=${BASH_SOURCE[$discard_top_fn_count]:-$_Dbg_bogus_file} 91 _Dbg_frame_last_filename=$(_Dbg_resolve_expand_filename "$_Dbg_frame_last_filename") 92 93 # Read in the journal to pick up variable settings that might have 94 # been left from a subshell. 95 _Dbg_source_journal 96 97 if (( _Dbg_QUIT_LEVELS > 0 )) ; then 98 _Dbg_do_quit $_Dbg_debugged_exit_code 99 fi 100} 101 102function _Dbg_set_to_return_from_debugger { 103 104 _Dbg_stop_reason='' 105 _Dbg_listline=0 106 # FIXME: put in a frame setup routine and remove from set_entry 107 _Dbg_last_lineno=${_Dbg_frame_last_lineno} 108 if (( $1 != 0 )) ; then 109 _Dbg_last_bash_command="$_Dbg_bash_command" 110 _Dbg_last_source_file="$_Dbg_frame_last_filename" 111 else 112 _Dbg_last_lineno=${BASH_LINENO[1]} 113 _Dbg_last_source_file=${BASH_SOURCE[2]:-$_Dbg_bogus_file} 114 _Dbg_last_bash_command="**unsaved _bashdb command**" 115 fi 116 117 if (( _Dbg_restore_debug_trap )) ; then 118 trap '_Dbg_debug_trap_handler 0 "$BASH_COMMAND" "$@"' DEBUG 119 else 120 trap - DEBUG 121 fi 122 123 _Dbg_restore_user_vars 124} 125 126_Dbg_save_state() { 127 _Dbg_statefile=$(_Dbg_tempname statefile) 128 echo '' > $_Dbg_statefile 129 _Dbg_save_breakpoints 130 _Dbg_save_actions 131 _Dbg_save_watchpoints 132 _Dbg_save_display 133 _Dbg_save_Dbg_set 134 echo "unset DBG_RESTART_FILE" >> $_Dbg_statefile 135 echo "rm $_Dbg_statefile" >> $_Dbg_statefile 136 export DBG_RESTART_FILE="$_Dbg_statefile" 137 _Dbg_write_journal "export DBG_RESTART_FILE=\"$_Dbg_statefile\"" 138} 139 140_Dbg_save_Dbg_set() { 141 declare -p _Dbg_set_basename >> $_Dbg_statefile 142 declare -p _Dbg_set_debug >> $_Dbg_statefile 143 declare -p _Dbg_edit >> $_Dbg_statefile 144 declare -p _Dbg_set_listsize >> $_Dbg_statefile 145 declare -p _Dbg_prompt_str >> $_Dbg_statefile 146 declare -p _Dbg_set_show_command >> $_Dbg_statefile 147} 148 149_Dbg_restore_state() { 150 typeset statefile=$1 151 . $1 152} 153 154# Things we do when coming back from a nested shell. 155# "shell", and "debug" create nested shells. 156_Dbg_restore_from_nested_shell() { 157 rm -f $_Dbg_shell_temp_profile 2>&1 >/dev/null 158 if [[ -r $_Dbg_restore_info ]] ; then 159 . $_Dbg_restore_info 160 rm $_Dbg_restore_info 161 fi 162} 163