mirror of
https://github.com/crosstool-ng/crosstool-ng.git
synced 2025-02-01 08:47:55 +00:00
scripts: add option to start an interactive debug shell
Add an option that, when a command fails: - starts an interactive shell with the failed command's environment - attempts re-execution of the failed command, continues, or aborts at user's whim. Before starting the debug-shell, the backtrace is printed. When exiting for an abort, the standard error message is printed. Based on an idea and a patch from: Johannes Stezenbach <js@sig21.net> http://sourceware.org/ml/crossgcc/2012-09/msg00144.html Signed-off-by: Johannes Stezenbach <js@sig21.net> [yann.morin.1998@free.fr: integrate in the fault handler] Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr> Acked-by: Johannes Stezenbach <js@sig21.net> Patchwork-Id: 191571 Patchwork-Id: 191668
This commit is contained in:
parent
df3be9eef3
commit
dd98145bc1
@ -87,4 +87,23 @@ config NO_OVERIDE_LC_MESSAGES
|
|||||||
|
|
||||||
Say N, please.
|
Say N, please.
|
||||||
|
|
||||||
|
config DEBUG_INTERACTIVE
|
||||||
|
bool
|
||||||
|
prompt "Interactive shell on failed commands"
|
||||||
|
help
|
||||||
|
If you say 'y' here, then an interactive shell will be spawned for
|
||||||
|
each failed command.
|
||||||
|
|
||||||
|
This shell will have the same environment that the failed command
|
||||||
|
was run with, and the working directory will be set to the directory
|
||||||
|
the failed command was run in.
|
||||||
|
|
||||||
|
After you fix the issue, you can exit the interactive shell with any
|
||||||
|
of these exit codes:
|
||||||
|
1 the issue was fixed, continue the build with the next command
|
||||||
|
2 the issue was fixed, re-run the failed command
|
||||||
|
3 abort the build
|
||||||
|
|
||||||
|
Note: '2' is only possible for commands run via CT_DoExecLog, though.
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
@ -25,6 +25,14 @@
|
|||||||
. .config.2
|
. .config.2
|
||||||
# Yes! We can do full logging from now on!
|
# Yes! We can do full logging from now on!
|
||||||
|
|
||||||
|
# If we want an interactive debug-shell, we must ensure these FDs
|
||||||
|
# are indeed connected to a terminal (and not redirected in any way).
|
||||||
|
if [ "${CT_DEBUG_INTERACTIVE}" = "y" -a ! \( -t 0 -a -t 6 -a -t 2 \) ]; then
|
||||||
|
CT_DoLog ERROR "Can't spawn interactive debug-shell,"
|
||||||
|
CT_DoLog ERROR "because stdout/stderr has been redirected."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
# Override the locale early, in case we ever translate crosstool-NG messages
|
# Override the locale early, in case we ever translate crosstool-NG messages
|
||||||
if [ -z "${CT_NO_OVERIDE_LC_MESSAGES}" ]; then
|
if [ -z "${CT_NO_OVERIDE_LC_MESSAGES}" ]; then
|
||||||
export LC_ALL=C
|
export LC_ALL=C
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
# Prepare the fault handler
|
# Prepare the fault handler
|
||||||
CT_OnError() {
|
CT_OnError() {
|
||||||
local ret=$?
|
local ret=$?
|
||||||
|
local result
|
||||||
|
local old_trap
|
||||||
local intro
|
local intro
|
||||||
local file line func
|
local file line func
|
||||||
local step step_depth
|
local step step_depth
|
||||||
@ -35,6 +37,62 @@ CT_OnError() {
|
|||||||
CT_DoLog ERROR ">> ${intro}: ${func}[${file}${line}]"
|
CT_DoLog ERROR ">> ${intro}: ${func}[${file}${line}]"
|
||||||
intro=" called from"
|
intro=" called from"
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# If the user asked for interactive debugging, dump him/her to a shell
|
||||||
|
if [ "${CT_DEBUG_INTERACTIVE}" = "y" ]; then
|
||||||
|
# We do not want this sub-shell exit status to be caught, because
|
||||||
|
# it is absolutely legit that it exits with non-zero.
|
||||||
|
# Save the trap handler to restore it after our debug-shell
|
||||||
|
old_trap="$(trap -p ERR)"
|
||||||
|
trap -- ERR
|
||||||
|
(
|
||||||
|
exec >&6
|
||||||
|
printf "\r \n\nCurrent command"
|
||||||
|
if [ -n "${cur_cmd}" ]; then
|
||||||
|
printf ":\n %s\n" "${cur_cmd}"
|
||||||
|
else
|
||||||
|
printf " (unknown), "
|
||||||
|
fi
|
||||||
|
printf "exited with error code: %d\n" ${ret}
|
||||||
|
printf "Please fix it up and finish by exiting the shell with one of these values:\n"
|
||||||
|
printf " 1 fixed, continue with next build command\n"
|
||||||
|
if [ -n "${cur_cmd}" ]; then
|
||||||
|
printf " 2 repeat this build command\n"
|
||||||
|
fi
|
||||||
|
printf " 3 abort build\n\n"
|
||||||
|
while true; do
|
||||||
|
${bash} --rcfile <(printf "PS1='ct-ng:\w> '\nPROMPT_COMMAND=''\n") -i
|
||||||
|
result=$?
|
||||||
|
case $result in
|
||||||
|
1) printf "\nContinuing past the failed command.\n\n"
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
2) if [ -n "${cur_cmd}" ]; then
|
||||||
|
printf "\nRe-trying last command.\n\n"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
;;&
|
||||||
|
3) break;;
|
||||||
|
*) printf "\nPlease exit with one of these values:\n"
|
||||||
|
printf " 1 fixed, continue with next build command\n"
|
||||||
|
if [ -n "${cur_cmd}" ]; then
|
||||||
|
printf " 2 repeat this build command\n"
|
||||||
|
fi
|
||||||
|
printf " 3 abort build\n"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
exit $result
|
||||||
|
)
|
||||||
|
result=$?
|
||||||
|
# Restore the trap handler
|
||||||
|
eval "${old_trap}"
|
||||||
|
case "${result}" in
|
||||||
|
1) rm -f "${CT_WORK_DIR}/backtrace"; return;;
|
||||||
|
2) rm -f "${CT_WORK_DIR}/backtrace"; touch "${CT_BUILD_DIR}/repeat"; return;;
|
||||||
|
# 3 is an abort, continue...
|
||||||
|
esac
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# And finally, in top-level shell, print some hints
|
# And finally, in top-level shell, print some hints
|
||||||
@ -157,10 +215,11 @@ CT_DoLog() {
|
|||||||
# Usage: CT_DoExecLog <level> [VAR=val...] <command> [parameters...]
|
# Usage: CT_DoExecLog <level> [VAR=val...] <command> [parameters...]
|
||||||
CT_DoExecLog() {
|
CT_DoExecLog() {
|
||||||
local level="$1"
|
local level="$1"
|
||||||
|
local cur_cmd
|
||||||
shift
|
shift
|
||||||
(
|
(
|
||||||
for i in "$@"; do
|
for i in "$@"; do
|
||||||
tmp_log+="'${i}' "
|
cur_cmd+="'${i}' "
|
||||||
done
|
done
|
||||||
while true; do
|
while true; do
|
||||||
case "${1}" in
|
case "${1}" in
|
||||||
@ -168,8 +227,39 @@ CT_DoExecLog() {
|
|||||||
*) break;;
|
*) break;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
CT_DoLog DEBUG "==> Executing: ${tmp_log}"
|
# This while-loop goes hand-in-hand with the ERR trap handler:
|
||||||
"${@}" 2>&1 |CT_DoLog "${level}"
|
# - if the command terminates successfully, then we hit the break
|
||||||
|
# statement, and we exit the loop
|
||||||
|
# - if the command terminates in error, then the ERR handler kicks
|
||||||
|
# in, then:
|
||||||
|
# - if the user did *not* ask for interactive debugging, the ERR
|
||||||
|
# handler exits, and we hit the end of the sub-shell
|
||||||
|
# - if the user did ask for interactive debugging, the ERR handler
|
||||||
|
# spawns a shell. Upon termination of this shell, the ERR handler
|
||||||
|
# examines the exit status of the shell:
|
||||||
|
# - if 1, the ERR handler returns; then we hit the else statement,
|
||||||
|
# then the break, and we exit the 'while' loop, to continue the
|
||||||
|
# build;
|
||||||
|
# - if 2, the ERR handler touches the repeat file, and returns;
|
||||||
|
# then we hit the if statement, and we loop for one more
|
||||||
|
# iteration;
|
||||||
|
# - if 3, the ERR handler exits with the command's exit status,
|
||||||
|
# and we're dead;
|
||||||
|
# - for any other exit status of the shell, the ERR handler
|
||||||
|
# prints an informational message, and respawns the shell
|
||||||
|
#
|
||||||
|
# This allows a user to get an interactive shell that has the same
|
||||||
|
# environment (PATH and so on) that the failed command was ran with.
|
||||||
|
while true; do
|
||||||
|
rm -f "${CT_BUILD_DIR}/repeat"
|
||||||
|
CT_DoLog DEBUG "==> Executing: ${cur_cmd}"
|
||||||
|
"${@}" 2>&1 |CT_DoLog "${level}"
|
||||||
|
if [ -f "${CT_BUILD_DIR}/repeat" ]; then
|
||||||
|
continue
|
||||||
|
else
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
)
|
)
|
||||||
# Catch failure of the sub-shell
|
# Catch failure of the sub-shell
|
||||||
[ $? -eq 0 ]
|
[ $? -eq 0 ]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user