Bug 5899 - $ptr->member in return probe
Summary: $ptr->member in return probe
Status: RESOLVED WORKSFORME
Alias: None
Product: systemtap
Classification: Unclassified
Component: translator (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: ---
Assignee: Unassigned
URL:
Keywords:
: 10701 (view as bug list)
Depends on: 10943
Blocks:
  Show dependency treegraph
 
Reported: 2008-03-08 01:06 UTC by Jim Keniston
Modified: 2011-08-11 00:21 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jim Keniston 2008-03-08 01:06:58 UTC
When I refer to $ptr->member in a return probe, and $ptr is a function arg, what
I get is the value of $ptr->member as it was when the function was called.  If
the function changes the contents of the object $ptr points to, usually what I
want is the value of $ptr->member when the function returns.

Because of stap's non-support for casting stap variables to pointers, I have to
resort to imbedded C to dig out the value I want.

I'd like a way to specify what I want.  For example:
entry_value($ptr->member) gets me what I get today.
entry_value($ptr)->member gets the current value of member using the value of
ptr when the function was called.
I think $ptr->member should yield either an error or (preferably) the same thing
 as entry_value($ptr)->member.  If I want entry_value($ptr->member), I can just
save that value during my entry probe.
Comment 1 Masami Hiramatsu 2008-03-10 22:04:16 UTC
I think bug #5634 can solve this issue as below:
$ptr("struct argument")->member
Comment 2 Jim Keniston 2008-03-11 20:19:21 UTC
(In reply to comment #1)
> I think bug #5634 can solve this issue as below:
> $ptr("struct argument")->member
> 

That feature would be useful in general, but I'm not sure how it solves this
problem.  Are you suggesting something like this?

probe kernel.function("myfunc").return
{
    printf("foo->bar on entry was %d\n", $foo->bar);
    foo2 = $foo
    printf("foo->bar on return was %d\n", foo2("struct foo_struct")->bar);
}

I don't think it would be obvious to the average user that $foo->bar gets
evaluated at function entry, but foo2("struct foo_struct")->bar doesn't.

BTW, I said "If I want entry_value($ptr->member), I can just save that value
during my entry probe."  That's kind of optimistic.  The problem is, WHERE would
I save that value, so I know it belongs to this particular function instance? 
Yeah, I could create an associative array indexed by task and (say) stack
pointer (in case of recursion), but that's what this feature was created to
avoid.  In any case, that's just more evidence that we need to get this feature
right.
Comment 3 Masami Hiramatsu 2008-03-11 21:59:34 UTC
(In reply to comment #2)
> I don't think it would be obvious to the average user that $foo->bar gets
> evaluated at function entry, but foo2("struct foo_struct")->bar doesn't.

Indeed, we need something special descriptor to get entry value.
So, entry_value($foo)("struct foo_struct")->bar is ok for me.
Comment 4 Frank Ch. Eigler 2009-01-23 15:58:47 UTC
Daniel suggests that using this sort of facility for timing might be
useful too, where it's not the snapshot value of a $context var
but rather a function evaluated at that time might be desirable for
saving.  so ..

probe FOO.return { 
   println(gettimeofday_ns() - @entry(gettimeofday_ns()))
}

We'd still need @cast() support (bug #6704) to do this sort of thing:

probe FOO.return {
   println(@cast(@entry($param),"struct foo")->field))
}
Comment 5 Ananth Mavinakayanahalli 2009-01-27 11:04:47 UTC
For the timing part atleast, the newer kernels have a mechanism to do similar --
look at samples/kprobes/kretprobe_example.c as an example.
Comment 6 Jim Keniston 2009-01-27 21:40:23 UTC
(In reply to comment #5)
> For the timing part atleast, the newer kernels have a mechanism to do similar --
> look at samples/kprobes/kretprobe_example.c as an example.

Yes.  #5916 is about exploiting this kretprobes feature.  There's also a patch
for uprobes -- #5973 -- to add the same capability.  You could use it to cache
any kind or amount of data between call and return.

This provides more efficient communication between call and return, but it
doesn't solve the problem at hand -- namely, the desire to deref pointers at
return time instead at call time.

A fairly simple patch would add a similar capability to

Comment 7 Roland McGrath 2009-10-23 23:20:07 UTC
*** Bug 10701 has been marked as a duplicate of this bug. ***
Comment 8 Josh Stone 2009-11-12 01:27:09 UTC
(In reply to comment #4)
> probe FOO.return {
>    println(@cast(@entry($param),"struct foo")->field))
> }

If we decide to make $param->field implicitly work this way, then we can use the
same internal mechanisms as @cast without requiring the user to know the type.
We can translate the pointer alone, and then pass that type die to
dwflpp::literal_stmt_for_pointer to read the rest, so we get two generated
functions:

  $param->field ==> _dwarf_tvar_get_cast_1(@entry(_dwarf_tvar_get_param_0()))

The @entry processing can go from here to save the expression as needed.
Comment 9 Frank Ch. Eigler 2011-08-11 00:21:54 UTC
We have both @entry and @cast; the original request is expressible as in comment #4.