问题
I'd like to have dtrace script that print new processes' cmdline and their matching parent name. i.e. : if I ran /Users/bla/myexec arg1 arg2 arg3 from bash I will get something like :
parent is bash process is --> /Users/bla/myexec arg1 arg2 arg3
After searching here and here I came up with the following solution :
#!/usr/sbin/dtrace -s
proc:::exec
{
self->pexecname = execname;
}
proc:::exec-success
/ self->pexecname != 0 /
{
this->isx64=(curproc->p_flag & P_LP64)!=0;
#define SELECT_64_86(x64, x86) (this->isx64 ? (x64) : (x86))
#define GET_POINTER(base, offset) (user_addr_t)SELECT_64_86(*(uint64_t *)((base)+sizeof(uint64_t)*(offset)), *(uint32_t *)((base)+sizeof(uint32_t)*(offset)))
this->ptrsize=SELECT_64_86(sizeof(uint64_t),sizeof(uint32_t));
this->argc=curproc->p_argc;
this->isClean=SELECT_64_86(1, (curproc->p_dtrace_argv==(uregs[R_SP]+sizeof(uint32_t)+sizeof(uint32_t))));
this->argv=(uint64_t)copyin(curproc->p_dtrace_argv,this->ptrsize*this->argc);
/* printf("%s with args:%d (%p, %p)\n",execname, this->argc, curproc->pdtraceargv, uregs\[R_SP\]); */
printf("parent is %s process is --> ", execname);
printf("%s ", (0 < this->argc && this->isClean) ? copyinstr(GET_POINTER(this->argv,0)) : "");
printf("%s ", (1 < this->argc && this->isClean) ? copyinstr(GET_POINTER(this->argv,1)) : "");
printf("%s ", (2 < this->argc && this->isClean) ? copyinstr(GET_POINTER(this->argv,2)) : "");
printf("%s ", (3 < this->argc && this->isClean) ? copyinstr(GET_POINTER(this->argv,3)) : "");
printf("%s ", (4 < this->argc && this->isClean) ? copyinstr(GET_POINTER(this->argv,4)) : "");
printf("%s ", (5 < this->argc && this->isClean) ? copyinstr(GET_POINTER(this->argv,5)) : "");
printf("%s ", (6 < this->argc && this->isClean) ? copyinstr(GET_POINTER(this->argv,6)) : "");
printf("%s ", (7 < this->argc && this->isClean) ? copyinstr(GET_POINTER(this->argv,7)) : "");
printf("%s ", (8 < this->argc && this->isClean) ? copyinstr(GET_POINTER(this->argv,8)) : "");
printf("%s ", (9 < this->argc && this->isClean) ? copyinstr(GET_POINTER(this->argv,9)) : "");
printf("\n");
#undef GET_POINTER
#undef SELECT_64_86
}
However, while running the script, it seems that for some probes there are uninitialized/corrupted variables.
Here's an output example of the following bash command sudo dtrace -C -s ./procargs.d
. It can be seen, that probe proc:mach_kernel:__mac_execve:exec-success
have uninitialized value in curproc->p_dtrace_argv
:
dtrace: script '/Users/zkabeli/procargs3.d' matched 4 probes
CPU ID FUNCTION:NAME
4 1212 posix_spawn:exec-success parent is Calendar process is --> /Applications/Calendar.app/Contents/MacOS/Calendar
6 1208 __mac_execve:exec-success parent is SFLIconTool process is --> /System/Library/Frameworks/CoreServices.framework/Frameworks/OSServices.framework/Versions/A/Support/SFLIconTool com.apple.recentitems RecentApplications
dtrace: error on enabled probe ID 4 (ID 1208: proc:mach_kernel:__mac_execve:exec-success): invalid address (0x7fff59e82e08) in action #5 at DIF offset 320
2 1212 posix_spawn:exec-success parent is kcm process is --> /System/Library/PrivateFrameworks/Heimdal.framework/Helpers/kcm --launchd
Perhaps you can tell me what's wrong with my script?
来源:https://stackoverflow.com/questions/35794993/dtrace-invalid-address-error-when-extracting-process-command-line