diff --git a/scripts/magic_run_common.sh.in b/scripts/magic_run_common.sh.in index 7795cd74..e6e190eb 100644 --- a/scripts/magic_run_common.sh.in +++ b/scripts/magic_run_common.sh.in @@ -138,6 +138,26 @@ magic_stage() { ln -sfn "$s"/magic/bitmaps "$MAGIC_TCL"/bitmaps 2>/dev/null || : } +# Split a launcher's argv on the first "--": +# -- +# Everything before "--" is for the wrapper tool (gdb/valgrind); everything after +# is magic's. With no "--" present, ALL arguments are treated as magic's -- the +# common case where no tool options are needed. Results are returned in the +# arrays MAGIC_TOOL_OPTS and MAGIC_ARGS. +magic_split_args() { + MAGIC_TOOL_OPTS=() + MAGIC_ARGS=() + local seen=0 a + for a in "$@"; do + if [ "$seen" -eq 0 ] && [ "$a" = "--" ]; then seen=1; continue; fi + if [ "$seen" -eq 1 ]; then MAGIC_ARGS+=("$a"); else MAGIC_TOOL_OPTS+=("$a"); fi + done + if [ "$seen" -eq 0 ]; then + MAGIC_ARGS=(${MAGIC_TOOL_OPTS[@]+"${MAGIC_TOOL_OPTS[@]}"}) + MAGIC_TOOL_OPTS=() + fi +} + # Fail early with a clear message if the build has not produced the binaries yet. magic_require_built() { if [ ! -x "$MAGIC_BUILDDIR/tcltk/magicexec" ] && \ diff --git a/scripts/run_magic_gdb.sh.in b/scripts/run_magic_gdb.sh.in index 30d49136..0ef96dd3 100644 --- a/scripts/run_magic_gdb.sh.in +++ b/scripts/run_magic_gdb.sh.in @@ -9,12 +9,20 @@ # "magicexec". Symbols come straight from the build tree. # # USAGE -# ./run_magic_gdb.sh [magic-args...] # then `run` at the (gdb) prompt -# For batch/no-GUI debugging (no X display needed, reproducible), debug the null -# binary instead: -# gdb --args "$MAGIC_TCL/magicdnull" -dnull -nowrapper +# ./run_magic_gdb.sh [gdb-opts...] [-- [magic-args...]] +# +# A "--" separates gdb's own options from magic's: +# ./run_magic_gdb.sh # plain interactive gdb +# ./run_magic_gdb.sh foo.mag # no "--" => all args go to magic +# ./run_magic_gdb.sh -tui -- foo.mag # gdb gets -tui, magic gets foo.mag +# ./run_magic_gdb.sh -ex run -- -dnull # gdb runs immediately; magic -dnull +# With no "--", every argument is passed to magic (the common case). +# +# For batch/no-GUI debugging point it at the null device: ... -- -dnull # # ENVIRONMENT OVERRIDES (all optional; each wins over the baked default) +# GDB debugger binary to use (default: gdb on PATH) +# GDB_OPTS default gdb options, prepended before any given on the command line # CAD_ROOT reuse an alternate runtime tree instead of staging $builddir/CAD_DIR # MAGIC_WISH wish for the Tk console (default: the configure-matched wish) # WISH TCLSH wish/tclsh matching this build's Tcl/Tk (--with-tk / --with-tcl) @@ -25,7 +33,15 @@ set -eu here="$(cd "$(dirname "$0")" && pwd)" . "$here/magic_run_common.sh" +GDB="${GDB:-gdb}" +command -v "$GDB" >/dev/null 2>&1 || magic_warn "debugger '$GDB' not found on PATH" + magic_require_built magic_stage +magic_split_args "$@" -exec gdb --args "$MAGIC_TCL/magicexec" -- "$@" +# gdb --args magicexec -- +exec "$GDB" ${GDB_OPTS-} \ + ${MAGIC_TOOL_OPTS[@]+"${MAGIC_TOOL_OPTS[@]}"} \ + --args "$MAGIC_TCL/magicexec" -- \ + ${MAGIC_ARGS[@]+"${MAGIC_ARGS[@]}"} diff --git a/scripts/run_magic_valgrind.sh.in b/scripts/run_magic_valgrind.sh.in index ba6c09a9..be524b83 100644 --- a/scripts/run_magic_valgrind.sh.in +++ b/scripts/run_magic_valgrind.sh.in @@ -9,12 +9,23 @@ # valgrind on the self-contained "magicexec". # # USAGE -# ./run_magic_valgrind.sh [magic-args...] -# This checks the GUI binary (magicexec); Tk/X allocations make the output -# noisy, so for real leak hunting prefer the batch binary (fewer moving parts): -# valgrind --leak-check=full "$MAGIC_TCL/magicdnull" -dnull -nowrapper +# ./run_magic_valgrind.sh [valgrind-opts...] [-- [magic-args...]] +# +# A "--" separates valgrind's own options from magic's: +# ./run_magic_valgrind.sh # default memcheck options +# ./run_magic_valgrind.sh foo.mag # no "--" => all args go to magic +# ./run_magic_valgrind.sh -v -- foo.mag # valgrind -v, magic gets foo.mag +# ./run_magic_valgrind.sh --tool=callgrind -- # a different valgrind tool +# With no "--", every argument is passed to magic (the common case). +# +# This checks the GUI binary; Tk/X allocations make the output noisy, so for +# real leak hunting run the batch device: ./run_magic_valgrind.sh -- -dnull # # ENVIRONMENT OVERRIDES (all optional; each wins over the baked default) +# VALGRIND valgrind binary to use (default: valgrind on PATH) +# VALGRIND_OPTS default valgrind options (default: --leak-check=full +# --error-exitcode=0). Set empty to clear them; command-line +# options before "--" are added after these. # CAD_ROOT reuse an alternate runtime tree instead of staging $builddir/CAD_DIR # MAGIC_WISH wish for the Tk console (default: the configure-matched wish) # WISH TCLSH wish/tclsh matching this build's Tcl/Tk (--with-tk / --with-tcl) @@ -25,8 +36,16 @@ set -eu here="$(cd "$(dirname "$0")" && pwd)" . "$here/magic_run_common.sh" +VALGRIND="${VALGRIND:-valgrind}" +command -v "$VALGRIND" >/dev/null 2>&1 || magic_warn "valgrind '$VALGRIND' not found on PATH" +VALGRIND_OPTS="${VALGRIND_OPTS---leak-check=full --error-exitcode=0}" + magic_require_built magic_stage +magic_split_args "$@" -exec valgrind --leak-check=full --error-exitcode=0 \ - "$MAGIC_TCL/magicexec" -- "$@" +# valgrind magicexec -- +exec "$VALGRIND" $VALGRIND_OPTS \ + ${MAGIC_TOOL_OPTS[@]+"${MAGIC_TOOL_OPTS[@]}"} \ + "$MAGIC_TCL/magicexec" -- \ + ${MAGIC_ARGS[@]+"${MAGIC_ARGS[@]}"}