strace не находит функцию shell с ошибкой "Can't stat"

Удаление файла не обязательно приводит к тому, что вы думаете. Вот почему в UNIX-подобных системах системный вызов называется unlink , а не delete . На странице руководства:

unlink() deletes a name from the filesystem.  If that name was the last
link to a file and no processes have the file open, the file is deleted
and the space it was using is made available for reuse.

If the name was the last link to a file but any processes still have
the file open, the file will remain in existence until  the  last  file
descriptor referring to it is closed.

Как следствие, пока компрессор / архиватор данных читает из файла, этот файл остается существующим, занимая место в файловой системе.

1
22.01.2017, 01:44
2 ответа

Я выяснил, обнаружив в этом потоке , что strace может вызывать только исполняемый файл.

Сработало изменение моего примера, приведенного выше.

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
}

Результат

$ 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
:
0
27.01.2020, 23:14

strace может только strace исполняемые файлы.

funk_a - это функция, программная конструкция оболочки, а не то, что вы можете выполнить.

Единственное, что strace может strace, - это новая оболочка, которая вычисляет тело этой функции, например:

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

(Я удалил -c , поскольку это не имеет смысла с -Ttt ).

Но затем вы увидите всю систему, вызываемую bash для загрузки и инициализации (а затем для очистки и выхода) в дополнение к этому системному вызову write сделано этой функцией funk_a .

Или вы можете указать strace для отслеживания pid оболочки, пока она оценивает функцию funk_a :

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

Хотя к тому времени, когда strace присоединяется к PID оболочки, оболочка вполне могла завершить интерпретацию функции. Вы можете попробовать синхронизацию, например

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

funk_a
kill "$!"

, но даже тогда, в зависимости от времени, trace_output.txt будет включать некоторые из используемых системных вызовов интерпретировать tail | read или kill мог убить strace до того, как он успел записать трассировку для команды echo в выходной файл.

Лучшим подходом могло бы быть размещение вызова funk_a между двумя распознаваемыми системными вызовами, такими как

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
6
27.01.2020, 23:14

Теги

Похожие вопросы