1

I'm trying to call a self-defined function funk_a in strace but it doesn't seem to find it. I confirmed that funk_a can be called by itself. I appreciate any opinions.

$ 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
}

Thank you.

  • what is the output of type funk_a? – ctrl-alt-delor Jan 22 '17 at 11:34
6

strace can only strace executable files.

funk_a is a function, a programming construct of the shell, not something you can execute.

The only thing strace could strace would be a new shell that evalutes the body of that function like:

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

(I removed -c as it makes no sense with -Ttt).

But you'll then see all the system called made by bash to load and initialise (and after to clean-up and exit) in addition to that one write system call made by that funk_a function.

Or you could tell strace to trace the pid of the shell while it evaluates the funk_a function:

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

Though, by the time strace attaches to the PID of the shell, the shell could very well have finished interpreting the function. You could try some synchronisation like

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

funk_a
kill "$!"

But even then depending on timing, trace_output.txt would include some of the system calls used interpret tail|read, or kill could kill strace before it has had the time to write the trace for the echo command to the output file.

A better approach could be to wrap the call to funk_a between two recognisable system calls like

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
0

Figured out by myself after finding out in this thread that strace can only call an executable.

Changing my example above as follows worked.

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
}

Result

$ 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
:

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.