📄 dbg-sig.inc
字号:
_Dbg_subst_handler_var() { local -i i local result='' for arg in $* ; do case $arg in '$LINENO' ) arg='${BASH_LINENO[0]}' ;; '${BASH_SOURCE[0]}' ) arg='${BASH_SOURCE[1]}' ;; '${FUNCNAME[0]}' ) arg='${FUNCNAME[1]}' ;; '${BASH_LINENO[0]}' ) arg='${BASH_LINENO[1]}' ;; esac if [[ $result == '' ]] ; then result=$arg else result="$result $arg" fi done echo $result}# Debugger exit handler. Don't really exit - but go back the debugger # command loop_Dbg_exit_handler() { # Consider putting the following line(s) in a routine. # Ditto for the restore environment local -i _Dbg_debugged_exit_code=$? # Turn off line and variable trace listing; allow unset parameter expansion. set +x +v +u if [[ ${_Dbg_sig_print[0]} == "print" ]] ; then # Note: use the same message that gdb does for this. _Dbg_msg "Program received signal EXIT (0)..." if [[ ${_Dbg_sig_show_stack[0]} == "showstack" ]] ; then _Dbg_do_stack_trace 0 fi fi if [[ $_Dbg_old_EXIT_handler != '' ]] ; then eval $_Dbg_old_EXIT_handler fi # If we've set the QUIT signal handler not to stop, or we've in the # middle of leaving so many (subshell) levels or we have set to # leave quietly on termination, then do it! if [[ ${_Dbg_sig_stop[0]} != "stop" ]] \ || (( BASHDB_QUIT_LEVELS != 0 )) \ || (( BASHDB_QUIT_ON_QUIT )) ; then _Dbg_do_quit # We don't return from here. fi # We've tested for all the quitting conditions above. # Even though this is an exit handler, don't exit! local term_msg="normally" if [[ $_Dbg_debugged_exit_code != 0 ]] ; then term_msg="with code $_Dbg_debugged_exit_code" fi # If we tried to exit from inside a subshell, we only want to enter # the command loop if don't have any pending subshells. if (( BASH_SUBSHELL == 0 )) ; then _Dbg_msg \ "Debugged program terminated $term_msg. Use q to quit or R to restart." _Dbg_running=0 while [[ 1 ]] ; do _Dbg_cmdloop done fi}# Generic signal handler for bashdb. We consult global array# _Dbg_sig_* for how to handle this signal.# Since the command loop may be called we need to be careful about# using variable names that would be exposed to the user. _Dbg_sig_handler() { # Consider putting the following line(s) in a routine. # Ditto for the restore environment local -i _Dbg_debugged_exit_code=$? _Dbg_old_set_opts=$- # Turn off line and variable trace listing; allow unset parameter expansion. set +x +v +u shopt -s extdebug local -i _Dbg_rc=0 # This is the signal number. E.g. 15 is SIGTERM local -r -i _Dbg_signum=$1 if [[ ${_Dbg_sig_print[$_Dbg_signum]} == "print" ]] || \ [[ ${_Dbg_sig_stop[$_Dbg_signum]} == "stop" ]] ; then local -r name=`_Dbg_signum2name $_Dbg_signum` # Note: use the same message that gdb does for this. _Dbg_msg "Program received signal $name ($_Dbg_signum)..." if [[ ${_Dbg_sig_show_stack[$_Dbg_signum]} == "showstack" ]] ; then local -i n=${#FUNCNAME[@]} _Dbg_do_stack_trace 0 $n 0 fi fi if [[ ${_Dbg_sig_stop[$_Dbg_signum]} == "stop" ]] ; then ### The below duplicates what is above in _Dbg_debug_trap handler ### Should put common stuff into a function. shift # signum _Dbg_bash_command=$1 shift # Save values of $1 $2 $3 when debugged program was stopped # We use the loop below rather than _Dbg_set_args="(@)" because # we want to preserve embedded blanks in the arguments. local -i _Dbg_n=${#@} local -i _Dbg_i=1 for (( ; _Dbg_n > 0; _Dbg_n-- )) ; do _Dbg_arg[$_Dbg_i]=$1 ((_Dbg_i++)) shift done unset _Dbg_arg[0] # Get rid of line number; makes array count # correct; also listing all _Dbg_arg works # like $*. _Dbg_set_debugger_entry _Dbg_cmdloop # enter debugger _Dbg_set_to_return_from_debugger 1 return $_Dbg_rc elif (( _Dbg_sig_old_handler[_Dbg_signum] )) ; then eval ${_Dbg_sig_old_handler[$_Dbg_signum]} fi _Dbg_set_to_return_from_debugger 1 return $_Dbg_debugged_exit_code}_Dbg_err_handler() { if [[ $_Dbg_old_ERR_handler != '' ]] ; then eval $_Dbg_old_ERR_handler fi _Dbg_msg "Error occured at ${BASH_SOURCE[1]}:${BASH_LINENO[1]}" _Dbg_cmdloop}# Echo the name for a given signal number $1. The resulting name# is in _Dbg_return_Dbg_signum2name() { local -i -r signum=$1; builtin kill -l $signum 2>/dev/null return $?}# Return the signal number for a given signal name $1. The resulting number# is in _Dbg_return_Dbg_name2signum() { local -r signame=$1; builtin kill -l $signame 2>/dev/null return $?}# Process debugger "handle" command. _Dbg_do_handle() { local sig=$1 local cmd=$2 local -i signum if [[ -z $sig ]] ; then _Dbg_msg "Missing signal name or signal number." return 1 fi eval "$_seteglob" if [[ $sig == $int_pat ]]; then eval "$_resteglob" signame=`_Dbg_signum2name $sig` if (( $? != 0 )) ; then _Dbg_msg "Bad signal number: $sig" return 1 fi signum=sig else eval "$_resteglob" local signum; signum=`_Dbg_name2signum $sig` if (( $? != 0 )) ; then _Dbg_msg "Bad signal name: $sig" return 1 fi fi case $cmd in nop | nopr | nopri | noprin | noprint ) _Dbg_sig_print[signum]='noprint' # noprint implies nostop _Dbg_sig_stop[signum]='stop' ;; nosta | nostac | nostack ) _Dbg_sig_show_stack[signum]='nostack' ;; nosto | nostop ) _Dbg_sig_stop[signum]='nostop' ;; p | pr | pri | prin | print ) _Dbg_sig_print[signum]='print' ;; sta | stac | stack ) _Dbg_sig_show_stack[signum]='showstack' ;; sto | stop ) _Dbg_sig_stop[signum]='stop' # stop keyword implies print _Dbg_sig_print[signum]='print' ;; * ) if (( !cmd )) ; then _Dbg_msg \ "Need to give a command: stop, nostop, stack, nostack, print, noprint" else _Dbg_msg "Invalid handler command $cmd" fi ;; esac}# Process debugger "signal" command. _Dbg_do_signal() { local sig=$1 local -i signum if [[ -z $sig ]] ; then _Dbg_msg "Missing signal name or signal number." return 1 fi eval "$_seteglob" if [[ $sig == $int_pat ]]; then eval "$_resteglob" signame=`_Dbg_signum2name $sig` if (( $? != 0 )) ; then _Dbg_msg "Bad signal number: $sig" return 1 fi signum=sig else eval "$_resteglob" local signum; signum=`_Dbg_name2signum $sig` if (( $? != 0 )) ; then _Dbg_msg "Bad signal name: $sig" return 1 fi fi kill -$signum $$}_Dbg_subexit_handler() { # Read in the journal to pick up variable settings that might have # been left from a subshell. if [[ ${FUNCNAME[1]} == _Dbg_* ]] && (( !_Dbg_debug_debugger )); then return 0 fi _Dbg_source_journal if (( $BASHDB_QUIT_LEVELS > 0 )) ; then __Dbg_do_quit $_Dbg_debugged_exit_code fi}# Set up generic trap handler. Arguments are: # NAME print showstack stop passthrough_Dbg_init_trap() { local -r name=$1 local -i -r signum=`_Dbg_name2signum $name` _Dbg_sig_print[$signum]=$2; _Dbg_sig_show_stack[$signum]=$3; _Dbg_sig_stop[$signum]=$4; # Work out passthrough later... # if [[ $5 == "pass*" ]] ; then # get existing trap from env. # _Dbg_sig_show_passthrough[$signum]=....; # if (( signum == 0 )) ; then trap '_Dbg_exit_handler "$BASH_COMMAND"' EXIT else local trap_cmd="trap '_Dbg_sig_handler $signum \"\$BASH_COMMAND\" \"\$@\"' $name" eval $trap_cmd fi}_Dbg_init_trap EXIT "noprint" "nostack" "stop" _Dbg_init_trap ILL "print" "showstack" "stop" _Dbg_init_trap INT "print" "showstack" "stop" _Dbg_init_trap QUIT "print" "showstack" "stop" _Dbg_init_trap TERM "print" "showstack" "stop" _Dbg_init_trap TRAP "print" "showstack" "stop" # This is put at the so we have something at the end to stop at # when we debug this. By stopping at the end all of the above functions# and variables can be tested.typeset -r _Dbg_sig_ver=\'$Id: dbg-sig.inc,v 1.21 2007/03/03 05:02:30 rockyb Exp $'#;;; Local Variables: ***#;;; mode:shell-script ***#;;; End: ***
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -