/bin/sh DTrace Provider

A couple of days ago Brendan was chatting with me on irc and we got to discussing such a beast. Mainly looking at something simple in the way of the python and perl providers that others have worked on.

Well, to make a long story short (ok it will be longer later), I've coded up something that appears to work against the nevada clone tree of a couple of days ago, and logged RFE 6591476 to track it.

I'll be putting the diffs up in the next day or so, but for a teaser, here is the documentation.

sh Provider

The sh provider makes available probes that can be used to observe the behaviour of bourne shell scripts.

Overview

The sh provider makes available the following probes:


builtin-entryProbe that fires on entry to a shell builtin command.
builtin-returnProbe that fires on return from a shell builtin command.

exec-entryProbe that fires when the shell execs an external command.
exec-returnProbe that fires on return from an external command.

function-entryProbe that fires on entry into a shell function.
function-returnProbe that fires on return from a shell function.

lineProbe that fires before commands on a particular line of code are executed.

subshell-entryProbe that fires when the shell forks a subshell.
subshell-returnProbe that fires on return from a forked subshell.

script-beginProbe that fires before any commands in a script are executed.
script-endProbe that fires on script exit.

Arguments

The argument types to the sh provider are listed in the below table.


Probeargs[0]args[1]args[2]args[3]

builtin-entry,
exec-entry,
function-entry
char \*char \*intchar \*\*

builtin-return,
exec-return,
function-return
char \*char \*int

line char \*int

script-begin char \*

script-end char \*int

subshell-entry char \*pid_t
subshell-return char \*int

arg0 in all probes is the script name.

In the builtin, exec, and function entry probes, and the builtin, exec, and function return probes, arg1 is the name of the function, builtin or program being called. arg2 and arg3 in these entry probes are the argument count and a pointer to the argument list. In these return probes, arg2 is the return code from the function, builtin or program.

In the subshell-entry, arg1 is the pid of the forked subshell and in subshell-return probes, arg1 is the return code from the subshell.

In the line probe, arg1 is the line number.

In the script-end probe, arg1 is the exit code of the script.

Stability

The sh provider uses DTrace's stability mechanism to describe its stabilities, as shown in the following table. For more information on the stability mechanism see Chapter 39 of the Solaris Dynamic Tracing guide.

ElementName ClassData ClassDependancy Class
ProviderUnstableUnstableCommon
ModulePrivatePrivateUnknown
FunctionPrivatePrivateUnknown
NameUnstableUnstableCommon
ArgumentsUnstableUnstableCommon

The probes that gave me the most trouble were line and subshell-\*.

line was tricky as sh only does line numbers when it parses input. It has no concept of line numbers on execution, which is what we need.

So, I needed to add another structure element (line) to trenod, and every other struct that is cast over the top of it. In the first failed attempt, I set this to standin->flin whenever we allocated a new one of these nodes, I set line to this value. The problem with this is that if the parser hits a newline, this number gets incremented before we actually set it, which means that the last command on every line has the line number of the following line. Not quite what I wanted.

What I ended up going with was the creation of another variable in the fileblk structure (comline) that I set just before standin->flin is incremented. This looks like it works.

The subshell-\* probes were not initially going to be a part of this, but an assumption I made about com in execute() when coding the exec-\* probes ended up causing the shell to coredump on me. It turns out that com is properly defined when we fall through the switch to the TFORK code, but if we go directly into the TFORK case, it's something completely different (would you believe "1"?). So, I made the probe conditional on the node type. If it was a TFORK, then we do a subshell probe, otherwise we do an exec probe. This also appears to work.

In the meanwhile, I've been sending Brendan sh binaries and he's already started coding more tools for the DTrace Toolkit based on this provider, and I have to say that some of his ideas look pretty cool.

Technorati Tags: , ,

Comments:

Post a Comment:
Comments are closed for this entry.
About

* - Solaris and Network Domain, Technical Support Centre


Alan is a kernel and performance engineer based in Australia who tends to have the nasty calls gravitate towards him

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
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
   
       
Today
Links
Blogroll

No bookmarks in folder

Sun Folk

No bookmarks in folder

Non-Sun Folk
Non-Sun Folks

No bookmarks in folder