debabrata das
2008-Nov-24 14:03 UTC
[dtrace-discuss] Printing the main script responsible for writing a file
Hi all, I am new in dtrace. But I have urgent requirement. I would like to know a name of program which is responsible for updating a file. I have written the small following program : #!/usr/sbin/dtrace -s syscall::open*:entry /pid == $1/ { printf("%s %s %d", execname, copyinstr(arg0), pid); } Now if I ruun this then I get following output : -bash-3.00$ ./text.d | grep deba dtrace: script ''./text.d'' matched 2 probes 8 402 open64:entry bash /tmp/deba.txt 18786 Now I want to know which script is updating this file. I would like to the see the output of "ptree 18786". I am not sure how to this structure of ptree or the name of the script. Thanks Deba -- This message posted from opensolaris.org
Jon Haslam
2008-Nov-25 13:50 UTC
[dtrace-discuss] Printing the main script responsible for writing a file
Hi Deba,> Now I want to know which script is updating this file. I would like to the see the output of "ptree 18786". I am not sure how to this structure of ptree or the name of the script.The simple approach may just be to stop the target process, ptree it and then continue it: #!/usr/sbin/dtrace -s #pragma D option destructive syscall::open*:entry /pid == $1/ { printf("%s %s %d", execname, copyinstr(arg0), pid); stop(); system("ptree %d", pid); system("prun %d", pid); } Jon.
Jonathan Adams
2008-Dec-10 23:18 UTC
[dtrace-discuss] Printing the main script responsible for writing a file
On Mon, Nov 24, 2008 at 06:03:44AM -0800, debabrata das wrote:> Hi all, > > I am new in dtrace. But I have urgent requirement. I would like to know a name of program which is responsible for updating a file. I have written the small following program : > > #!/usr/sbin/dtrace -s > > syscall::open*:entry > /pid == $1/ > { > printf("%s %s %d", execname, copyinstr(arg0), pid); > } > > Now if I ruun this then I get following output : > > -bash-3.00$ ./text.d | grep deba > dtrace: script ''./text.d'' matched 2 probes > 8 402 open64:entry bash /tmp/deba.txt 18786 > > Now I want to know which script is updating this file. I would like to the see the output of "ptree 18786". I am not sure how to this structure of ptree or the name of the script.you want curpsinfo->pr_psargs; it''s a string which contains the string that "ptree" outputs, which is the "argv" array, separated by spaces, truncated to 80 characters. Cheers, - jonathan
Jim Hall
2008-Dec-11 14:21 UTC
[dtrace-discuss] Printing the main script responsible for writing a file
On Wed, 10 Dec 2008, Jonathan Adams wrote:> you want curpsinfo->pr_psargs; it''s a string which contains the string that > "ptree" outputs, which is the "argv" array, separated by spaces, truncated > to 80 characters.is there a way to get pargs(1) type output, i.e. > 80 chars? JIM
Jonathan Adams
2008-Dec-11 20:31 UTC
[dtrace-discuss] Printing the main script responsible for writing a file
On Thu, Dec 11, 2008 at 09:21:45AM -0500, Jim Hall wrote:> > > > On Wed, 10 Dec 2008, Jonathan Adams wrote: > > > you want curpsinfo->pr_psargs; it''s a string which contains the string that > > "ptree" outputs, which is the "argv" array, separated by spaces, truncated > > to 80 characters. > > is there a way to get pargs(1) type output, i.e. > 80 chars?It''s possible, but not easy, and is subject to corruption by the user app. Something like: --- cut here --- #!/usr/sbin/dtrace -s #pragma D option quiet uint_t this arg; uint_t this argc; uintptr_t this argv; proc:::exec-success { this->argc = 0; } proc:::exec-success { printf("%d: %s\n", pid, curpsinfo->pr_psargs); this->arg = 0u; this->argc = curthread->t_procp->p_user.u_argc; this->argp = curthread->t_procp->p_user.u_argv; this->model = curpsinfo->pr_dmodel; } proc:::exec-success / this->arg < this->argc / { this->ptr = (this->model == PR_MODEL_ILP32) ? (uintptr_t)*(uint_t *)copyin(this->argp + 4 * this->arg, 4) : *(uintptr_t *)copyin(this->argp + 8 * this->arg, 8); printf("argv[%d]: %S\n", this->arg, copyinstr(this->ptr)); this->arg++; } proc:::exec-success / this->arg < this->argc / { this->ptr = (this->model == PR_MODEL_ILP32) ? (uintptr_t)*(uint_t *)copyin(this->argp + 4 * this->arg, 4) : *(uintptr_t *)copyin(this->argp + 8 * this->arg, 8); printf("argv[%d]: %S\n", this->arg, copyinstr(this->ptr)); this->arg++; } --- cut here --- As written, this will get the first two (0 and 1) arguments to any command which is executed. By duplicating the final clause additional times, more arguments will be printed. You can change all of the "proc:::exec-success" to another probe of interest, and add a predicate to the second enabling to restrict the printing: --- cut here --- #!/usr/sbin/dtrace -s #pragma D option quiet uint_t this arg; uint_t this argc; uintptr_t this argv; syscall::open64:return { this->argc = 0; } syscall::open64:return / errno == 0 && fds[arg0].fi_pathname == "/etc/passwd" / { printf("%d: %s\n", pid, curpsinfo->pr_psargs); this->arg = 0u; this->argc = curthread->t_procp->p_user.u_argc; this->argp = curthread->t_procp->p_user.u_argv; this->model = curpsinfo->pr_dmodel; } syscall::open64:return / this->arg < this->argc / { this->ptr = (this->model == PR_MODEL_ILP32) ? (uintptr_t)*(uint_t *)copyin(this->argp + 4 * this->arg, 4) : *(uintptr_t *)copyin(this->argp + 8 * this->arg, 8); printf("argv[%d]: %S\n", this->arg, copyinstr(this->ptr)); this->arg++; } ... more copies of the last one ... --- cut here --- Will print the full path of any process using the open64() system call to open /etc/passwd. If you do a "cat /etc/passwd" in another window: % ./foo.d 375: cat /etc/passwd argv[0]: cat\0 argv[1]: /etc/passwd\0 Cheers, - jonathan