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.
I think bug #5634 can solve this issue as below: $ptr("struct argument")->member
(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.
(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.
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)) }
For the timing part atleast, the newer kernels have a mechanism to do similar -- look at samples/kprobes/kretprobe_example.c as an example.
(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
*** Bug 10701 has been marked as a duplicate of this bug. ***
(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.
We have both @entry and @cast; the original request is expressible as in comment #4.