Hello!

Thanks a lot the answer, what use in your script it doesn't work in my script:
...
/ (arg0 != NULL) && (execname == "ps") && (copyinstr(arg0) ==
("/proc/"+$$1+"/psinfo")) /
...
This was the error:
$ ./process_ps.d 905
dtrace: failed to compile script ./process_ps.d: line 11: operands
have incompatible types: "string" + "string"

but with this
/ (arg0 != NULL) && (execname == "ps") && (copyinstr(arg0) ==
strjoin(strjoin("/proc/",$$1),"/psinfo")) /
it working fine

To understand what is my goal:
$ ./process_ps.d 905
Your parameter(s):      905
Current pid: 990
Current pid: 990
dtrace: error on enabled probe ID 2 (ID 46032: syscall::open:entry):
invalid address (0xd2786f9f) in predicate at DIF offset 120
syscall::open:entry     ->      /proc/905/psinfo (16)
syscall::open:entry     ->      xxxxxyyyyypsinfo (Modified)
syscall::open:entry     ->      /proc/990/psinfo (16)
syscall::open:entry     ->      xxxxxyyyyypsinfo (Modified)
^C

The script:
$ cat process_ps.d
#!/usr/sbin/dtrace -qs
#pragma D option quiet
#pragma D option destructive

BEGIN {
        printf("Your parameter(s):\t%s\n", $$1);
        printf("Current pid: %d\n", $pid);
        printf("Current pid: %s\n", lltostr($pid));
}

syscall::open:entry
/ (arg0 != NULL) && (execname == "ps") && ((copyinstr(arg0) ==
strjoin(strjoin("/proc/",$$1),"/psinfo")) || (copyinstr(arg0) ==
strjoin(strjoin("/proc/",lltostr($pid)),"/psinfo")))/
{
        printf("%s:%s:%s:%s\t->\t%s (%d)\n", probeprov, probemod,
probefunc, probename, copyinstr(arg0), strlen(copyinstr(arg0)));
        copyoutstr("xxxxxyyyyy", arg0, 10);
        printf("%s:%s:%s:%s\t->\t%s (Modified)\n", probeprov,
probemod, probefunc, probename, copyinstr(arg0));
}

The result(output) on an other terminal:
When the script doesn't run:
$ ps -ef | egrep -i "dtrace|fsf|terminal" | grep -iv grep
    root     3     0   0 20:25:14 ?           0:04 fsflush
    root   905     1   2 20:37:17 ?           0:55 /usr/bin/gnome-terminal

After i start to run the script:
$ ps -ef | egrep -i "dtrace|fsf|terminal" | grep -iv grep
    root     3     0   0 20:25:14 ?           0:04 fsflush

After i cancel the script:
$ ps -ef | egrep -i "dtrace|fsf|terminal" | grep -iv grep
    root     3     0   0 20:25:14 ?           0:04 fsflush
    root   905     1   2 20:37:17 ?           0:55 /usr/bin/gnome-terminal

My problem was how can i modify ps output, after i check ps's syscalls
(i don't check kernel space calls, just syscalls), i find
syscall::open:entry ask info about the process, and
syscall::write:return write the data to the terminal/console etc.....

If you modify the syscall::open:entry calls to a wrong call, the
result will be an error and the syscall::write:return doesn't contain
error string.

Cni

2009/12/8 Jonathan Adams <[email protected]>:
>
> This is a classic userland data access issue;  if the memory holding the
> string has not been touched by either the program or the kernel, it's not
> possible to map it in from a dtrace probe.  The usual workaround is to delay
> doing the copyin until after the kernel has read the string, typically by
> using the return probe.  Your script would look like:
>
> --- cut here ---
> #!/usr/sbin/dtrace -s
>
> dtrace:::BEGIN
> {
>        printf("Parameter(s):\t%s\n", $$1);
> }
>
> syscall::open:entry
> / arg0 != NULL &&  execname == "ps" /
> {
>        self->file = arg0;
> }
>
> syscall::open:return
> / self->file && copyinstr(self->file) == ("/proc/" + $$1 + "/psinfo") /
> {
>        printf("%s:%s:%s:%s\t->\t%s (%d)\n", probeprov, probemod,
>            probefunc, probename, copyinstr(self->file),
>            strlen(copyinstr(self->file)));
> }
>
> /* free the thread-local variable after we're done, or if the thread exits */
> syscall::open:return, proc:::lwp-exit
> /self->file/
> {
>        self->file = 0;
> }
> --- cut here ---
>
> Make sense?
>
> Cheers,
> - jonathan
_______________________________________________
dtrace-discuss mailing list
[email protected]

Reply via email to