All, I have the following dtrace script: syscall::*fork*:entry /curpsinfo->pr_argc > 0/ { this->argp = (uintptr_t)(curpsinfo->pr_dmodel == PR_MODEL_ILP32 ? *(uint32_t*)copyin(curpsinfo->pr_argv + 0 * 4, 4) : *(uint64_t*)copyin(curpsinfo->pr_argv + 0 * 8, 8)); this->arg1 = copyinstr(this->argp); printf("first arg: %s\n", this->arg1); } I am trying to get the non-truncated first parameter of every process that forks. The above script works, except once in a while I get these messages due to unmapped pages: dtrace: error on enabled probe ID 1 (ID 19253: syscall::fork1:entry): invalid address (0xffbfe000) in action #1 at DIF offset 232 What can I do to avoid this issue? I am on Solaris 10 boxes. --Matt Zyzik
On Fri, May 01, 2009 at 01:08:44PM -0400, Zyzik, Matt wrote:> All, > > I have the following dtrace script: > > syscall::*fork*:entry > /curpsinfo->pr_argc > 0/ > { > this->argp = (uintptr_t)(curpsinfo->pr_dmodel == PR_MODEL_ILP32 ? > *(uint32_t*)copyin(curpsinfo->pr_argv + 0 * 4, 4) : > *(uint64_t*)copyin(curpsinfo->pr_argv + 0 * 8, 8)); > this->arg1 = copyinstr(this->argp); > printf("first arg: %s\n", this->arg1); } > > I am trying to get the non-truncated first parameter of every process that forks. The above script works, except once in a while I get these messages due to unmapped pages: > > dtrace: error on enabled probe ID 1 (ID 19253: syscall::fork1:entry): invalid address (0xffbfe000) in action #1 at DIF offset 232 > > What can I do to avoid this issue? I am on Solaris 10 boxes.If your script will run before the processes you''re interested in, you could do: proc:::exec { self->name = args[0]; } proc:::exec-failure { self->name = 0; } proc:::exec-success /self->name != 0/ { proc_execname[curpsinfo->pr_addr] = self->name; self->name = 0; } proc:::create { this->arg0 = proc_arg0[curpsinfo->pr_addr]; this->arg0 = (this->arg0 != NULL)? this->arg0 : strtok(curpsinfo->pr_psargs, " "); proc_arg0[args[0]->pr_addr] = this->arg0; printf("%s", this->arg0); } proc:::exit { proc_arg0[curpsinfo->pr_addr] = 0; } This will give you the pathname passed to exec, not the value of argv[0]. If you want that, replace all of the ''exec*'' probes with: proc:::exec-success { proc_execname[curpsinfo->pr_addr] copyinstr((uintptr_t)(curpsinfo->pr_dmodel == PR_MODEL_ILP32 ? *(uint32_t*)copyin(curpsinfo->pr_argv + 0 * 4, 4) : *(uint64_t*)copyin(curpsinfo->pr_argv + 0 * 8, 8))); } Cheers, - jonathan
>> All, >> >> I have the following dtrace script: >> >> syscall::*fork*:entry >> /curpsinfo->pr_argc > 0/ >> { >> this->argp = (uintptr_t)(curpsinfo->pr_dmodel == PR_MODEL_ILP32 ? >> *(uint32_t*)copyin(curpsinfo->pr_argv + 0 * 4, 4) : >> *(uint64_t*)copyin(curpsinfo->pr_argv + 0 * 8, 8)); >> this->arg1 = copyinstr(this->argp); >> printf("first arg: %s\n", this->arg1); } >> >> I am trying to get the non-truncated first parameter of every process that forks. The above script works, except once in a while I get these messages due to unmapped pages: >> >> dtrace: error on enabled probe ID 1 (ID 19253: syscall::fork1:entry): >> invalid address (0xffbfe000) in action #1 at DIF offset 232 >> >> What can I do to avoid this issue? I am on Solaris 10 boxes. > > If your script will run before the processes you''re interested in, you could do: > > > proc:::exec > { > self->name = args[0]; > } > > proc:::exec-failure > { > self->name = 0; > } > > proc:::exec-success > /self->name != 0/ > { > proc_execname[curpsinfo->pr_addr] = self->name; > self->name = 0; > } > > proc:::create > { > this->arg0 = proc_arg0[curpsinfo->pr_addr]; > this->arg0 = (this->arg0 != NULL)? > this->arg0 : strtok(curpsinfo->pr_psargs, " "); > proc_arg0[args[0]->pr_addr] = this->arg0; > > printf("%s", this->arg0); > } > > proc:::exit > { > proc_arg0[curpsinfo->pr_addr] = 0; > } > > This will give you the pathname passed to exec, not the value of argv[0]. If you want that, replace all of the ''exec*'' probes with: > > proc:::exec-success > { > proc_execname[curpsinfo->pr_addr] > copyinstr((uintptr_t)(curpsinfo->pr_dmodel == PR_MODEL_ILP32 ? > *(uint32_t*)copyin(curpsinfo->pr_argv + 0 * 4, 4) : > *(uint64_t*)copyin(curpsinfo->pr_argv + 0 * 8, 8))); } >I agree this solution would work if my dtrace script ran before the processes I am interested in, but I don''t have that option. I am trying to run this script amongst long running daemons. Is there any way to accomplish what I am trying to do? I can sleep well if someone confirms it''s not possible. --Matt
On Fri, May 01, 2009 at 02:19:16PM -0400, Zyzik, Matt wrote:> >> All, > >> > >> I have the following dtrace script: > >> > >> syscall::*fork*:entry > >> /curpsinfo->pr_argc > 0/ > >> { > >> this->argp = (uintptr_t)(curpsinfo->pr_dmodel == PR_MODEL_ILP32 ? > >> *(uint32_t*)copyin(curpsinfo->pr_argv + 0 * 4, 4) : > >> *(uint64_t*)copyin(curpsinfo->pr_argv + 0 * 8, 8)); > >> this->arg1 = copyinstr(this->argp); > >> printf("first arg: %s\n", this->arg1); } > >> > >> I am trying to get the non-truncated first parameter of every process that forks. The above script works, except once in a while I get these messages due to unmapped pages: > >> > >> dtrace: error on enabled probe ID 1 (ID 19253: syscall::fork1:entry): > >> invalid address (0xffbfe000) in action #1 at DIF offset 232 > >> > >> What can I do to avoid this issue? I am on Solaris 10 boxes. > > > > If your script will run before the processes you''re interested in, you could do: > > > > > > proc:::exec > > { > > self->name = args[0]; > > } > > > > proc:::exec-failure > > { > > self->name = 0; > > } > > > > proc:::exec-success > > /self->name != 0/ > > { > > proc_execname[curpsinfo->pr_addr] = self->name; > > self->name = 0; > > } > > > > proc:::create > > { > > this->arg0 = proc_arg0[curpsinfo->pr_addr]; > > this->arg0 = (this->arg0 != NULL)? > > this->arg0 : strtok(curpsinfo->pr_psargs, " "); > > proc_arg0[args[0]->pr_addr] = this->arg0; > > > > printf("%s", this->arg0); > > } > > > > proc:::exit > > { > > proc_arg0[curpsinfo->pr_addr] = 0; > > } > > > > This will give you the pathname passed to exec, not the value of argv[0]. If you want that, replace all of the ''exec*'' probes with: > > > > proc:::exec-success > > { > > proc_execname[curpsinfo->pr_addr] > > copyinstr((uintptr_t)(curpsinfo->pr_dmodel == PR_MODEL_ILP32 ? > > *(uint32_t*)copyin(curpsinfo->pr_argv + 0 * 4, 4) : > > *(uint64_t*)copyin(curpsinfo->pr_argv + 0 * 8, 8))); } > > > > I agree this solution would work if my dtrace script ran before the processes I am interested in, but I don''t have that option. I am trying to run this script amongst long running daemons. Is there any way to accomplish what I am trying to do? I can sleep well if someone confirms it''s not possible. > > --MattAssuming there are no spaces involved, and argv0 is < 80 characters, then: this->arg0 = strtok(curpsinfo->pr_psargs, " "); will work. Otherwise, there''s no great way to do it. Cheers, - jonathan
> > > > All, > > > > > > > > I have the following dtrace script: > > > > > > > > syscall::*fork*:entry > > > > /curpsinfo->pr_argc > 0/ > > > > { > > > > this->argp = (uintptr_t)(curpsinfo->pr_dmodel == PR_MODEL_ILP32 ? > > > > *(uint32_t*)copyin(curpsinfo->pr_argv + 0 * 4, 4) : > > > > *(uint64_t*)copyin(curpsinfo->pr_argv + 0 * 8, 8)); > > > > this->arg1 = copyinstr(this->argp); > > > > printf("first arg: %s\n", this->arg1); } > > > > > > > > I am trying to get the non-truncated first parameter of every process that forks. The above script works, except once in a while I get these messages due to unmapped pages: > > > > > > > > dtrace: error on enabled probe ID 1 (ID 19253: syscall::fork1:entry): > > > > invalid address (0xffbfe000) in action #1 at DIF offset 232 > > > > > > > > What can I do to avoid this issue? I am on Solaris 10 boxes. > > > > > > If your script will run before the processes you''re interested in, you could do: > > > > > > > > > proc:::exec > > > { > > > self->name = args[0]; > > > } > > > > > > proc:::exec-failure > > > { > > > self->name = 0; > > > } > > > > > > proc:::exec-success > > > /self->name != 0/ > > > { > > > proc_execname[curpsinfo->pr_addr] = self->name; > > > self->name = 0; > > > } > > > > > > proc:::create > > > { > > > this->arg0 = proc_arg0[curpsinfo->pr_addr]; > > > this->arg0 = (this->arg0 != NULL)? > > > this->arg0 : strtok(curpsinfo->pr_psargs, " "); > > > proc_arg0[args[0]->pr_addr] = this->arg0; > > > > > > printf("%s", this->arg0); > > > } > > > > > > proc:::exit > > > { > > > proc_arg0[curpsinfo->pr_addr] = 0; } > > > > > > This will give you the pathname passed to exec, not the value of argv[0]. If you want that, replace all of the ''exec*'' probes with: > > > > > > proc:::exec-success > > > { > > > proc_execname[curpsinfo->pr_addr] > > > copyinstr((uintptr_t)(curpsinfo->pr_dmodel == PR_MODEL_ILP32 ? > > > *(uint32_t*)copyin(curpsinfo->pr_argv + 0 * 4, 4) : > > > *(uint64_t*)copyin(curpsinfo->pr_argv + 0 * 8, 8))); } > > > > > > > I agree this solution would work if my dtrace script ran before the processes I am interested in, but I don''t have that option. I am trying to run this script amongst long running daemons. Is there any way to accomplish what I am trying to do? I can sleep well if someone confirms it''s not possible. > > > > --Matt > > Assuming there are no spaces involved, and argv0 is < 80 characters, then: > > this->arg0 = strtok(curpsinfo->pr_psargs, " "); > > will work. Otherwise, there''s no great way to do it. > > Cheers, > - jonathanI just want to say to the rest of the mailing list that I am interested in a "not so great" way to do it. If anyone knows any exotic means of force-faulting those pages, please share. --Matt
On Fri, May 01, 2009 at 02:44:45PM -0400, Zyzik, Matt wrote:> > > > > All, > > > > > > > > > > I have the following dtrace script: > > > > > > > > > > syscall::*fork*:entry > > > > > /curpsinfo->pr_argc > 0/ > > > > > { > > > > > this->argp = (uintptr_t)(curpsinfo->pr_dmodel == PR_MODEL_ILP32 ? > > > > > *(uint32_t*)copyin(curpsinfo->pr_argv + 0 * 4, 4) : > > > > > *(uint64_t*)copyin(curpsinfo->pr_argv + 0 * 8, 8)); > > > > > this->arg1 = copyinstr(this->argp); > > > > > printf("first arg: %s\n", this->arg1); } > > > > > > > > > > I am trying to get the non-truncated first parameter of every process that forks. The above script works, except once in a while I get these messages due to unmapped pages: > > > > > > > > > > dtrace: error on enabled probe ID 1 (ID 19253: syscall::fork1:entry): > > > > > invalid address (0xffbfe000) in action #1 at DIF offset 232 > > > > > > > > > > What can I do to avoid this issue? I am on Solaris 10 boxes. > > > > > > > > If your script will run before the processes you''re interested in, you could do: > > > > > > > > > > > > proc:::exec > > > > { > > > > self->name = args[0]; > > > > } > > > > > > > > proc:::exec-failure > > > > { > > > > self->name = 0; > > > > } > > > > > > > > proc:::exec-success > > > > /self->name != 0/ > > > > { > > > > proc_execname[curpsinfo->pr_addr] = self->name; > > > > self->name = 0; > > > > } > > > > > > > > proc:::create > > > > { > > > > this->arg0 = proc_arg0[curpsinfo->pr_addr]; > > > > this->arg0 = (this->arg0 != NULL)? > > > > this->arg0 : strtok(curpsinfo->pr_psargs, " "); > > > > proc_arg0[args[0]->pr_addr] = this->arg0; > > > > > > > > printf("%s", this->arg0); > > > > } > > > > > > > > proc:::exit > > > > { > > > > proc_arg0[curpsinfo->pr_addr] = 0; } > > > > > > > > This will give you the pathname passed to exec, not the value of argv[0]. If you want that, replace all of the ''exec*'' probes with: > > > > > > > > proc:::exec-success > > > > { > > > > proc_execname[curpsinfo->pr_addr] > > > > copyinstr((uintptr_t)(curpsinfo->pr_dmodel == PR_MODEL_ILP32 ? > > > > *(uint32_t*)copyin(curpsinfo->pr_argv + 0 * 4, 4) : > > > > *(uint64_t*)copyin(curpsinfo->pr_argv + 0 * 8, 8))); } > > > > > > > > > > I agree this solution would work if my dtrace script ran before the processes I am interested in, but I don''t have that option. I am trying to run this script amongst long running daemons. Is there any way to accomplish what I am trying to do? I can sleep well if someone confirms it''s not possible. > > > > > > --Matt > > > > Assuming there are no spaces involved, and argv0 is < 80 characters, then: > > > > this->arg0 = strtok(curpsinfo->pr_psargs, " "); > > > > will work. Otherwise, there''s no great way to do it. > > > > Cheers, > > - jonathan > > I just want to say to the rest of the mailing list that I am interested in a "not so great" way to do it. If > anyone knows any exotic means of force-faulting those pages, please share.proc:::start /!progenyof($pid)/ { stop(); system("pargs %d | grep argv.0.: ; prun %d", pid, pid); }
On Fri, May 01, 2009 at 11:52:22AM -0700, Jonathan Adams wrote:> proc:::start > /!progenyof($pid)/ > { > stop(); > system("pargs %d | grep argv.0.: ; prun %d", pid, pid); > }Nota Bene: You *MUST* have the "!progenyof($pid)" line, or things will go pear-shaped *very* quickly. Cheers, - jonathan
> > > > > > All, > > > > > > > > > > > > I have the following dtrace script: > > > > > > > > > > > > syscall::*fork*:entry > > > > > > /curpsinfo->pr_argc > 0/ > > > > > > { > > > > > > this->argp = (uintptr_t)(curpsinfo->pr_dmodel == PR_MODEL_ILP32 ? > > > > > > *(uint32_t*)copyin(curpsinfo->pr_argv + 0 * 4, 4) : > > > > > > *(uint64_t*)copyin(curpsinfo->pr_argv + 0 * 8, 8)); > > > > > > this->arg1 = copyinstr(this->argp); > > > > > > printf("first arg: %s\n", this->arg1); } > > > > > > > > > > > > I am trying to get the non-truncated first parameter of every process that forks. The above script works, except once in a while I get these messages due to unmapped pages: > > > > > > > > > > > > dtrace: error on enabled probe ID 1 (ID 19253: syscall::fork1:entry): > > > > > > invalid address (0xffbfe000) in action #1 at DIF offset 232 > > > > > > > > > > > > What can I do to avoid this issue? I am on Solaris 10 boxes. > > > > > > > > > > If your script will run before the processes you''re interested in, you could do: > > > > > > > > > > > > > > > proc:::exec > > > > > { > > > > > self->name = args[0]; > > > > > } > > > > > > > > > > proc:::exec-failure > > > > > { > > > > > self->name = 0; > > > > > } > > > > > > > > > > proc:::exec-success > > > > > /self->name != 0/ > > > > > { > > > > > proc_execname[curpsinfo->pr_addr] = self->name; > > > > > self->name = 0; > > > > > } > > > > > > > > > > proc:::create > > > > > { > > > > > this->arg0 = proc_arg0[curpsinfo->pr_addr]; > > > > > this->arg0 = (this->arg0 != NULL)? > > > > > this->arg0 : strtok(curpsinfo->pr_psargs, " "); > > > > > proc_arg0[args[0]->pr_addr] = this->arg0; > > > > > > > > > > printf("%s", this->arg0); > > > > > } > > > > > > > > > > proc:::exit > > > > > { > > > > > proc_arg0[curpsinfo->pr_addr] = 0; } > > > > > > > > > > This will give you the pathname passed to exec, not the value of argv[0]. If you want that, replace all of the ''exec*'' probes with: > > > > > > > > > > proc:::exec-success > > > > > { > > > > > proc_execname[curpsinfo->pr_addr] > > > > > copyinstr((uintptr_t)(curpsinfo->pr_dmodel == PR_MODEL_ILP32 ? > > > > > *(uint32_t*)copyin(curpsinfo->pr_argv + 0 * 4, 4) : > > > > > *(uint64_t*)copyin(curpsinfo->pr_argv + 0 * 8, 8))); } > > > > > > > > > > > > > I agree this solution would work if my dtrace script ran before the processes I am interested in, but I don''t have that option. I am trying to run this script amongst long running daemons. Is there any way to accomplish what I am trying to do? I can sleep well if someone confirms it''s not possible. > > > > > > > > --Matt > > > > > > Assuming there are no spaces involved, and argv0 is < 80 characters, then: > > > > > > this->arg0 = strtok(curpsinfo->pr_psargs, " "); > > > > > > will work. Otherwise, there''s no great way to do it. > > > > > > Cheers, > > > - jonathan > > > > I just want to say to the rest of the mailing list that I am > > interested in a "not so great" way to do it. If anyone knows any exotic means of force-faulting those pages, please share. > > proc:::start > /!progenyof($pid)/ > { > stop(); > system("pargs %d | grep argv.0.: ; prun %d", pid, pid); }I should also mention that I plan to aggregate on the values, like this: "@agg[this->arg1] = count();"; and print with the "tick-5s" probe. In that case, the above-mentioned method won''t be useful as I cannot collect the output from the system(..) function. --Matt
Zyzik, Matt wrote:>>>>>>> All, >>>>>>> >>>>>>> I have the following dtrace script: >>>>>>> >>>>>>> syscall::*fork*:entry >>>>>>> /curpsinfo->pr_argc > 0/ >>>>>>> { >>>>>>> this->argp = (uintptr_t)(curpsinfo->pr_dmodel == PR_MODEL_ILP32 ? >>>>>>> *(uint32_t*)copyin(curpsinfo->pr_argv + 0 * 4, 4) : >>>>>>> *(uint64_t*)copyin(curpsinfo->pr_argv + 0 * 8, 8)); >>>>>>> this->arg1 = copyinstr(this->argp); >>>>>>> printf("first arg: %s\n", this->arg1); } >>>>>>> >>>>>>> I am trying to get the non-truncated first parameter of every process that forks. The above script works, except once in a while I get these messages due to unmapped pages: >>>>>>> >>>>>>> dtrace: error on enabled probe ID 1 (ID 19253: syscall::fork1:entry): >>>>>>> invalid address (0xffbfe000) in action #1 at DIF offset 232 >>>>>>> >>>>>>> What can I do to avoid this issue? I am on Solaris 10 boxes. >>>>>>> >>>>>> If your script will run before the processes you''re interested in, you could do: >>>>>> >>>>>> >>>>>> proc:::exec >>>>>> { >>>>>> self->name = args[0]; >>>>>> } >>>>>> >>>>>> proc:::exec-failure >>>>>> { >>>>>> self->name = 0; >>>>>> } >>>>>> >>>>>> proc:::exec-success >>>>>> /self->name != 0/ >>>>>> { >>>>>> proc_execname[curpsinfo->pr_addr] = self->name; >>>>>> self->name = 0; >>>>>> } >>>>>> >>>>>> proc:::create >>>>>> { >>>>>> this->arg0 = proc_arg0[curpsinfo->pr_addr]; >>>>>> this->arg0 = (this->arg0 != NULL)? >>>>>> this->arg0 : strtok(curpsinfo->pr_psargs, " "); >>>>>> proc_arg0[args[0]->pr_addr] = this->arg0; >>>>>> >>>>>> printf("%s", this->arg0); >>>>>> } >>>>>> >>>>>> proc:::exit >>>>>> { >>>>>> proc_arg0[curpsinfo->pr_addr] = 0; } >>>>>> >>>>>> This will give you the pathname passed to exec, not the value of argv[0]. If you want that, replace all of the ''exec*'' probes with: >>>>>> >>>>>> proc:::exec-success >>>>>> { >>>>>> proc_execname[curpsinfo->pr_addr] >>>>>> copyinstr((uintptr_t)(curpsinfo->pr_dmodel == PR_MODEL_ILP32 ? >>>>>> *(uint32_t*)copyin(curpsinfo->pr_argv + 0 * 4, 4) : >>>>>> *(uint64_t*)copyin(curpsinfo->pr_argv + 0 * 8, 8))); } >>>>>> >>>>>> >>>>> I agree this solution would work if my dtrace script ran before the processes I am interested in, but I don''t have that option. I am trying to run this script amongst long running daemons. Is there any way to accomplish what I am trying to do? I can sleep well if someone confirms it''s not possible. >>>>> >>>>> --Matt >>>>> >>>> Assuming there are no spaces involved, and argv0 is < 80 characters, then: >>>> >>>> this->arg0 = strtok(curpsinfo->pr_psargs, " "); >>>> >>>> will work. Otherwise, there''s no great way to do it. >>>> >>>> Cheers, >>>> - jonathan >>>> >>> I just want to say to the rest of the mailing list that I am >>> interested in a "not so great" way to do it. If anyone knows any exotic means of force-faulting those pages, please share. >>> >> proc:::start >> /!progenyof($pid)/ >> { >> stop(); >> system("pargs %d | grep argv.0.: ; prun %d", pid, pid); } >> > > I should also mention that I plan to aggregate on the values, like this: "@agg[this->arg1] = count();"; and > print with the "tick-5s" probe. In that case, the above-mentioned method won''t be useful as I cannot collect > the output from the system(..) function. >What if you did something like this: system("dd if=/proc/%d/as of=/dev/null bs=1 count=%d skip=%d", pid, object_size, object_addr); Would it fault in the missing pages for you? If so, you could safely copyin() afterward. Ryan
On Fri, May 01, 2009 at 09:39:46PM +0200, Ryan Johnson wrote:> Zyzik, Matt wrote: > >>>>>>>All, > >>>>>>> > >>>>>>>I have the following dtrace script: > >>>>>>> > >>>>>>>syscall::*fork*:entry > >>>>>>>/curpsinfo->pr_argc > 0/ > >>>>>>>{ > >>>>>>> this->argp = (uintptr_t)(curpsinfo->pr_dmodel == PR_MODEL_ILP32 ? > >>>>>>> *(uint32_t*)copyin(curpsinfo->pr_argv + 0 * 4, 4) : > >>>>>>> *(uint64_t*)copyin(curpsinfo->pr_argv + 0 * 8, 8)); > >>>>>>> this->arg1 = copyinstr(this->argp); > >>>>>>> printf("first arg: %s\n", this->arg1); } > >>>>>>> > > > What if you did something like this: > > system("dd if=/proc/%d/as of=/dev/null bs=1 count=%d skip=%d", pid, > object_size, object_addr); > > Would it fault in the missing pages for you? If so, you could safely > copyin() afterward.That could work; do: syscall::*fork:entry { stop(); system( "dd if=/proc/%d/as of=/dev/null bs=4096 skip=%d 2>/dev/null; " "prun %d", pid, (uintptr_t)curpsinfo->pr_argv / 4096, pid); } proc:::create { /* do your copyinstr here */ } This takes advantage of the fact that argv[] is at a lower address than the argument strings it points to, so they will all be pulled in (dd will stop at the guard page at the end of the main stack). This may not work if your processes change argv[0] to point at some unrelated string. The entry probe will stop the process, have the dtrace process fault in the pages, then start the process running; when you get to proc:::create, they''ll be available for reading. Cheers, - jonathan
> > What if you did something like this: > > > > system("dd if=/proc/%d/as of=/dev/null bs=1 count=%d skip=%d", pid, > > object_size, object_addr); > > > > Would it fault in the missing pages for you? If so, you could safely > > copyin() afterward. > > That could work; do: > > syscall::*fork:entry > { > stop(); > system( > "dd if=/proc/%d/as of=/dev/null bs=4096 skip=%d 2>/dev/null; " > "prun %d", > pid, (uintptr_t)curpsinfo->pr_argv / 4096, pid); } > > proc:::create > { > /* do your copyinstr here */ > } > > This takes advantage of the fact that argv[] is at a lower address than the argument strings it points to, so they will all be pulled in (dd will stop at the guard page at the end of the main stack). This may not work if your processes change argv[0] to point at some unrelated string. > > The entry probe will stop the process, have the dtrace process fault in the pages, then start the process running; when you get to proc:::create, they''ll be available for reading. > > Cheers, > - jonathanThis is exactly the kind of thing I was looking for. And it works. Thanks. --Matt Zyzik