File: calltrace.d

package info (click to toggle)
dtrace 2.0.5-1
  • links: PTS
  • area: main
  • in suites: sid
  • size: 24,408 kB
  • sloc: ansic: 61,247; sh: 17,997; asm: 1,717; lex: 947; awk: 754; yacc: 695; perl: 37; sed: 17; makefile: 15
file content (95 lines) | stat: -rwxr-xr-x 3,100 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/*
 * Oracle Linux DTrace.
 * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
 * Licensed under the Universal Permissive License v 1.0 as shown at
 * http://oss.oracle.com/licenses/upl.
 */

/*
 *  NAME
 *    calltrace.d - time all system calls for the cp command
 *
 *  SYNOPSIS
 *    sudo dtrace -s calltrace.d
 *
 *  DESCRIPTION
 *    List and time all the system calls that are executed during
 *    a cp command.
 *
 *  NOTES
 *    - This script traces all system calls that are executed when
 *    a cp command is run.
 *
 *    This means that you need to execute the cp command while the
 *    script is running.  There are two ways to do this:
 *    o Execute this script in the background, and type in the cp command.
 *    o Alternatively, run the script in the foreground and type
 *    the cp command in a separate terminal window on the same system.
 *
 *    - You can use any file to copy, but you can also generate a file
 *    and then copy it.  This is an example how to create a 500 MB file,
 *    copy it with the cp command and remove both files again:
 *    $ dd if=/dev/zero of=tmp_file bs=100M seek=5 count=0
 *    $ cp tmp_file tmp_file2
 *    $ rm tmp_file tmp_file2
 *
 *    - The script needs to be terminated with ctrl-C.  In case the
 *    script is running in the background, get it to run in the
 *    foreground first by using the fg command and then use ctrl-C
 *    to terminate the process.  Otherwise, typing in ctrl-C will do.
 *
 *    - Although the results of an aggregation are automatically
 *    printed when the tracing terminates, in this case, we want to
 *    control the format of the output.  This is why the results are
 *    printed using printa() in the END probe
 */

/*
 *  Set the base value of the timer.  This is used as an offset in the
 *  return probe to calculate the time spent in a system call.
 *
 *  A predicate is used to select the cp command.  All other commands
 *  skip executing the clause and do not set ts_base.
 */
syscall:::entry
/ execname == "cp" /
{
  self->ts_base = timestamp;
}

/*
 *  The predicate ensures that the base timing has been set.
 *  Since this is only done for the cp command, no information
 *  is collected for the other processes.
 */
syscall:::return
/self->ts_base != 0/
{
/*
 *  Compute the time passed since the entry probe fired and
 *  convert the nanosecond value to microseconds.
 *
 *  Update the aggregation called totals with this time.  The
 *  execname (which is cp here) and the system call that caused
 *  the probe to fire, are the fields in the key.
 */
  this->time_call = (timestamp - self->ts_base)/1000;
  @totals[execname,probefunc] = sum(this->time_call);

/*
 *  Free the storage for ts_base.
 */
  self->ts_base = 0;
}

/*
 *  Print the results.  Use printf() to print a description of
 *  the contents of the aggregation.  The format string in printa()
 *  is used to create a table lay-out.
 */
END
{
  printf("System calls executed and their duration:\n");
  printa("%15s executed %18s - this took a total of %@8d microseconds\n",
         @totals);
}