From c756aec1f66e5cc220ec25032162045ccfa4d515 Mon Sep 17 00:00:00 2001 From: Justin Zhang Date: Wed, 4 Jun 2025 18:13:47 +0800 Subject: [PATCH] Implement #67 - Preset breakpoints in per project .bashdbrc - Fix failure to set conditional breakpoint using condition command - Document startup behavior under "entry-exit" section Signed-off-by: Justin Zhang --- command/condition.sh | 1 + dbg-main.sh | 5 +++ docs/entry-exit.rst | 55 +++++++++++++++++++++++++++++ lib/filecache.sh | 4 +-- test/data/brkpt1.right | 2 +- test/data/preset-brkpt.cmd | 1 + test/data/preset-brkpt.right | 13 +++++++ test/integration/Makefile.am | 3 +- test/integration/check-common.sh.in | 18 +++++++--- test/integration/test-preset-brkpt | 35 ++++++++++++++++++ 10 files changed, 129 insertions(+), 8 deletions(-) create mode 100644 test/data/preset-brkpt.cmd create mode 100644 test/data/preset-brkpt.right create mode 100755 test/integration/test-preset-brkpt diff --git a/command/condition.sh b/command/condition.sh index b9ade938..460e66dc 100644 --- a/command/condition.sh +++ b/command/condition.sh @@ -65,6 +65,7 @@ function _Dbg_do_condition { return 3 fi + condition=$@ if [[ -z $condition ]] ; then condition=1 _Dbg_msg "Breakpoint $n now unconditional." diff --git a/dbg-main.sh b/dbg-main.sh index 971908de..1ef78796 100644 --- a/dbg-main.sh +++ b/dbg-main.sh @@ -59,6 +59,11 @@ if (( 0 == _Dbg_o_nx)) && [[ -r "$_Dbg_startup_cmdfile" ]] ; then _Dbg_do_source "$_Dbg_startup_cmdfile" fi +typeset _Dbg_per_project_cmdfile=$(pwd)/.${_Dbg_debugger_name}rc +if (( 0 == _Dbg_o_nx)) && [[ -r "$_Dbg_per_project_cmdfile" ]] ; then + _Dbg_do_source "$_Dbg_per_project_cmdfile" +fi + # _Dbg_DEBUGGER_LEVEL is the number of times we are nested inside a debugger # by virtue of running "debug" for example. if [[ -z "${_Dbg_DEBUGGER_LEVEL}" ]] ; then diff --git a/docs/entry-exit.rst b/docs/entry-exit.rst index 8ecfb967..056c0468 100644 --- a/docs/entry-exit.rst +++ b/docs/entry-exit.rst @@ -4,6 +4,61 @@ Entering the Bash Debugger .. toctree:: .. contents:: +Startup Behavior +================ + +You can customize bashdb's initialization process such as setting up +breakpoints to facilitate complex issue trouble shooting. This can be achieved +by creating per-user or per-project rc files named ``.bashdbrc`` under your +home directory or any directory in your project. The per-user rc file is loaded +first, followed by the per-project rc file. Therefore, you can override +settings in your per-project ``.bashdbrc`` file. + +The follow code snippet demonstrates a per-project ``.bashdbrc`` with a few +breakpoints configured: + +.. code:: console + + $ cd my-project + $ cat .bashdbrc + + # explicit load is required to make + # code in this file available to bashdb + load ./libs/functions.sh + break ./main.sh:13 $cmd == "start" + break ./libs/functions.sh:332 + +Currently explicit loading of programs invoked by main script is required. +Therefore, in this example, the ``load`` command makes the code defined in the +``libs/functions.sh`` available to the debugging session. Once the per-project +``.bashdbrc`` is configured, you can launch the debugger under the directory +where the ``.bashdbrc`` located as follows: + +.. code:: console + + $ bashdb main.sh start + + bash debugger, bashdb, release 5.2-1.1.2 + + Copyright 2002-2004, 2006-2012, 2014, 2016-2019, 2021, 2023-2024 Rocky Bernstein + This is free software, covered by the GNU General Public License, and you are + welcome to change it and/or distribute copies of it under certain conditions. + + (/home/user/my-project/main.sh:3): + 3: source ./libs/functions.sh + File /home/user/my-project/libs/functions.sh loaded. + Breakpoint 1 set in file /home/user/my-project/libs/functions.sh, line 332. + Breakpoint 2 set in file /home/user/my-project/main.sh, line 13. + bashdb<4> info breakpoints + Num Type Disp Enb What + 1 breakpoint keep y /home/user/my-project/libs/functions.sh:332 + 2 breakpoint keep y /home/user/my-project/main.sh:13 + stop only if $cmd == "start" + +In this example, bashdb shows the two breakpoints presetted by the +``.bashdbrc`` file when it finishes startup. The ``info breakpoints`` command, +abbreviated as ``i b``, reveals the second breakpoint is a conditional +breakpoint. Invoking the Debugger Initially =============================== diff --git a/lib/filecache.sh b/lib/filecache.sh index 3ee92a9f..da4a7273 100644 --- a/lib/filecache.sh +++ b/lib/filecache.sh @@ -38,8 +38,8 @@ _Dbg_filecache_reset() { } _Dbg_filecache_reset -# Check that line $2 is not greater than the number of lines in -# file $1 +# Check that line $1 is not greater than the number of lines in +# file $2 _Dbg_check_line() { (( $# != 2 )) && return 1 typeset -i line_number=$1 diff --git a/test/data/brkpt1.right b/test/data/brkpt1.right index 3c41eb2a..010c98ab 100644 --- a/test/data/brkpt1.right +++ b/test/data/brkpt1.right @@ -96,7 +96,6 @@ Num Type Disp Enb What +condition x==1 ** condition: Bad breakpoint number: x==1 +condition 4 x==1 -Breakpoint 4 now unconditional. +condition bad ** condition: Bad breakpoint number: bad +condition 30 y==1 @@ -109,6 +108,7 @@ Num Type Disp Enb What ---------------------------- 2 breakpoint keep n dbg-test1.sh:22 4 breakpoint keep y dbg-test1.sh:23 + stop only if x==1 5 breakpoint keep n dbg-test1.sh:23 stop only if x==0 6 breakpoint keep y dbg-test1.sh:24 diff --git a/test/data/preset-brkpt.cmd b/test/data/preset-brkpt.cmd new file mode 100644 index 00000000..9e8d561d --- /dev/null +++ b/test/data/preset-brkpt.cmd @@ -0,0 +1 @@ +info break diff --git a/test/data/preset-brkpt.right b/test/data/preset-brkpt.right new file mode 100644 index 00000000..77c96db6 --- /dev/null +++ b/test/data/preset-brkpt.right @@ -0,0 +1,13 @@ +(gcd.sh:24): +24: gcd $1 $2 +Breakpoint 1 set in file gcd.sh, line 8. +Breakpoint 2 set in file gcd.sh, line 11. +Breakpoint 3 set in file gcd.sh, line 15. +Num Type Disp Enb What +---------------------------- +1 breakpoint keep y gcd.sh:8 +2 breakpoint keep y gcd.sh:11 +3 breakpoint keep y gcd.sh:15 + stop only if a==1 + +bashdb: That's all, folks... diff --git a/test/integration/Makefile.am b/test/integration/Makefile.am index d1c11bda..46972599 100644 --- a/test/integration/Makefile.am +++ b/test/integration/Makefile.am @@ -76,7 +76,8 @@ TESTS = \ test-tbreak \ test-trace \ test-watch1 \ - test-watch2 + test-watch2 \ + test-preset-brkpt TESTS_ENVIRONMENT = \ srcdir="$(abs_srcdir)" \ diff --git a/test/integration/check-common.sh.in b/test/integration/check-common.sh.in index 2c0aa79c..502d4aff 100644 --- a/test/integration/check-common.sh.in +++ b/test/integration/check-common.sh.in @@ -62,9 +62,14 @@ TEST_FILTERED_FILE="/tmp/${TEST_NAME}-filtered.check" RIGHT_FILTERED_FILE="/tmp/${TEST_NAME}-filtered.right" run_test_check() { - short_script_name=${1:-$TEST_NAME} - short_test_name=${2:-$TEST_NAME} - debugged_script=${3:-"${top_srcdir}/test/example/${short_script_name}.sh"} + short_script_name=$1 + short_test_name=$2 + debugged_script=$3 + with_init=$4 + [[ -z $short_script_name ]] && short_script_name=$TEST_NAME + [[ -z $short_test_name ]] && short_test_name=$TEST_NAME + [[ -z $debugged_script ]] && debugged_script="${top_srcdir}/test/example/${short_script_name}.sh" + [[ -z $with_init ]] && with_init="no" # Reassign variables to allow overrides via the above parameters TEST_FILE="${top_builddir}/test/integration/${short_test_name}.check" @@ -78,7 +83,12 @@ run_test_check() { print -r -- "You need to set srcdir before running this." exit 10 fi - (cd $srcdir && run_debugger "$debugged_script" 2>&1 >"$TEST_FILE" &1 >"$TEST_FILE" &1 >"$TEST_FILE" "${builddir}/.bashdbrc" +break gcd +break 11 +break 15 if a==1 +EOF + +script=gcd +# The fourth argument loads per-project .bashdbrc +run_test_check $script "" "" "yes" +rc=$? +(( $rc != 0 )) && exit $rc + +# Return code tells testing mechanism whether passed or not. +exit 0