strace não encontra a função shell com erro “Não é possível stat”

1

Estou tentando chamar uma função autodefinida funk_a em strace , mas não parece encontrá-la. Eu confirmei que funk_a pode ser chamado por si só. Eu aprecio todas as opiniões.

$ source ./strace_sample.sh 
$ funk_a
Earth, Wind, Fire and Water
$ funk_b
Get on up
strace: Can't stat 'funk_a': No such file or directory

$ dpkg -p strace|grep Vers
Version: 4.8-1ubuntu5
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 14.04.5 LTS
Release:        14.04
Codename:       trusty

strace_sample.sh

#!/bin/bash

function funk_a {
  echo "Earth, Wind, Fire and Water"
}

function funk_b {
  echo "Get on up"
  strace -o trace_output.txt -c -Ttt funk_a
}

Obrigado.

    
por IsaacS 21.01.2017 / 19:37

2 respostas

6

strace pode apenas strace arquivos executáveis.

funk_a é uma função, uma construção de programação do shell, não algo que você possa executar.

A única coisa que strace poderia usar seria um novo shell que avalia o corpo dessa função como:

strace -o trace_output.txt -Ttt bash -c "$(typeset -f funk_a); funk_a"

(eu removi -c porque não faz sentido com -Ttt ).

Mas você verá todo o sistema chamado feito por bash para carregar e inicializar (e depois de limpar e sair), além da chamada de sistema write feita por essa função funk_a .

Ou você poderia dizer a strace para rastrear o pid do shell enquanto avalia a função funk_a :

strace -o trace_output.txt -Ttt -p "$$" &
funk_a
kill "$!"

Embora, no momento em que strace se anexa ao PID do shell, o shell poderia ter terminado de interpretar a função. Você poderia tentar alguma sincronização como

strace -o trace_output.txt  -Ttt -p "$$" &
tail -F trace_output.txt | read # wait for some output in trace_output.txt

funk_a
kill "$!"

Mas, mesmo assim, dependendo do momento, trace_output.txt incluiria algumas das chamadas de sistema usadas interpretar tail|read ou kill poderia matar strace antes de ter tido tempo de gravar o rastreio para o echo comando para o arquivo de saída.

Uma abordagem melhor poderia ser envolver a chamada para funk_a entre duas chamadas de sistema reconhecíveis, como

strace -fo >(sed -n '1,\|open("///dev/null|d
                     \|open("/dev///null|q;p' > trace_output.txt
  ) -Ttt -p "$$" &
sleep 1 # give enough time for strace to start
exec 3<  ///dev/null # start signal
funk_a
exec 3< /dev///null # end signal
    
por 21.01.2017 / 19:48
0

Descobri por mim mesmo depois de descobrir em este tópico que strace só pode chamar um executável.

Alterar o meu exemplo acima, da seguinte forma, funcionou.

util.sh

#!/bin/bash
echo "Earth, Wind, Fire and Water"

strace_sample.sh

#!/bin/bash

function funk_b {
  echo "Get on up"
  #strace -o funk_a.out -c -Ttt funk_a
  strace -o util.out -c -Ttt ./util.sh
}

Resultado

$ funk_b
Get on up
Earth, Wind, Fire and Water
$ more util.out 
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
  0.00    0.000000           0         7           read
  0.00    0.000000           0         1           write
  0.00    0.000000           0        27        18 open
:
    
por 21.01.2017 / 19:47