bash: Acessando a pilha de chamadas de função na função de interceptação

6

Trabalhando em um rastreamento de pilha de chamada de função bash ...

O script detecta erros e executa uma função callStack() . Mas no trapping, ele sempre mostra uma pilha de chamadas para a função callStack() em vez da função onde a armadilha ocorreu como em ...

/share/sbin/zimdialog: line 647: status: command not found
    Function call stack ( command.function() ) ...
      /share/sbin/zimdialog.main()
        /share/sbin/include.callStack()

Olhando para obter um rastreamento de pilha que inclua errantFunction() like ...

/share/sbin/zimdialog: line 647: status: command not found
    Function call stack ( command.function() ) ...
      /share/sbin/zimdialog.main()
        /share/sbin/zimdialog.errantFunction()
          /share/sbin/include.callStack()

A armadilha é codificada como ...

trap callStack HUP INT QUIT TERM ERR

A função callStack() está codificada como ...

function callStack () {
  { isNotNull "$1" && isHelp "$1"; } && {
    helpShow 'callStack
    Diagnostics regarding where the call to this function came from'
    return
  }
  local T="${T}  "
  local STACK=
  i=${#FUNCNAME[@]}
  ((--i))
  printf "${T}Function call stack ( command.function() ) ...\n" >&2
  T="${T}  "
  while (( $i >= 0 ))
  do
    STACK+="${T}${BASH_SOURCE[$i]}.${FUNCNAME[$i]}()\n"
    T="${T}  "
    ((--i))
  done
  printf "$STACK" >&2
}

Suplemento: defina -E, etc. não funciona

Em /share/sbin/gshlib ...

set -e
set -E
set -T
shopt -s extdebug

trap $(callStack) ERR

function initialize () {
    :
  logstatus                         #<<< ERROR FOR TESTING trap
}
export -f initialize

Misnaming logStatus to logstatus dentro de /share/sbin/gshlib.initialize() para gerar o trap ERR , o melhor que eu obtenho é ...

    Function call stack ...
    | /share/sbin/archive.main()
    |   /share/sbin/include.include()
    |     /share/sbin/gshlib.source()
    |       /share/sbin/include.callStack()
/share/sbin/gshlib: line 109: logstatus: command not found

O que eu estou procurando é ...

    Function call stack ...
    | /share/sbin/archive.main()
    |   /share/sbin/include.include()
    |     /share/sbin/gshlib.source()
    |       /share/sbin/gshlib.initialize()
    |         /share/sbin/include.callStack()
/share/sbin/gshlib: line 109: logstatus: command not found
    
por DocSalvager 24.06.2013 / 06:53

1 resposta

5

Você precisa set -E (ou set -o errtrace ) para que o trap ERR seja herdado pelas funções chamadas.

Depois de fazer isso, você provavelmente descobrirá que receberá um relatório de erros em cascata, pois cada função na pilha de chamadas será encerrada (com um código de saída diferente de zero) pelo erro de script.

ERR não é acionado pela invocação de uma função de shell em um contexto em que a falha não é considerada fatal (como if ou while ). Em tal contexto, o rastreamento de pilha provavelmente não aparecerá, embora eu não tenha certeza de como isso é específico à versão.

    
por 24.06.2013 / 07:43