This is the mail archive of the crossgcc@sourceware.org mailing list for the crossgcc project.
See crosstool-NG for lots more information.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
# HG changeset patch # User "Yann E. MORIN" <yann.morin.1998@free.fr> # Date 1349560087 -7200 # Node ID 82c19a72f25a7b399f6be4e2c8c1cecc45d8c171 # Parent 2a616dab6531ad82876c3252cd2e1cb873375c3f 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, continue, or aborts at user's whim. 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: "Yann E. MORIN" <yann.morin.1998@free.fr> Cc: Johannes Stezenbach <js@sig21.net> diff --git a/config/global/ct-behave.in b/config/global/ct-behave.in --- a/config/global/ct-behave.in +++ b/config/global/ct-behave.in @@ -87,4 +87,22 @@ Say N, please. +config DEBUG_INTERACTIVE + bool + prompt "Interactive shell on failed commands" + depends on EXPERIMENTAL + help + If you say 'y' here, then an interactive shell will be spawned for + each failed command run via CT_DoExecLog. + + 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 + endif diff --git a/scripts/functions b/scripts/functions --- a/scripts/functions +++ b/scripts/functions @@ -5,10 +5,45 @@ # Prepare the fault handler CT_OnError() { local ret=$? + local old_trap result local intro local file line func local step step_depth + # 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 + old_trap="$(trap -p ERR)" + trap ERR + ( + exec >&6 + printf "Current command\n %s\n" "${cur_cmd}" + printf "exited with error code: %d\n" ${ret} + printf "Please fix it up and finish by exiting the shell.\n" + while true; do + bash --rcfile <(echo "PS1='ct-ng:\w> '") -i + result=$? + case $result in + 1) break;; + 2) break;; + 3) break;; + *) echo "please exit with one of these values:" + echo "1 fixed, continue with next build command" + echo "2 repeat this build command" + echo "3 abort build" + ;; + esac + done + exit $result + ) + result=$? + case "${result}" in + 1) return;; + 2) touch "${CT_BUILD_DIR}/repeat"; return;; + # 3 is an abort, continue... + esac + fi + # To avoid printing the backtace for each sub-shell # up to the top-level, just remember we've dumped it if [ ! -f "${CT_BUILD_DIR}/backtrace" ]; then @@ -157,10 +192,11 @@ # Usage: CT_DoExecLog <level> [VAR=val...] <command> [parameters...] CT_DoExecLog() { local level="$1" + local cur_cmd shift ( for i in "$@"; do - tmp_log+="'${i}' " + cur_cmd+="'${i}' " done while true; do case "${1}" in @@ -168,8 +204,39 @@ *) break;; esac done - CT_DoLog DEBUG "==> Executing: ${tmp_log}" - "${@}" 2>&1 |CT_DoLog "${level}" + # This while-loop goes hand-in-hand with the ERR trap handler: + # - 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 [ $? -eq 0 ] -- For unsubscribe information see http://sourceware.org/lists.html#faq
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |