📄 dbg-cmds.inc
字号:
# dbg-cmds.inc - Bourne Again Shell Debugger Top-level debugger commands## Copyright (C) 2002, 2003, 2004, 2005, 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.# Debugger command loop: Come here at to read debugger commands to# run.# Main-line debugger read/execute command loop# ==================== VARIABLES =======================================# _Dbg_INPUT_START_DESC is the lowest descriptor we use for reading.# _Dbg_MAX_INPUT_DESC is the maximum input descriptor that can be # safely used (as per the bash manual on redirection)# _Dbg-input_desc is the current descriptor in use. "sourc"ing other# command files will increase this descriptortypeset -ir _Dbg_INPUT_START_DESC=4typeset -i _Dbg_MAX_INPUT_DESC=9 # logfile can reduce thistypeset -i _Dbg_input_desc=_Dbg_INPUT_START_DESC-1 # will ++ before usetypeset -a _Dbg_history=()# Are we inside the middle of a "skip" command?typeset -i _Dbg_inside_skip=0# keep a list of source'd command files. If the entry is "" then we are # interactive.typeset -a _Dbg_cmdfile=('')# A variable holding a space is set so it can be used in a "set prompt" command# ("read" in the main command loop will remove a trailing space so we need# another way to allow a user to enter spaces in the prompt.)typeset _Dbg_space=' '# Should we allow editing of debugger commands? # The value should either be '-e' or ''typeset _Dbg_edit='-e'# What do we use for a debugger prompt? Technically we don't need to# use the above $bashdb_space in the assignment below, but we put it# in to suggest to a user that this is how one gets a spaces into the# prompt.typeset _Dbg_prompt_str='bashdb${_Dbg_less}${#_Dbg_history[@]}${_Dbg_greater}$_Dbg_space'# The arguments in the last "print" command.typeset _Dbg_last_print_args=''# The arguments in the last "x" command.typeset _Dbg_last_x_args=''# ===================== FUNCTIONS =======================================# Note: We have to be careful here in naming "local" variables. In contrast# to other places in the debugger, because of the read/eval loop, they are# in fact seen by those using the debugger. So in contrast to other "local"s# in the debugger, we prefer to preface these with _Dbg_._Dbg_cmdloop() { # THIS SHOULD BE DONE IN dbg-sig.inc, but there's a bug in BASH in # trying to change "trap RETURN" inside a "trap RETURN" handler.... # Turn off return trapping. Not strictly necessary, since it *should* be # covered by the _Dbg_ test below if we've named functions correctly. # However turning off the RETURN trap should reduce unnecessary calls. # trap RETURN _Dbg_inside_skip=0 # Evaluate all the display expressions _Dbg_eval_all_display # Loop over all pending open input file descriptors while (( $_Dbg_input_desc >= $_Dbg_INPUT_START_DESC )) ; do # Set up prompt to show shell level. local _Dbg_greater='' local _Dbg_less='' local -i _Dbg_i=0 for (( _Dbg_i=0 ; _Dbg_i < BASHDB_LEVEL ; _Dbg_i++ )) ; do _Dbg_greater=">$_Dbg_greater" _Dbg_less="<$_Dbg_less" done for (( _Dbg_i=0 ; _Dbg_i < BASH_SUBSHELL ; _Dbg_i++ )) ; do _Dbg_greater=")$_Dbg_greater" _Dbg_less="$_Dbg_less(" done # Loop over debugger commands. But before reading a debugger # command, we need to make sure IFS is set to spaces to ensure our # two variables (command name and rest of the arguments) are set # correctly. Saving the IFS and setting it to the "normal" value # of space should be done in the DEBUG signal handler entry. # Also, we need to make sure the prompt output is # redirected to the debugger terminal. Both of these things may # have been changed by the debugged program for its own # purposes. Furthermore, were we *not* to redirect our stderr # below, we may mess up what the debugged program expects to see # in in stderr by adding our debugger prompt. # if no tty, no prompt local _Dbg_prompt_output=${_Dbg_tty:-/dev/null} eval "local _Dbg_prompt=$_Dbg_prompt_str" local _Dbg_cmd local args while read $_Dbg_edit -p "$_Dbg_prompt" \ _Dbg_cmd args \ <&$_Dbg_input_desc 2>>$_Dbg_prompt_output; do if (( _Dbg_brkpt_commands_defining )) ; then case $_Dbg_cmd in silent ) _Dbg_brkpt_commands_silent[$_Dbg_brkpt_commands_current]=1 continue ;; end ) _Dbg_brkpt_commands_defining=0 #### ??? TESTING ## local -i cur=$_Dbg_brkpt_commands_current ## local -i start=${_Dbg_brkpt_commands_start[$cur]} ## local -i end=${_Dbg_brkpt_commands_end[$cur]} ## local -i i ## echo "++ brkpt: $cur, start: $start, end: $end " ## for (( i=start; (( i < end )) ; i++ )) ; do ## echo ${_Dbg_brkpt_commands[$i]} ## done eval "_Dbg_prompt=$_Dbg_prompt_str" continue ;; *) _Dbg_brkpt_commands[${#_Dbg_brkpt_commands[@]}]="$_Dbg_cmd $args" (( _Dbg_brkpt_commands_end[$_Dbg_brkpt_commands_current]++ )) continue ;; esac else _Dbg_onecmd "$_Dbg_cmd" "$args" fi local rc=$? if (( $rc != 10 )) ; then return $rc fi if (( _Dbg_brkpt_commands_defining )) ; then _Dbg_prompt='>' else eval "_Dbg_prompt=$_Dbg_prompt_str" fi done # while read $_Dbg_edit -p ... ((_Dbg_input_desc--)) # Remove last entry of $_Dbg_cmdfile unset _Dbg_cmdfile[${#_Dbg_cmdfile[@]}] done # Loop over all open pending file descriptors # EOF hit. Same as quit without arguments _Dbg_msg "" # Cause <cr> since EOF may not have put in. _Dbg_do_quit}# Run a single command# Parameters: _Dbg_cmd and args# _Dbg_onecmd() { local _Dbg_cmd=$1 shift local args=$* # Set default next, step or skip command if [[ -z $_Dbg_cmd ]]; then _Dbg_cmd=$_Dbg_last_next_step_cmd args=$_Dbg_last_next_step_args fi # If "set trace-commands" is "on", echo the the command if [[ $_Dbg_trace_commands == 'on' ]] ; then _Dbg_msg "+$_Dbg_cmd $args" fi local dq_cmd=$(_Dbg_esc_dq "$_Dbg_cmd") local dq_args=$(_Dbg_esc_dq "$args") # _Dbg_write_journal_eval doesn't work here. Don't really understand # how to get it to work. So we do this in two steps. _Dbg_write_journal \ "_Dbg_history[${#_Dbg_history[@]}]=\"$dq_cmd $dq_args\"" _Dbg_history[${#_Dbg_history[@]}]="$_Dbg_cmd $args" _Dbg_hi=${#_Dbg_history[@]} local -i _Dbg_redo=1 while (( $_Dbg_redo )) ; do _Dbg_redo=0 case $_Dbg_cmd in # Comment line [#]* ) _Dbg_remove_history_item ;; # List window up to _curline - ) local -i start_line=(_curline+1-$_Dbg_listsize) local -i count=($_Dbg_listsize) if (( start_line <= 0 )) ; then ((count=count+start_line-1)) start_line=1; fi _Dbg_list $_cur_source_file $start_line $count ;; # list current line . ) _Dbg_list $_cur_source_file $_curline 1 ;; # Search forwards for pattern /* ) _Dbg_do_search $_Dbg_cmd ;; # Search backwards for pattern [?]* ) _Dbg_do_search_back $_Dbg_cmd ;; # Set action to be silently run when a line is hit a ) _Dbg_do_action $args ;; # Set breakpoint on a line b | br | bre | brea | break ) _Dbg_do_break 0 $args ;; # Stack trace ba | bac | back | backt | backtr | backtra | backtrac | backtrace | bt | T | wh | whe | wher | where ) _Dbg_do_stack_trace 2 $args; ;; # Continue c | cont | conti |contin |continu | continue ) _Dbg_do_continue $args if [[ $? == 0 ]] ; then IFS="$_Dbg_old_IFS"; _Dbg_write_journal_eval \ "_Dbg_old_set_opts=\"$_Dbg_old_set_opts -o functrace\"" return 0 fi ;; # Change Directory cd ) # Allow for tilde expansion. We also allow expansion of # variables like $HOME which gdb doesn't allow. That's life. local cd_command="cd $args" eval $cd_command _Dbg_do_pwd ;; # commands comm | comma | comman | command | commands ) _Dbg_do_commands $args ;; # complete com | comp | compl | comple |complet | complete ) _Dbg_do_complete $args ;; # Breakpoint/Watchpoint Conditions cond | condi |condit |conditi | conditio | condition ) _Dbg_do_condition $args ;; # Delete all breakpoints by line number. # Note we use "d" as an alias for "clear" to be compatible # with the Perl5 debugger. d | cl | cle | clea | clea | clear ) _Dbg_do_clear_brkpt $args ;; # Delete breakpoints by entry numbers. Note "d" is an alias for # clear. de | del | dele | delet | delete ) _Dbg_do_delete $args ;; # Set up a script for debugging into. deb | debu | debug ) _Dbg_do_debug $args # Skip over the execute statement which presumably we ran above. _Dbg_do_next_step_skip "skip" 1 IFS="$_Dbg_old_IFS"; return 1 ;; # Disable breakpoints di | dis | disa | disab | disabl | disable ) _Dbg_do_disable $args ;; # Display expression disp | displ | displa| display ) _Dbg_do_display $args ;; # Delete all breakpoints. D | deletea | deleteal | deleteall ) _Dbg_clear_all_brkpt ;; # List stack 1 up do | dow | down ) _Dbg_do_down $args ;; # evaluate as bash command e | ev | eva | eval ) _Dbg_do_eval $args ;; # evaluate as bash command en | ena | enab | enabl | enable ) _Dbg_do_enable $args ;; # fil | file ) _Dbg_do_file $args ;; # fin | fini | finis | finish | r ) (( _Dbg_return_level=${#FUNCNAME[@]}-3 )) return 0 ;; # Set stack frame fr | fra | fra | frame ) _Dbg_do_frame $args ;; # print help command menu h | he | hel | help | '?' ) _Dbg_do_help $args ;; # Set signal handle parameters ha | han | hand | handl | handle ) _Dbg_do_handle $args ;; # Info subcommands i | in | inf | info ) _Dbg_do_info $args ;; # List line. # print lines in file l | li | lis | list ) _Dbg_do_list $args ;; # List line. # print lines in file lo | loa | load ) _Dbg_do_load $args ;; # kill program k | ki | kil | kill ) _Dbg_do_kill $args ;; # next/single-step N times (default 1) n | ne | nex | next | s | st | ste | step | sk | ski | skip ) _Dbg_last_next_step_cmd="$_Dbg_cmd" _Dbg_last_next_step_args=$args _Dbg_do_next_step_skip $_Dbg_cmd $args if [[ $_Dbg_cmd == sk* ]] ; then _Dbg_inside_skip=1 return 1 else return 0 fi ;; # print globbed or substituted variables p | pr | pri | prin | print ) _Dbg_do_print "$args" ;; # print working directory pw | pwd ) _Dbg_do_pwd ;; # quit q | qu | qui | quit ) _Dbg_do_quit $args ;; # restart debug session. re | res | rest | resta | restar | restart | ru | run | R ) _Dbg_do_restart $args ;; # return from function/source without finishing executions ret | retu | retur | return ) _Dbg_steps=1 _Dbg_write_journal "_Dbg_steps=$_Dbg_steps" IFS="$_Dbg_old_IFS"; return 2 ;; # Search backwards for pattern rev | reve | rever | revers | reverse ) _Dbg_do_search_back $args ;; # Run a debugger set command se | set ) _Dbg_do_set $args ;; # Search forwards for pattern sea | sear | searc | search | \ for | forw | forwa | forwar | forward ) _Dbg_do_search $args ;; # Run a debugger show command sh | sho | show ) _Dbg_do_show $args ;; # run shell command. Has to come before ! below. she | shel | shell | '!!' ) eval $args ;; # Send signal to process si | sig | sign | signa | signal ) _Dbg_do_signal $args ;; # Run a debugger comamnd file so | sou | sour | sourc | source ) _Dbg_do_source $args ;; # toggle execution trace t | to | tog | togg | toggl | toggle ) _Dbg_do_trace ;; # Set breakpoint on a line tb | tbr | tbre | tbrea | tbreak ) _Dbg_do_break 1 $args ;; # Set the output tty tt | tty ) _Dbg_do_tty $args _Dbg_prompt_output=${_Dbg_tty:-/dev/null} ;; # List call stack up u | up ) _Dbg_do_up $args ;; # List call stack up un | undi | undis | undisp | undispl | undispla | undisplay ) _Dbg_do_undisplay $args ;; # Show version information ve | ver | vers | versi | versio | version | M ) _Dbg_do_show_versions ;; # List window around line. w | wi | win | wind | windo | window ) ((_startline=_curline - _Dbg_listsize/2)) (( $_startline <= 0 )) && _startline=1 _Dbg_list $_cur_source_file $_startline ;; # watch variable wa | wat | watch | W ) local -a a a=($args) local first=${a[0]} if [[ $first == '' ]] ; then _Dbg_do_watch 0 else if [[ 0 == `_Dbg_is_var $first` ]] ; then _Dbg_msg "Can't set watch: no such variable $first." else unset a first _Dbg_do_watch 0 "\$$args"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -