public inbox for systemtap@sourceware.org
 help / color / mirror / Atom feed
* access pointer and global variables
@ 2007-06-07  9:18 Wenji Huang
  2007-06-07 15:38 ` Stone, Joshua I
  2007-06-07 17:57 ` David Smith
  0 siblings, 2 replies; 10+ messages in thread
From: Wenji Huang @ 2007-06-07  9:18 UTC (permalink / raw)
  To: systemtap

  Hi guru,

    I just began to know about the project and ran into some problems.

    a. dereference pointer
       probe kernel.function("schedule").return{
          $prev can be accessed, but just treated as long type
          $prev->pid can't be accessed
        }
   
    b. Global variable
        how to get the value of global variables, seems that only local 
variables are accessible in probe point.

    c. char *
        probe kernel.function("sys_open") {
           //parameter list in source:   const char __user *filename, 
int flags, int mode)  

           $filename can be accessed, but how to get the string of 
filename point ?
        }

Thanks in advance!
*
Wenji*

 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: access pointer and global variables
  2007-06-07  9:18 access pointer and global variables Wenji Huang
@ 2007-06-07 15:38 ` Stone, Joshua I
  2007-06-07 17:57 ` David Smith
  1 sibling, 0 replies; 10+ messages in thread
From: Stone, Joshua I @ 2007-06-07 15:38 UTC (permalink / raw)
  To: Wenji Huang; +Cc: systemtap

Wenji Huang wrote:
>    c. char *
>        probe kernel.function("sys_open") {
>           //parameter list in source:   const char __user *filename, int 
> flags, int mode) 
>           $filename can be accessed, but how to get the string of 
> filename point ?
>        }

I'm not sure about your other questions, but I'll answer the easy one. 
To read a string from a pointer, use either kernel_string() or 
user_string().  Since $filename is a __user pointer, you should use the 
latter.

Alternately, you can use the tapset alias "syscall.open" which gives you 
variables that are already dereferenced.


Josh

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: access pointer and global variables
  2007-06-07  9:18 access pointer and global variables Wenji Huang
  2007-06-07 15:38 ` Stone, Joshua I
@ 2007-06-07 17:57 ` David Smith
  2007-06-07 18:09   ` Stone, Joshua I
  1 sibling, 1 reply; 10+ messages in thread
From: David Smith @ 2007-06-07 17:57 UTC (permalink / raw)
  To: Wenji Huang; +Cc: systemtap

Wenji Huang wrote:
>  Hi guru,
> 
>    I just began to know about the project and ran into some problems.
> 
>    a. dereference pointer
>       probe kernel.function("schedule").return{
>          $prev can be accessed, but just treated as long type
>          $prev->pid can't be accessed
>        }

Here's what is going on here.  We really don't have access to parameters 
in return probes.  So, we fake it.  When you access a parameter in a 
return probe, the systemtap translator actually creates an entry probe 
that cache's the parameter values so you can access them in the return 
probe.

But, we've thrown away the type information at that point, so the value 
in your case is just a long as far as systemtap is concerned.  So, to 
access $prev->pid you are going to have to write some code to access it. 
   See tapset/aux_syscalls.stp for examples of functions that take a 
pointer value and dereference fields from it.

(Alternatively you could write an entry probe yourself to cache the 
$prev->pid value if that is all you are interested in.)

-- 
David Smith
dsmith@redhat.com
Red Hat
http://www.redhat.com
256.217.0141 (direct)
256.837.0057 (fax)

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: access pointer and global variables
  2007-06-07 17:57 ` David Smith
@ 2007-06-07 18:09   ` Stone, Joshua I
  2007-06-07 18:35     ` David Smith
  0 siblings, 1 reply; 10+ messages in thread
From: Stone, Joshua I @ 2007-06-07 18:09 UTC (permalink / raw)
  To: David Smith; +Cc: Wenji Huang, systemtap

David Smith wrote:
> But, we've thrown away the type information at that point, so the value 
> in your case is just a long as far as systemtap is concerned.  So, to 
> access $prev->pid you are going to have to write some code to access it. 
>   See tapset/aux_syscalls.stp for examples of functions that take a 
> pointer value and dereference fields from it.
> 
> (Alternatively you could write an entry probe yourself to cache the 
> $prev->pid value if that is all you are interested in.)

Perhaps the SystemTap language is representing $prev as a plain long, 
but the translator should know better.  Whether we cache $prev->pid or 
we cache $prev and remember how to dereference ->pid, that's just a 
design decision.  But I think it's possible for the translator to still 
handle this automatically.

Josh

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: access pointer and global variables
  2007-06-07 18:09   ` Stone, Joshua I
@ 2007-06-07 18:35     ` David Smith
  2007-06-07 18:56       ` Stone, Joshua I
  0 siblings, 1 reply; 10+ messages in thread
From: David Smith @ 2007-06-07 18:35 UTC (permalink / raw)
  To: Stone, Joshua I; +Cc: Wenji Huang, systemtap

Stone, Joshua I wrote:
> David Smith wrote:
>> But, we've thrown away the type information at that point, so the 
>> value in your case is just a long as far as systemtap is concerned.  
>> So, to access $prev->pid you are going to have to write some code to 
>> access it.   See tapset/aux_syscalls.stp for examples of functions 
>> that take a pointer value and dereference fields from it.
>>
>> (Alternatively you could write an entry probe yourself to cache the 
>> $prev->pid value if that is all you are interested in.)
> 
> Perhaps the SystemTap language is representing $prev as a plain long, 
> but the translator should know better.  Whether we cache $prev->pid or 
> we cache $prev and remember how to dereference ->pid, that's just a 
> design decision.  But I think it's possible for the translator to still 
> handle this automatically.

Hmm.  What you are asking for is this:

probe kernel.function("schedule") {
     printf("pid is %d\n", $prev->pid)
     prev_copy = $prev
     printf("pid is still %d\n", prev_copy->pid)
}

That is going to be tricky to implement.


David "Grumble - dang users never satisfied.  Give them parameters in 
return probes, and they are happy for a moment.  Then they want more, 
always more.  I can remember when we only had toggle switches on the 
front of the vax and were happy to have them..." Smith

-- 
David Smith
dsmith@redhat.com
Red Hat
http://www.redhat.com
256.217.0141 (direct)
256.837.0057 (fax)

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: access pointer and global variables
  2007-06-07 18:35     ` David Smith
@ 2007-06-07 18:56       ` Stone, Joshua I
  2007-06-07 19:03         ` Stone, Joshua I
  0 siblings, 1 reply; 10+ messages in thread
From: Stone, Joshua I @ 2007-06-07 18:56 UTC (permalink / raw)
  To: David Smith; +Cc: Wenji Huang, systemtap

David Smith wrote:
> Hmm.  What you are asking for is this:
> 
> probe kernel.function("schedule") {
>     printf("pid is %d\n", $prev->pid)
>     prev_copy = $prev
>     printf("pid is still %d\n", prev_copy->pid)
> }
> 
> That is going to be tricky to implement.

That's not really what I meant.  If you figure out how to do that, 
awesome, but that certainly adds a lot of complication to SystemTap types.

Let me try to rephrase.  In an entry probe, we see $prev->pid and we 
know how to generate code to dereference it.  When we're generating code 
for the return probe, wouldn't you still know what the type looked like? 
  I suppose it depends on how you generate that code.  But when I see this:

     probe kernel.function("schedule").return {
         printf("pid is %d\n", $prev->pid)
     }

I expect that the translator could produce one of these options:

     probe kernel.function("schedule") {
         cache[...] = $prev
     }
     probe kernel.function("schedule").return {
         printf("pid is %d\n", cache[...]->pid)
         // The dereference happens using the same loc2c
         // generated function that the entry would have used.
     }

OR

     probe kernel.function("schedule") {
         cache[...] = $prev->pid
     }
     probe kernel.function("schedule").return {
         printf("pid is %d\n", cache[...])
     }

The former works if you're immediately generating code, so you don't 
have to remember the extra type information for long.  But I expect the 
latter should be a lot easier to do, at the expense of more caching 
memory if many fields are dereferenced.

> David "Grumble - dang users never satisfied.  Give them parameters in 
> return probes, and they are happy for a moment.  Then they want more, 
> always more.  I can remember when we only had toggle switches on the 
> front of the vax and were happy to have them..." Smith

I only ask because you're so good about providing. :)


Josh

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: access pointer and global variables
  2007-06-07 18:56       ` Stone, Joshua I
@ 2007-06-07 19:03         ` Stone, Joshua I
  2007-06-07 20:04           ` David Smith
  0 siblings, 1 reply; 10+ messages in thread
From: Stone, Joshua I @ 2007-06-07 19:03 UTC (permalink / raw)
  To: David Smith; +Cc: Wenji Huang, systemtap

Stone, Joshua I wrote:
>     probe kernel.function("schedule") {
>         cache[...] = $prev
>     }
>     probe kernel.function("schedule").return {
>         printf("pid is %d\n", cache[...]->pid)
>         // The dereference happens using the same loc2c
>         // generated function that the entry would have used.
>     }

I just realized that this still looks a lot like what you were grumbling 
about.  The difference I was try to make is that I don't expect that we 
should ever support users writing this kind of code directly.  Trying to 
track the "original" type of arbitrary longs passed around is extremely 
hairy.  But in a controlled environment, where this is happening behind 
the scenes in the translator, I think it's more manageable.

> OR
> 
>     probe kernel.function("schedule") {
>         cache[...] = $prev->pid
>     }
>     probe kernel.function("schedule").return {
>         printf("pid is %d\n", cache[...])
>     }

But I would still be happy with this, which I don't think would require 
too much change.

Josh

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: access pointer and global variables
  2007-06-07 19:03         ` Stone, Joshua I
@ 2007-06-07 20:04           ` David Smith
  2007-06-07 20:39             ` Stone, Joshua I
  0 siblings, 1 reply; 10+ messages in thread
From: David Smith @ 2007-06-07 20:04 UTC (permalink / raw)
  To: Stone, Joshua I; +Cc: Wenji Huang, systemtap

Stone, Joshua I wrote:
> Stone, Joshua I wrote:
>>     probe kernel.function("schedule") {
>>         cache[...] = $prev->pid
>>     }
>>     probe kernel.function("schedule").return {
>>         printf("pid is %d\n", cache[...])
>>     }
> 
> But I would still be happy with this, which I don't think would require 
> too much change.

I agree with you that this might be implementable, but is it what you 
would really want?  In a return probe would you want the original value 
of $prev->pid or the current value (assuming the function changed the 
data pointed to by $prev)?

I'd guess that most times you'd want the current value.

-- 
David Smith
dsmith@redhat.com
Red Hat
http://www.redhat.com
256.217.0141 (direct)
256.837.0057 (fax)

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: access pointer and global variables
  2007-06-07 20:04           ` David Smith
@ 2007-06-07 20:39             ` Stone, Joshua I
  2007-06-07 23:42               ` Jim Keniston
  0 siblings, 1 reply; 10+ messages in thread
From: Stone, Joshua I @ 2007-06-07 20:39 UTC (permalink / raw)
  To: David Smith; +Cc: Wenji Huang, systemtap

David Smith wrote:
> I agree with you that this might be implementable, but is it what you 
> would really want?  In a return probe would you want the original value 
> of $prev->pid or the current value (assuming the function changed the 
> data pointed to by $prev)?
> 
> I'd guess that most times you'd want the current value.

That's a hard question to answer, because it can easily go either way. 
For strace-like scripts, you generally want to say "this function with 
these arguments produced this return value" -- so you want the original 
values.  But there are certainly times when you want to see how the 
arguments were updated.

For a lot of cases, I think the arguments aren't modified, so it 
wouldn't matter when you read them.

I think we can either find a way to do both, for the best flexibility, 
or else pick the one that's the most sane (implementable? matches most 
users' expectation?) and document how it works.


Josh

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: access pointer and global variables
  2007-06-07 20:39             ` Stone, Joshua I
@ 2007-06-07 23:42               ` Jim Keniston
  0 siblings, 0 replies; 10+ messages in thread
From: Jim Keniston @ 2007-06-07 23:42 UTC (permalink / raw)
  To: Stone, Joshua I; +Cc: David Smith, Wenji Huang, systemtap

On Thu, 2007-06-07 at 13:39 -0700, Stone, Joshua I wrote:
> David Smith wrote:
> > I agree with you that this might be implementable, but is it what you 
> > would really want?  In a return probe would you want the original value 
> > of $prev->pid or the current value (assuming the function changed the 
> > data pointed to by $prev)?
> > 
> > I'd guess that most times you'd want the current value.
> 
> That's a hard question to answer, because it can easily go either way. 
> For strace-like scripts, you generally want to say "this function with 
> these arguments produced this return value" -- so you want the original 
> values.  But there are certainly times when you want to see how the 
> arguments were updated.

I agree: it depends.

In my current application of stap, the value I'm interested in is
regs->eip.  regs is the function arg, and its value doesn't change, but
the value of regs->eip does change.  When I refer to $regs->eip in the
return probe, what I want is entry_value($regs)->eip, but what stap
gives me is entry_value($regs->eip).

So I had to cache the value of regs, and write an embedded-C function
(to be called from the return probe) to cast regs[tid()] back to a
struct pt_regs* and get the (updated) eip member.  (Cuz stap doesn't
support casts, right?)

> 
> For a lot of cases, I think the arguments aren't modified, so it 
> wouldn't matter when you read them.
> 
> I think we can either find a way to do both, for the best flexibility, 
> or else pick the one that's the most sane (implementable? matches most 
> users' expectation?) and document how it works.

I'd much rather see the former.  Make stap require the script author to
specify what he/she wants -- e.g., via a built-in function such as
entry_value($arg) -- at the very least if it's a dereferenced pointer.
Even if it's just an int or something, the current practice of allowing
plain old $arg in a return probe could be misleading.
 
> 
> 
> Josh

Jim

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2007-06-07 23:42 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-06-07  9:18 access pointer and global variables Wenji Huang
2007-06-07 15:38 ` Stone, Joshua I
2007-06-07 17:57 ` David Smith
2007-06-07 18:09   ` Stone, Joshua I
2007-06-07 18:35     ` David Smith
2007-06-07 18:56       ` Stone, Joshua I
2007-06-07 19:03         ` Stone, Joshua I
2007-06-07 20:04           ` David Smith
2007-06-07 20:39             ` Stone, Joshua I
2007-06-07 23:42               ` Jim Keniston

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).