⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dbg-brk.inc

📁 bash debugger. You can use this tool to debug bash shell script
💻 INC
📖 第 1 页 / 共 2 页
字号:
# dbg-brk.inc - Bourne Again Shell Debugger Break/Watch/Action routines#   Copyright (C) 2002, 2003, 2006, 2007 Rocky Bernstein #   rockyb@users.sourceforge.net##   Bash is free software; you can redistribute it and/or modify it under#   the terms of the GNU General Public License as published by the Free#   Software Foundation; either version 2, or (at your option) any later#   version.##   Bash is distributed in the hope that it will be useful, but WITHOUT ANY#   WARRANTY; without even the implied warranty of MERCHANTABILITY or#   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License#   for more details.#   #   You should have received a copy of the GNU General Public License along#   with Bash; see the file COPYING.  If not, write to the Free Software#   Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA.#================ VARIABLE INITIALIZATIONS ====================#declare -r _Dbg_brk_ver=\'$Id: dbg-brk.inc,v 1.15 2007/03/02 07:56:34 rockyb Exp $'typeset -ar _Dbg_yn=("n" "y")         typeset -ar _Dbg_keep=('keep' 'del')  # action data structurestypeset -ai _Dbg_action_line=()     # Line number of breakpointtypeset -a  _Dbg_action_file=()     # filename of breakpointtypeset -ai _Dbg_action_enable=()   # 1/0 if enabled or nottypeset -a  _Dbg_action_stmt=()     # Statement to eval when line is hit.typeset -i  _Dbg_action_max=0       # Needed because we can't figure                                        # out what the max index is and arrays                                        # can be sparse# Note: we loop over possibly sparse arrays with _Dbg_brkpt_max by adding one# and testing for an entry. Could add yet another array to list only # used indices. Bash is kind of primitive.# Breakpoint data structurestypeset -ai _Dbg_brkpt_line=()     # Line number of breakpointtypeset -a  _Dbg_brkpt_file=()     # filename of breakpointtypeset -a  _Dbg_brkpt_enable=()   # 1/0 if enabled or nottypeset -ai _Dbg_brkpt_count=()    # Number of times hittypeset -ai _Dbg_brkpt_onetime=()  # Is this a onetime break?typeset -a  _Dbg_brkpt_cond=()     # Condition to eval true in order to stop.typeset -i  _Dbg_brkpt_max=0       # Needed because we can't figure out what                               # the max index is and arrays can be sparse# Note: we loop over possibly sparse arrays with _Dbg_brkpt_max by adding one# and testing for an entry. Could add yet another array to list only # used indices. Bash is kind of primitive.# Watchpoint data structurestypeset -a  _Dbg_watch_exp=() # Watchpoint expressionstypeset -a  _Dbg_watch_val=() # values of watchpoint expressionstypeset -ai _Dbg_watch_arith=()  # 1 if arithmetic expression or not.typeset -ai _Dbg_watch_count=()  # Number of times hittypeset -ai _Dbg_watch_enable=() # 1/0 if enabled or nottypeset -i  _Dbg_watch_max=0     # Needed because we can't figure out what                                    # the max index is and arrays can be sparsetypeset -r  _watch_pat="${int_pat}[wW]"# Display data structurestypeset -a  _Dbg_disp_exp=() # Watchpoint expressionstypeset -ai _Dbg_disp_enable=() # 1/0 if enabled or nottypeset -i  _Dbg_disp_max=0     # Needed because we can't figure out what                                    # the max index is and arrays can be sparse#========================= FUNCTIONS   ============================## Error message for file not read in_Dbg_file_not_read_in() {    local -r filename=$(_Dbg_adjust_filename "$1")    _Dbg_msg "File $filename not found in read-in files."    _Dbg_msg "See 'info files' for a list of known files and"    _Dbg_msg "'load' to read in a file."}# Common routine for setup of commands that take a single# linespec argument. We assume the following variables # which we store into:#  filename, line_number, full_filename_Dbg_linespec_setup() {  local linespec=${1:-''}  if [[ -z $linespec ]] ; then    _Dbg_msg "Invalid line specification, null given"  fi  local -a word=($(_Dbg_parse_linespec "$linespec"))  if [[ ${#word[@]} == 0 ]] ; then    _Dbg_msg "Invalid line specification: $linespec"    return  fi    filename=${word[2]}  local -ir is_function=${word[1]}  line_number=${word[0]}  full_filename=`_Dbg_is_file $filename`  if (( is_function )) ; then      if [[ -z $full_filename ]] ; then 	  _Dbg_readin "$filename"	  full_filename=`_Dbg_is_file $filename`      fi  fi}# Error message for file not read in_Dbg_file_not_read_in() {    local -r filename=$(_Dbg_adjust_filename ${1:-""})    _Dbg_msg "File $filename not found in read-in files."    _Dbg_msg "See 'info files' for a list of known files and"    _Dbg_msg "'load' to read in a file."}_Dbg_save_breakpoints() {  local file  for file in ${_Dbg_filenames[@]} ; do      local filevar="`_Dbg_file2var $file`"    declare -p _Dbg_brkpt_$filevar >> $_Dbg_statefile 2>/dev/null  done          declare -p _Dbg_brkpt_line >> $_Dbg_statefile  declare -p _Dbg_brkpt_file >> $_Dbg_statefile   declare -p _Dbg_brkpt_cond >> $_Dbg_statefile   declare -p _Dbg_brkpt_count >> $_Dbg_statefile   declare -p _Dbg_brkpt_enable >> $_Dbg_statefile  declare -p _Dbg_brkpt_onetime >> $_Dbg_statefile  declare -p _Dbg_brkpt_max >> $_Dbg_statefile}_Dbg_save_actions() {  for file in ${_Dbg_filenames[@]} ; do      local filevar="`_Dbg_file2var $file`"    declare -p _Dbg_action_$filevar >> $_Dbg_statefile 2>/dev/null  done          declare -p _Dbg_action_line >> $_Dbg_statefile  declare -p _Dbg_action_file >> $_Dbg_statefile  declare -p _Dbg_action_enable >> $_Dbg_statefile  declare -p _Dbg_action_stmt >> $_Dbg_statefile  declare -p _Dbg_action_max >> $_Dbg_statefile}_Dbg_save_watchpoints() {  declare -p _Dbg_watch_exp >> $_Dbg_statefile  declare -p _Dbg_watch_val >> $_Dbg_statefile  declare -p _Dbg_watch_arith >> $_Dbg_statefile  declare -p _Dbg_watch_count >> $_Dbg_statefile  declare -p _Dbg_watch_enable >> $_Dbg_statefile  declare -p _Dbg_watch_max >> $_Dbg_statefile}_Dbg_save_display() {  declare -p _Dbg_disp_exp >> $_Dbg_statefile  declare -p _Dbg_disp_enable >> $_Dbg_statefile  declare -p _Dbg_disp_max >> $_Dbg_statefile}# Start out with general break/watchpoint functions first...# Routine to a delete breakpoint/watchpoint by entry numbers._Dbg_do_delete() {  local -r  to_go=$@  local -i  i  local -i  found=0    # set -xv  eval "$_seteglob"  for del in $to_go ; do     case $del in      $_watch_pat )        _Dbg_delete_watch_entry ${del:0:${#del}-1}        ;;      $int_pat )	_Dbg_delete_brkpt_entry $del        ((found += $?))	;;      * )	_Dbg_msg "Invalid entry number skipped: $del"    esac  done  eval "$_resteglob"  [[ $found != 0 ]] && _Dbg_msg "Removed $found breakpoint(s)."  return $found  # set +xv}# Enable/disable breakpoint or watchpoint by entry numbers._Dbg_enable_disable() {  if [ -z "$1" ] ; then     _Dbg_msg "Expecting a list of breakpoint/watchpoint numbers. Got none."    return 1  fi  local -i on=$1  local en_dis=$2  shift; shift  if [[ $1 = 'display' ]] ; then    shift    local to_go="$@"    local i    eval "$_seteglob"    for i in $to_go ; do       case $i in	$int_pat )	  _Dbg_enable_disable_display $on $en_dis $i	;;	* )	  _Dbg_msg "Invalid entry number skipped: $i"      esac    done    eval "$_resteglob"    return 0  elif [[ $1 = 'action' ]] ; then    shift    local to_go="$@"    local i    eval "$_seteglob"    for i in $to_go ; do       case $i in	$int_pat )	  _Dbg_enable_disable_action $on $en_dis $i	;;	* )	  _Dbg_msg "Invalid entry number skipped: $i"      esac    done    eval "$_resteglob"    return 0  fi  local to_go="$@"  local i  eval "$_seteglob"  for i in $to_go ; do     case $i in      $_watch_pat )        _Dbg_enable_disable_watch $on $en_dis ${del:0:${#del}-1}        ;;      $int_pat )        _Dbg_enable_disable_brkpt $on $en_dis $i	;;      * )      _Dbg_msg "Invalid entry number skipped: $i"    esac  done  eval "$_resteglob"  return 0}_Dbg_do_continue() {  # set -xv  if (( ! _Dbg_running )) ; then      _Dbg_msg "The program is not being run."      return  fi  [[ -z "$1" ]] && return 0  local filename  local -i line_number  local full_filename  _Dbg_linespec_setup $1  if [[ -n $full_filename ]] ; then     if (( $line_number ==  0 )) ; then       _Dbg_msg "There is no line 0 to continue at."    else       _Dbg_check_line $line_number "$full_filename"      (( $? == 0 )) && \	_Dbg_set_brkpt "$full_filename" "$line_number" 1 1      return 0    fi  else    _Dbg_file_not_read_in $filename  fi  return 1}# Enable breakpoint(s)/watchpoint(s) by entry number(s)._Dbg_do_enable() {  _Dbg_enable_disable 1 "enabled" $@}# Disable breakpoint(s)/watchpoint(s) by entry number(s)._Dbg_do_disable() {  _Dbg_enable_disable 0 "disabled" $@}_Dbg_print_brkpt_count() {  local -ir i=$1  if (( _Dbg_brkpt_count[$i] != 0 )) ; then    if (( _Dbg_brkpt_count[$i] == 1 )) ; then       _Dbg_printf "\tbreakpoint already hit 1 time"     else      _Dbg_printf "\tbreakpoint already hit %d times" ${_Dbg_brkpt_count[$i]}    fi  fi}#======================== BREAKPOINTS  ============================## Add breakpoint(s) at given line number of the current file.  $1 is# the line number or _curline if omitted.  $2 is a condition to test# for whether to stop._Dbg_do_break() {  local -i is_temp=$1  shift  local n=${1:-$_curline}  shift  local condition=${1:-''};  if [[ "$n" == 'if' ]]; then    n=$_curline  elif [[ -z $condition ]] ; then    condition=1  elif [[ $condition == 'if' ]] ; then    shift  fi  if [[ -z $condition ]] ; then    condition=1  else     condition="$*"  fi  local filename  local -i line_number  local full_filename  _Dbg_linespec_setup $n  if [[ -n $full_filename ]]  ; then     if (( $line_number ==  0 )) ; then       _Dbg_msg "There is no line 0 to break at."    else       _Dbg_check_line $line_number "$full_filename"      (( $? == 0 )) && \	_Dbg_set_brkpt "$full_filename" "$line_number" $is_temp "$condition"    fi  else    _Dbg_file_not_read_in $filename  fi}# Set a condition for a given breakpoint $1 is a breakpoint number# $2 is a condition. If not given, set "unconditional" or 1.# returns 0 if success or 1 if fail._Dbg_do_condition() {  # set -x  local -r n=$1  shift   local condition="$@"  # set -xv  if [[ -z $n ]]; then    _Dbg_msg "Argument required (breakpoint number)."    return 1  fi  eval "$_seteglob"  if [[ $n != $int_pat ]]; then    eval "$_resteglob"    _Dbg_msg "Bad breakpoint number: $n"    return 1  fi  eval "$_resteglob"  if [[ -z ${_Dbg_brkpt_file[$n]} ]] ; then    _Dbg_msg "Breakpoint entry $n is not set. Condition not changed."    return 1  fi    if [[ -z $condition ]] ; then    condition=1    _Dbg_msg "Breakpoint $n now unconditional."  fi  _Dbg_brkpt_cond[$n]="$condition"  return 0}# delete brkpt(s) at given file:line numbers. If no file is given# use the current file._Dbg_do_clear_brkpt() {  # set -x  local -r n=${1:-$_curline}  local filename  local -i line_number  local full_filename  _Dbg_linespec_setup $n  if [[ -n $full_filename ]] ; then     if (( $line_number ==  0 )) ; then       _Dbg_msg "There is no line 0 to clear."    else       _Dbg_check_line $line_number "$full_filename"      if (( $? == 0 )) ; then	_Dbg_unset_brkpt "$full_filename" "$line_number"	local -r found=$?	if [[ $found != 0 ]] ; then 	  _Dbg_msg "Removed $found breakpoint(s)."	else 	  _Dbg_msg "Didn't find any breakpoints to remove at $n."	fi      fi    fi  else    _Dbg_file_not_read_in $filename  fi}# list breakpoints and break condition.# If $1 is given just list those associated for that line._Dbg_do_list_brkpt() {  local brkpt_num=${1:-''}  eval "$_seteglob"  if [[ -n $brkpt_num ]] ; then     if [[ $brkpt_num != $int_pat ]]; then      _Dbg_msg "Bad breakpoint number $brkpt_num."    elif [[ -z ${_Dbg_brkpt_file[$brkpt_num]} ]] ; then      _Dbg_msg "Breakpoint entry $brkpt_num is not set."    else      local -r -i i=$brkpt_num      local source_file=${_Dbg_brkpt_file[$i]}      source_file=$(_Dbg_adjust_filename "$source_file")      _Dbg_msg "Num Type       Disp Enb What"      _Dbg_printf "%-3d breakpoint %-4s %-3s %s:%s" $i \	${_Dbg_keep[${_Dbg_brkpt_onetime[$i]}]} \	${_Dbg_yn[${_Dbg_brkpt_enable[$i]}]} \	$source_file ${_Dbg_brkpt_line[$i]}      if [[ ${_Dbg_brkpt_cond[$i]} != '1' ]] ; then	_Dbg_printf "\tstop only if %s" "${_Dbg_brkpt_cond[$i]}"      fi      _Dbg_print_brkpt_count ${_Dbg_brkpt_count[$i]}    fi    eval "$_resteglob"    return  fi  if [ ${#_Dbg_brkpt_line[@]} != 0 ]; then    local -i i    _Dbg_msg "Num Type       Disp Enb What"    for (( i=1; (( i <= _Dbg_brkpt_max )) ; i++ )) ; do      local source_file=${_Dbg_brkpt_file[$i]}      if [[ -n ${_Dbg_brkpt_line[$i]} ]] ; then	source_file=$(_Dbg_adjust_filename "$source_file")	_Dbg_printf "%-3d breakpoint %-4s %-3s %s:%s" $i \	  ${_Dbg_keep[${_Dbg_brkpt_onetime[$i]}]} \	  ${_Dbg_yn[${_Dbg_brkpt_enable[$i]}]} \	  $source_file ${_Dbg_brkpt_line[$i]}	if [[ ${_Dbg_brkpt_cond[$i]} != '1' ]] ; then	  _Dbg_printf "\tstop only if %s" "${_Dbg_brkpt_cond[$i]}"	fi	if (( _Dbg_brkpt_count[$i] != 0 )) ; then	  _Dbg_print_brkpt_count ${_Dbg_brkpt_count[$i]}	fi      fi    done  else    _Dbg_msg "No breakpoints have been set."  fi}# clear all brkpts_Dbg_clear_all_brkpt() {  local -i k  for (( k=0; (( k < ${#_Dbg_filenames[@]} )) ; k++ )) ; do    local filename=${_filename[$k]}    local filevar="`_Dbg_file2var $filename`"    local brkpt_a="_Dbg_brkpt_${filevar}"    _Dbg_write_journal_eval "unset ${brkpt_a}[$k]"  done  _Dbg_write_journal_eval "_Dbg_brkpt_line=()"  _Dbg_write_journal_eval "_Dbg_brkpt_cond=()"  _Dbg_write_journal_eval "_Dbg_brkpt_file=()"  _Dbg_write_journal_eval "_Dbg_brkpt_enable=()"  _Dbg_write_journal_eval "_Dbg_brkpt_count=()"  _Dbg_write_journal_eval "_Dbg_brkpt_onetime=()"}# Internal routine to a set breakpoint unconditonally. _Dbg_set_brkpt() {  local source_file=$1  local -ir line=$2  local -ir is_temp=$3  local -r  condition=${4:-1}  local -r filevar="`_Dbg_file2var $source_file`"  local val_str=`_Dbg_get_assoc_array_entry "_Dbg_brkpt_$filevar" $line`  # Increment brkpt_max here because we are 1-origin  ((_Dbg_brkpt_max++))  if [ -z "$val_str" ] ; then     val_str=$_Dbg_brkpt_max  else    val_str="$val_str $_Dbg_brkpt_max"  fi  _Dbg_brkpt_line[$_Dbg_brkpt_max]=$line  _Dbg_brkpt_file[$_Dbg_brkpt_max]="$source_file"  _Dbg_brkpt_cond[$_Dbg_brkpt_max]="$condition"  _Dbg_brkpt_onetime[$_Dbg_brkpt_max]=$is_temp  _Dbg_brkpt_count[$_Dbg_brkpt_max]=0  _Dbg_brkpt_enable[$_Dbg_brkpt_max]=1  local dq_source_file=$(_Dbg_esc_dq "$source_file")  local dq_condition=$(_Dbg_esc_dq "$condition")  _Dbg_write_journal "_Dbg_brkpt_line[$_Dbg_brkpt_max]=$line"  _Dbg_write_journal "_Dbg_brkpt_file[$_Dbg_brkpt_max]=\"$dq_source_file\""  _Dbg_write_journal "_Dbg_brkpt_cond[$_Dbg_brkpt_max]=\"$dq_condition\""  _Dbg_write_journal "_Dbg_brkpt_onetime[$_Dbg_brkpt_max]=$is_temp"

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -