Bug 2645 - Need a syntax to specify optional probes
Summary: Need a syntax to specify optional probes
Status: RESOLVED FIXED
Alias: None
Product: systemtap
Classification: Unclassified
Component: translator (show other bugs)
Version: unspecified
: P2 enhancement
Target Milestone: ---
Assignee: Frank Ch. Eigler
URL:
Keywords:
Depends on:
Blocks: 2295
  Show dependency treegraph
 
Reported: 2006-05-08 20:58 UTC by Josh Stone
Modified: 2006-06-06 01:37 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Last reconfirmed: 2006-06-02 14:59:54


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Josh Stone 2006-05-08 20:58:47 UTC
see http://sources.redhat.com/ml/systemtap/2006-q2/msg00286.html

Summary of desired behavior: given

  probe FOO ? { }
  probe alias = BAR ?, BAZ ? { }

If FOO is not found, then that probe should be discarded.  If both BAR and BAZ
are not found, there are two cases:

  probe alias { } // ERROR: probepoint not found
  probe alias ? { } // ok, probe is discarded


Similarly, if a syscall "sys_foobar" isn't found:

tapset:
  probe syscall.foobar = kernel.function("sys_foobar") ? {}

user script:
  probe syscall.foobar {} // error, probepoint not found
  probe syscall.foobar ? {} // ok, probe is discarded

  probe syscall.* {} // ok if all non-optional syscall probes were found,
                     // or if all are optional, then at least one was found
Comment 1 bibo,mao 2006-05-09 03:52:02 UTC
what about this kind of tapset, user script should care nothing about whether is
it optional or not.

tapset:
  probe syscall.foobar = kernel.function("sys_foobar") ? {}     optional 
  probe syscall.foobar1 = kernel.function("sys_foobar1") {}     non-optional
 
user script:
  probe syscall.foobar  {}    // ok, probe is discarded
  probe syscall.foobar1 {}   // ERROR: probepoint not found

  probe syscall.* {} // ok if all non-optional syscall probes were found,
                     // or if all are optional, then at least one was found
Comment 2 Josh Stone 2006-05-09 21:09:02 UTC
(In reply to comment #1)
> what about this kind of tapset, user script should care nothing about 
> whether is it optional or not.

The user doesn't know whether the lower level tapset has marked a binding as
optional or not.  Thus, when the user writes a probe on syscall.foobar, they
will likely be surprised if this probe was automatically removed.  We should
avoid surprising results.

At a minimum this should be an warning, but I still think it's better to be an
error.
Comment 3 Frank Ch. Eigler 2006-05-14 12:01:05 UTC
If I understand the concern correctly, in this scenario,
   probe group.f = pp ? { }  # in tapset
   probe group.* { }         # in user script
and for missing "pp", should this succeed or fail?  There is an ambiguity.
With the current flavouring of the code, it would fail, since the group.*
match would expand to an empty set of derived_probe's.

With a little bit of extra work, we can let the tapset author make this pass.
Let's provide a new probe point "never", which would be similar to "begin"
and "end" but never actually run its handler.  (It doesn't even need to show
up in the translated C code.)  Then, if a tapset author wants to make the
alias succeed with a missing pp, even for non-optional users, he can say:
  probe group.f = pp ? , never { } # in tapset
Comment 4 Josh Stone 2006-05-14 20:22:58 UTC
(In reply to comment #3)
> If I understand the concern correctly, in this scenario,
>    probe group.f = pp ? { }  # in tapset
>    probe group.* { }         # in user script
> and for missing "pp", should this succeed or fail?  There is an ambiguity.
> With the current flavouring of the code, it would fail, since the group.*
> match would expand to an empty set of derived_probe's.

I think failure is correct here.  With missing "pp", "group.*" should fail, yet
"group.* ?" would be ok.  If there were another alias, "probe group.g = qq ?
{}", then "group.*" will succeed iff at least one of "pp" and "qq" are found.

> With a little bit of extra work, we can let the tapset author make this pass.
> Let's provide a new probe point "never", which would be similar to "begin"
> and "end" but never actually run its handler.  (It doesn't even need to show
> up in the translated C code.)  Then, if a tapset author wants to make the
> alias succeed with a missing pp, even for non-optional users, he can say:
>   probe group.f = pp ? , never { } # in tapset

I think this is a good workaround if a tapset author really wants to write a
probe that could possibly do nothing.  While I personally think this should be
discouraged, for the reasons I gave in comment #2, it may be good to allow this
possibility to cover all use cases.
Comment 5 Frank Ch. Eigler 2006-06-02 18:16:47 UTC
patch committed
Comment 6 Josh Stone 2006-06-02 19:15:44 UTC
Patch confirmed.  I made changes to the process tapset to take advantage of
this, and it appears to work very well.  This is a powerful capability for
tapset authors -- thank you!
Comment 7 Josh Stone 2006-06-02 19:32:16 UTC
Sorry to reopen this -- I found a case that doesn't work, but probably should:

probe alias = kernel.function("foobar") { }
probe alias ? { }

semantic error: no match for probe point
while: resolving probe point kernel.function("foobar")

The use of 'alias' is marked optional, so this shouldn't be an error.
Comment 8 Frank Ch. Eigler 2006-06-02 23:14:28 UTC
let's try that one again :-)

(BTW, the "process.signal_handle" alias doesn't expand at all on my FC5 machine.)
Comment 9 Josh Stone 2006-06-03 00:20:16 UTC
(In reply to comment #8)
> let's try that one again :-)

Better -- you indeed pass the test I gave before.  How about multiple levels of
indirection?

probe x = kernel.function("foobar") {}
probe y = x {}
probe y ? {}

semantic error: no match for probe point
while: resolving probe point kernel.function("foobar")
Pass 2: analysis failed.  Try again with more '-v' (verbose) options.

:(

> (BTW, the "process.signal_handle" alias doesn't expand at all on my FC5 machine.)

Strange - it works for me.  On i686 RHEL4 it expands to the function version,
and on x86_64 FC5 it expands to the inline version.  The function being probed
(handle_signal) is not marked as inline, so apparently the compiler is taking
liberties.

Either way, that function should definitely exist!  I would suspect this is a
compiler/elfutils issue, so we may need a new bug opened.
Comment 10 Frank Ch. Eigler 2006-06-03 00:32:12 UTC
> How about multiple levels of indirection?

I'm unsure about to what extent it makes sense to push "?" all the way down.
If it's obviously sensible, it can be implemented e.g. by having the
alias_expansion_builder::build routine pass the incoming location->optional
flag to the alias_derived_probe->locations[].

Multiple levels of implicit optionality make me a bit uneasy.  In your example,
the author of the middle alias ("probe y = x {}") could be interpreted as
asserting x's existence.
Comment 11 Frank Ch. Eigler 2006-06-05 19:46:05 UTC
> How about multiple levels of indirection?

The new code passes down "?" from outer to inner levels of indirection.
Comment 12 Josh Stone 2006-06-05 21:20:41 UTC
(In reply to comment #10)
> the author of the middle alias ("probe y = x {}") could be interpreted as
> asserting x's existence.

Except that if 'y' is never instantiated, there's no error.  It's not until
there's a use of 'y' that an error is generated, and if that use is marked
optional, then why should it be an error?

(In reply to comment #11)
> The new code passes down "?" from outer to inner levels of indirection.
Verified.

I have another weird case, but I'm not sure of the right answer here.

probe x = kernel.function("sys_open"), kernel.function("foobar") {}
probe x {/*1*/}
probe x ? {/*2*/}

#1 generates an error, and rightly so.

#2 results in a probe on "sys_open" only, ignoring the missing "foobar".  Is
this what we want?  Or should 'x' be treated as an entire entity, such that if
not all required components of 'x' are found, it is omitted completely.  That
is, #2 would be completely removed if 'x' cannot be expanded correctly -- all or
nothing.

It feels weird to me either way, so I'd like to hear another opinion.
Comment 13 Frank Ch. Eigler 2006-06-06 00:08:09 UTC
It seems to me like your two examples in comment #12 somewhat contradict each
other.  I'd like to retreat from complexity and try the current simple-to-explain
behavior ("? is pushed down all the way through wildcard / alias expansion") for
a while.
Comment 14 Josh Stone 2006-06-06 01:37:41 UTC
I'll grant that I may have been overthinking it -- in the quest for
completeness, it's easy to lose sight.  I always figure it's better to document
any & all concerns, because it's easy to forget them later.

What you've implemented now looks good.