📄 dbg-cmds.inc
字号:
fi fi ;; # Watch expression watche | We ) _Dbg_do_watch 1 "$args" ;; # intelligent print of variable, function or expression x | examine ) _Dbg_do_x "$args" ;; # List all breakpoints and actions. L ) _Dbg_do_list_brkpt _Dbg_list_watch _Dbg_list_action ;; # Remove all actions A ) _Dbg_do_clear_all_actions $args ;; # Run debugger command history H ) _Dbg_remove_history_item _Dbg_do_history_list $args ;; # S List subroutine names S ) _Dbg_do_list_subroutines $args ;; # Dump variables V ) _Dbg_do_list_variables "$args" ;; # Has to come after !! of "shell" listed above \!* | hi | his | hist | histo | histor | history ) _Dbg_remove_history_item _Dbg_do_history_parse $args if (( $history_num >= 0 )) ; then if (( $history_num < ${#_Dbg_history[@]} )) ; then set ${_Dbg_history[$history_num]} _Dbg_cmd=$1 shift args="$@" _Dbg_redo=1; else _Dbg_msg \ "Number $history_num should be less than ${#_Dbg_history[@]}" fi fi ;; * ) _Dbg_msg "Undefined command: \"$_Dbg_cmd\". Try \"help\"." _Dbg_remove_history_item ;; esac done # while (( $_Dbg_redo )) IFS=$_Dbg_space_IFS; eval "_Dbg_prompt=$_Dbg_prompt_str" return 10}# Set up to Debug into another script...# TODO: would work better if instead of using $source_line below# which might have several statements, we could just pick up the next# single statement._Dbg_do_debug() { # set -xv local script_cmd=${@:-$_Dbg_bash_command} # We need to expand variables that might be in $script_cmd. # set_Dbg_nested_debug_cmd is set up to to be eval'd below. local set_Dbg_debug_cmd="local _Dbg_debug_cmd=\"$script_cmd\""; [ -z "$BASH" ] && BASH='bash' eval "$_seteglob" # Add appropriate bash debugging options if [[ $_Dbg_script != 1 ]] ; then # Running "bash --debugger", so prepend "bash --debugger" set_Dbg_debug_cmd="local _Dbg_debug_cmd=\"$BASH --debugger $script_cmd\""; elif [[ $0/// == *bashdb/// ]] ; then # Running "bashdb", so prepend "bash bashdb .." set_Dbg_debug_cmd="local _Dbg_debug_cmd=\"$BASH $0 -q -L $_Dbg_libdir $script_cmd\""; fi eval "$_resteglob" eval $set_Dbg_debug_cmd if (( _Dbg_basename_only )) ; then _Dbg_msg "Debugging new script with $script_cmd" else _Dbg_msg "Debugging new script with $_Dbg_debug_cmd" fi local -r old_quit_on_quit=$BASHDB_QUIT_ON_QUIT export BASHDB_QUIT_ON_QUIT=1 export BASHDB_BASENAME_ONLY="$_Dbg_basename_only" ((BASHDB_LEVEL++)) $_Dbg_debug_cmd ((BASHDB_LEVEL--)) export BASHDB_QUIT_ON_QUIT=$old_quit_on_quit}# V [![pat]] List variables and values for whose variables names which # match pat $1. If ! is used, list variables that *don't* match. # If pat ($1) is omitted, use * (everything) for the pattern._Dbg_do_list_variables() { local _Dbg_old_glob="$GLOBIGNORE" GLOBIGNORE="*" local _Dbg_match="$1" _Dbg_match_inverted=no case ${_Dbg_match} in \!*) _Dbg_match_inverted=yes _Dbg_match=${_Dbg_match#\!} ;; "") _Dbg_match='*' ;; esac local _Dbg_list=`declare -p` local _Dbg_old_ifs=${IFS} IFS="" local _Dbg_temp=${_Dbg_list} _Dbg_list="" local -i i=0 local -a _Dbg_list # GLOBIGNORE protects us against using the result of # a glob expansion, but it doesn't protect us from # actually performing it, and this can bring bash down # with a huge _Dbg_source_ variable being globbed. # So here we disable globbing momentarily set -o noglob for _Dbg_item in ${_Dbg_temp}; do _Dbg_list[${i}]="${_Dbg_item}" i=${i}+1 done set +o noglob IFS=${_Dbg_old_ifs} local _Dbg_item="" local _Dbg_skip=0 local _Dbg_show_cmd="" _Dbg_show_cmd=`echo -e "case \\${_Dbg_item} in \n${_Dbg_match})\n echo yes;;\n*)\necho no;; esac"` for (( i=0; (( i < ${#_Dbg_list[@]} )) ; i++ )) ; do _Dbg_item=${_Dbg_list[$i]} case ${_Dbg_item} in *\ \(\)\ ) _Dbg_skip=1 ;; \}) _Dbg_skip=0 continue esac if [[ _Dbg_skip -eq 1 ]]; then continue fi # Ignore all _Dbg_ variables here because the following # substitutions takes a long while when it encounters # a big _Dbg_source_ case ${_Dbg_item} in _Dbg_*) # Hide/ignore debugger variables. continue; ;; esac _Dbg_item=${_Dbg_item/=/==/} _Dbg_item=${_Dbg_item%%=[^=]*} case ${_Dbg_item} in _=);; *=) _Dbg_item=${_Dbg_item%=} local _Dbg_show=`eval $_Dbg_show_cmd` if [[ "$_Dbg_show" != "$_Dbg_match_inverted" ]]; then if [[ -n ${_Dbg_item} ]]; then local _Dbg_var=`declare -p ${_Dbg_item} 2>/dev/null` if [[ -n "$_Dbg_var" ]]; then # Uncomment the following 3 lines to use literal # linefeeds# _Dbg_var=${_Dbg_var//\\\\n/\\n}# _Dbg_var=${_Dbg_var//#/\n} # Comment the following 3 lines to use literal linefeeds _Dbg_var=${_Dbg_var//\\\\n/\\\\\\n} _Dbg_var=${_Dbg_var///\\n} _Dbg_var=${_Dbg_var#* * } _Dbg_msg ${_Dbg_var} fi fi fi ;; *) ;; esac done GLOBIGNORE=$_Dbg_old_glob}_Dbg_do_eval() { echo ". ${_Dbg_libdir}/dbg-set-d-vars.inc" > $_Dbg_evalfile echo "$@" >> $_Dbg_evalfile if [[ -n $_basdhb_tty ]] ; then . $_Dbg_evalfile >>$_Dbg_tty else . $_Dbg_evalfile fi # We've reset some variables like IFS and PS4 to make eval look # like they were before debugger entry - so reset them now _Dbg_set_debugger_internal}_Dbg_do_file() { local filename if [[ -z "$1" ]] ; then _Dbg_msg "Need to give a filename for the file command" return fi _Dbg_glob_filename $1 if [[ ! -f "$filename" ]] && [[ ! -x "$filename" ]] ; then _Dbg_msg "Source file $filename does not exist as a readable regular file." return fi local filevar=`_Dbg_file2var ${BASH_SOURCE[3]}` _Dbg_set_assoc_scalar_entry "_Dbg_file_cmd_" $filevar "$filename" local source_file="${BASH_SOURCE[3]}" (( _Dbg_basename_only )) && source_file=${source_file##*/} _Dbg_msg "File $filename will be used when $source_file is referenced."}_Dbg_do_kill() { local _Dbg_prompt_output=${_Dbg_tty:-/dev/null} read $_Dbg_edit -p "Do hard kill and terminate the debugger? (y/n): " \ <&$_Dbg_input_desc 2>>$_Dbg_prompt_output if [[ $REPLY = [Yy]* ]] ; then kill -9 $$ fi}_Dbg_do_load() { local filename=$1 if [[ -z "$filename" ]] ; then _Dbg_msg "Need to give a filename for the file command" return fi local full_filename=$(_Dbg_resolve_expand_filename "$filename") if [ -n $full_filename ] && [ -r $full_filename ] ; then # Have we already loaded in this file? for file in ${_Dbg_filenames[@]} ; do if [[ $file = $full_filename ]] ; then _Dbg_msg "File $full_filename already loaded." return fi done _Dbg_readin "$full_filename" _Dbg_msg "File $full_filename loaded." else _Dbg_msg "Couldn't resolve or read $filename" fi}_Dbg_do_next_step_skip() { if (( ! _Dbg_running )) ; then _Dbg_msg "The program is not being run." return fi local cmd=$1 local count=${2:-1} # Do we step debug into functions called or not? if [[ $cmd == n* ]] ; then _Dbg_old_set_opts="$_Dbg_old_set_opts +o functrace" else _Dbg_old_set_opts="$_Dbg_old_set_opts -o functrace" fi _Dbg_write_journal "_Dbg_old_set_opts=\"$_Dbg_old_set_opts\"" if [[ $count == [0-9]* ]] ; then let _Dbg_steps=${count:-1} else _Dbg_msg "Argument ($count) should be a number or nothing." _Dbg_steps=1 fi _Dbg_write_journal "_Dbg_steps=$_Dbg_steps"}_Dbg_do_print() { local -r _Dbg_expr=${@:-"$_Dbg_last_print_args"} local -r dq_expr=$(_Dbg_esc_dq "$_Dbg_expr") . ${_Dbg_libdir}/dbg-set-d-vars.inc eval "_Dbg_msg $_Dbg_expr" _Dbg_last_print_args="$dq_expr"}_Dbg_do_pwd() { local _Dbg_cwd=$(pwd) (( _Dbg_basename_only )) && _Dbg_cwd=${_Dbg_cwd##*/} _Dbg_msg "Working directory ${_Dbg_cwd}."}# Restart script in same way with saved arguments (probably the same# ones as we were given before)._Dbg_do_restart() { _Dbg_cleanup; local script_args if (( $# != 0 )) ; then script_args="$@" else script_args="${_Dbg_script_args[@]}" fi local exec_cmd="$0 $script_args"; if [[ $_Dbg_script != 1 ]] ; then [ -z "$BASH" ] && BASH='bash' if [ $_cur_source_file == $_Dbg_bogus_file ] ; then script_args="--debugger -c \"$BASH_EXECUTION_STRING\"" exec_cmd="$BASH --debugger -c \"$BASH_EXECUTION_STRING\""; else exec_cmd="$BASH --debugger $0 $script_args"; fi elif [[ -n "$BASH" ]] ; then local exec_cmd="$BASH $0 $script_args"; fi if (( _Dbg_basename_only )) ; then _Dbg_msg "Restarting with: $script_args" else _Dbg_msg "Restarting with: $exec_cmd" fi # If we are in a subshell we need to get out of those levels # first before we restart. The strategy is to write into persistent # storage the restart command, and issue a "quit." The quit should # discover the restart at the last minute and issue the restart. if (( BASH_SUBSHELL > 0 )) ; then _Dbg_msg "Note you are in a subshell. We will need to leave that first." _Dbg_write_journal "BASHDB_RESTART_COMMAND=\"$exec_cmd\"" _Dbg_do_quit 0 fi _Dbg_save_state cd $_Dbg_init_cwd exec $exec_cmd}# Handle command-file source. If the filename's okay we just increase the# input-file descriptor by one and redirect input which will# be picked up in next debugger command loop._Dbg_do_source() { local filename if [[ -z "$1" ]] ; then _Dbg_msg "Need to give a filename for the source command" return fi _Dbg_glob_filename $1 if [[ -r $filename ]] || [[ "$filename" == '/dev/stdin' ]] ; then if ((_Dbg_input_desc < _Dbg_MAX_INPUT_DESC )) ; then ((_Dbg_input_desc++)) _Dbg_input[$_Dbg_input_desc]=$filename local _Dbg_redirect_cmd="exec $_Dbg_input_desc<$filename" eval $_Dbg_redirect_cmd _Dbg_cmdfile[${#_Dbg_cmdfile[@]}]=$filename else local -i max_nesting ((max_nesting=_Dbg_MAX_INPUT_DESC-_Dbg_INPUT_START_DESC+1)) _Dbg_msg "Source nesting too deep; nesting can't be greater than $max_nesting." fi else _Dbg_msg "Source file $filename is not readable." fi}# toggle execution trace feature_Dbg_do_trace() { ((_Dbg_linetrace=!$_Dbg_linetrace)) _Dbg_msg "Line trace = \c" let " $_Dbg_linetrace" && _Dbg_msg "on" || _Dbg_msg "off"}# Set output tty_Dbg_do_tty() { if [[ -z "$1" ]] ; then _Dbg_msg "Argument required (terminal name for running target process)." return 1 fi if ! $(touch $1 >/dev/null 2>/dev/null); then _Dbg_msg "Can't access $1 for writing." return 1 fi if [[ ! -w $1 ]] ; then _Dbg_msg "tty $1 needs to be writable" return 1 fi _Dbg_tty=$1 return 0}_Dbg_do_x() { local -r _Dbg_expr=${@:-"$_Dbg_last_x_args"} local _Dbg_result if (( `_Dbg_is_var $_Dbg_expr` )) ; then _Dbg_result=`declare -p $_Dbg_expr` _Dbg_msg "$_Dbg_result" elif (( `_Dbg_is_function $_Dbg_expr` )) ; then _Dbg_result=`declare -f $_Dbg_expr` _Dbg_msg "$_Dbg_result" else local -i _Dbg_rc eval let _Dbg_result=$_Dbg_expr 2>/dev/null; _Dbg_rc=$? if (( $_Dbg_rc != 0 )) ; then _Dbg_do_print "$_Dbg_expr" else _Dbg_msg "$_Dbg_result" fi fi _Dbg_last_x_args="$_Dbg_x_args"}_Dbg_save_state() { _Dbg_statefile=`_Dbg_tempname statefile` echo "" > $_Dbg_statefile _Dbg_save_breakpoints _Dbg_save_actions _Dbg_save_watchpoints _Dbg_save_display _Dbg_save_Dbg_set echo "unset BASHDB_RESTART_FILE" >> $_Dbg_statefile echo "rm $_Dbg_statefile" >> $_Dbg_statefile export BASHDB_RESTART_FILE="$_Dbg_statefile" _Dbg_write_journal "export BASHDB_RESTART_FILE=\"$_Dbg_statefile\""}_Dbg_save_Dbg_set() { declare -p _Dbg_basename_only >> $_Dbg_statefile declare -p _Dbg_debug_debugger >> $_Dbg_statefile declare -p _Dbg_edit >> $_Dbg_statefile declare -p _Dbg_listsize >> $_Dbg_statefile declare -p _Dbg_prompt_str >> $_Dbg_statefile declare -p _Dbg_show_command >> $_Dbg_statefile}_Dbg_restore_state() { local statefile=$1 . $1}# ================== INITIALIZATION =====================================if [[ -r /dev/stdin ]] ; then _Dbg_do_source /dev/stdinelif [[ $(tty) != 'not a tty' ]] ; then _Dbg_do_source $(tty)fi# List of command files to processtypeset -a _Dbg_input# Have we already specified where to read debugger input from?# Note: index 0 is only set by bashdb. It is not used otherwise for I/O# like those indices >= _Dbg_INPUT_START_DESC are.if [ -n "$BASHDB_INPUT" ] ; then _Dbg_input=($BASHDB_INPUT) _Dbg_do_source ${_Dbg_input[0]} _Dbg_no_init=1fiif [[ -z $_Dbg_no_init && -r ~/.bashdbinit ]] ; then _Dbg_do_source ~/.bashdbinitfi# BASHDB_LEVEL is the number of times we are nested inside a debugger# by virtue of running "debug" for example.if [[ -z "${BASHDB_LEVEL}" ]] ; then typeset -i BASHDB_LEVEL=1 export BASHDB_LEVELfi# temp file for internal eval'd commandstypeset _Dbg_evalfile=`_Dbg_tempname eval`# File to save information that needs to be passed from a subshell# to a parent shelltypeset _Dbg_journal=`_Dbg_tempname journal`if [ ! -f _Dbg_journal ] ; then typeset -i BASHDB_QUIT_LEVELS=0 _Dbg_write_journal "BASHDB_QUIT_LEVELS=0"fi# 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._Dbg_cmds_ver='$Id: dbg-cmds.inc,v 1.30 2007/03/03 05:02:30 rockyb Exp $'#;;; Local Variables: ***#;;; mode:shell-script ***#;;; End: ***
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -