OS X缺少linux的strace
,但它有dtrace
,应该会好得多。
但是,我错过了对单个命令进行简单跟踪的功能。例如,在linux上我可以编写strace -f gcc hello.c
来限制所有系统调用,这为我提供了编译程序所需的文件名 all 的列表(优秀的memoize }脚本建立在这个技巧上)
我想在mac上移植memoize,所以我需要某种strace
。我真正需要的是文件列表gcc
读取和写入,所以我需要的更多是truss
。我当然可以说dtruss -f gcc hello.c
并获得一些相同的功能,但随后编译器运行root权限,这显然是不可取的(除了大量的安全风险,一个问题是a.out
文件现在由root拥有: - )
然后我尝试了dtruss -f sudo -u myusername gcc hello.c
,但这感觉有点不对,反正无法工作(这时我得不到a.out
文件,不知道为什么)
所有长篇故事试图激发我原来的问题:如何让dtrace
以正常的用户权限运行我的命令,就像在linux中strace
一样?
编辑:似乎我不是唯一一个想知道如何做到这一点的人:问题#1204256与我的几乎相同(并且具有相同的次优sudo答案:-)
答案 0 :(得分:43)
最简单的方法是使用sudo:
sudo dtruss -f sudo -u $USER whoami
其他解决方案是首先运行调试器并监视新的特定进程。 E.g。
sudo dtruss -fn whoami
然后在另一个终端中运行:
whoami
这很简单。
您可以在手册中找到更棘手的参数:man dtruss
或者,您可以将dtruss附加到正在运行的用户进程,例如在Mac上:
sudo dtruss -fp PID
在Linux / Unix上使用strace 或类似的东西:
sudo strace -fp PID
另一个hacky技巧可能是执行命令,然后在附加到进程后立即执行。以下是一些例子:
sudo true; (./Pages &); sudo dtruss -fp `pgrep -n -x Pages`
sudo true; (sleep 1 &); sudo dtruss -fp `pgrep -n -x sleep`
sudo true; (tail -f /var/log/system.log &); sudo dtruss -fp `pgrep -n -x tail`
注意:
第一个sudo只是在第一次运行时缓存密码,
这个技巧不适用于像ls, date
这样的快速命令行,因为它需要一些时间,直到调试器将附加到进程,
您必须在两个地方输入命令,
您可以忽略&
将流程运行到后台,如果它已经这样做了,
完成调试后,您必须手动终止后台进程(例如killall -v tail
)
答案 1 :(得分:8)
-n
的{{1}}参数将导致dtruss等待并检查与dtruss
的参数匹配的进程。 -n
选项仍然可以跟踪从-f
匹配的进程分叉的进程。
所有这些意味着如果你想要一个进程(为了争论,让我们说它是-n
)作为非特权用户运行,请按照以下步骤操作:
whoami
dtruss -fn whoami
这个答案重复了@ kenorb回复的后半部分,但它应该是一流的答案。
答案 2 :(得分:5)
我不知道你是否可以像strace一样无所畏惧。
“sudo [to root] dtruss sudo [back to nonroot] cmd”的一个变体似乎在我的一些快速测试中效果更好:
sudo dtruss -f su -l `whoami` cd `pwd` && cmd....
外部sudo当然是以root身份运行。
内部su回到我身边,使用-l它可以正确地重新创建环境,此时我们需要回到我们开始的地方。
如果您希望环境成为用户通常获得的环境,我认为“su -l user”优于“sudo -u user”。那将是他们的登录环境;我不知道是否有一种让环境通过两个用户更改继承的好方法。
在你的问题中,除了丑陋之外,你还有一个关于“sudo dtruss sudo”解决方法的另一个抱怨是“我现在没有得到任何a.out文件,不知道为什么”。我不知道为什么,但在我的小测试脚本中,“sudo dtruss sudo”变体也无法写入测试输出文件,上面的“sudo dtruss su”变体确实创建了输出文件。
答案 3 :(得分:5)
不是你问题的答案,而是要知道的事情。 OpenSolaris使用“权限”(部分)解决了这个问题 - 请参阅this page。即使在OpenSolaris中,也不可能允许用户在没有任何额外权限的情况下使用自己的进程。 原因是dtrace的工作方式 - 它启用内核中的探测器。因此,允许非特权用户探测内核意味着用户可以做很多不需要的事情,例如通过在键盘驱动程序中启用探针来嗅探其他用户的密码!
答案 4 :(得分:3)
似乎OS X不支持使用dtrace复制所需的strace的所有功能。但是,我建议尝试围绕合适的系统调用创建一个包装器。看起来DYLD_INSERT_LIBRARIES是您想要破解的环境变量。这与Linux的LD_PRELOAD
基本相同。
更容易实现库函数覆盖的方法是使用 DYLD_INSERT_LIBRARIES环境变量(类似于LD_PRELOAD on Linux的)。概念很简单:在加载时动态链接器(dyld) 将加载DYLD_INSERT_LIBRARIES中指定的任何动态库 在可执行文件要加载的任何库之前。通过命名一个函数 与库函数中的一个相同,它将覆盖任何调用 原来。
原始函数也被加载,可以使用 dlsym(RTLD_NEXT,“function_name”);功能。这允许简单 包装现有库函数的方法。
根据example的Tom Robinson,您可能还需要设置DYLD_FORCE_FLAT_NAMESPACE=1
。
仅覆盖lib_overrides.c
的原始示例(fopen
)的副本:
#include <stdio.h>
#include <unistd.h>
#include <dlfcn.h>
// for caching the original fopen implementation
FILE * (*original_fopen) (const char *, const char *) = NULL;
// our fopen override implmentation
FILE * fopen(const char * filename, const char * mode)
{
// if we haven’t already, retrieve the original fopen implementation
if (!original_fopen)
original_fopen = dlsym(RTLD_NEXT, "fopen");
// do our own processing; in this case just print the parameters
printf("== fopen: {%s,%s} ==\n", filename, mode);
// call the original fopen with the same arugments
FILE* f = original_fopen(filename, mode);
// return the result
return f;
}
用法:
$ gcc -Wall -o lib_overrides.dylib -dynamiclib lib_overrides.c
$ DYLD_FORCE_FLAT_NAMESPACE=1 DYLD_INSERT_LIBRARIES=lib_overrides.dylib command-to-test
答案 5 :(得分:2)
免责声明:这是来自@ kenorb&#39; s answer。它有一些优点:PID比execname更具体。我们可以在开始之前使一个短暂的进程等待DTrace。
这有点竞争条件,但是......
我们想要跟踪cat /etc/hosts
:
sudo true && \
(sleep 1; cat /etc/hosts) &; \
sudo dtrace -n 'syscall:::entry /pid == $1/ {@[probefunc] = count();}' $!; \
kill $!
我们使用sudo true
确保在开始运行任何时间敏感之前清除sudo的密码提示。
我们开始后台流程(&#34;等待1秒,然后做一些有趣的事情&#34;)。同时,我们启动DTrace。我们已将后台进程的PID捕获到$!
,因此我们可以将其作为arg传递给DTrace。
关闭DTrace后kill $!
运行。对于我们的cat
示例(进程自行关闭),它不是必需的,但它可以帮助我们结束长期运行的后台进程,例如ping
。将-p $!
传递给DTrace是执行此操作的首选方法,但在macOS上显然需要代码签名的可执行文件。
你可以做的另一件事是在一个单独的shell中运行命令,然后窥探那个shell。查看我的answer。
答案 6 :(得分:1)
我不知道如何以普通用户的身份运行你想要的东西,因为似乎dtruss使用dtrace需要su权限。
但是,我相信你要找的命令而不是
dtruss -f sudo -u myusername gcc hello.c
是
sudo dtruss -f gcc hello.c
输入密码后,dtruss将运行dtrace将sudo权限,您将获得跟踪以及a.out文件。
抱歉,我无法提供进一步的帮助。