【问题标题】:Failed to execute script.sh: unknown error执行 script.sh 失败:未知错误
【发布时间】:2017-06-24 23:23:47
【问题描述】:

我想使用 DTrace 来查看“我的 shell 脚本进行了哪些系统调用”。

我做了一个非常简单的shell脚本shell.sh,并赋予它执行权限:

#!/bin/bash
grep 1 <<< 123

cd'd 进入了它的目录,并运行了这个简单的 DTrace 脚本:

sudo dtrace -n 'syscall:::entry
/pid == $target/
{
    @[probefunc] = count();
}' -c ./trace-me.sh

我得到这个错误输出:

dtrace: failed to execute ./trace-me.sh: unknown error

这里发生了什么?我已经运行csrutil enable --without dtrace。如果我删除 -c arg(并将 $target 替换为 pid),DTrace 脚本运行良好。

这只是另一个 Mac 问题吗?我正在运行 macOS Sierra 10.12.5 Beta。

【问题讨论】:

标签: macos bsd dtrace


【解决方案1】:

感谢@l'L'l 链接到的tip:我能够解决这个问题。

你需要两个 shell。

在外壳 A(我们将要检查的外壳)中:

# copy this shell's PID to clipboard (93827 for this example)
echo $$ | pbcopy

在 shell B(将运行 DTrace 的 shell)中,开始跟踪该 PID:

sudo dtrace -n 'syscall:::entry
/progenyof($1) && pid != $1/
{
    @[probefunc] = count();
}' 93827

我们使用progenyof() 来确保我们跟踪shell 的子进程。我添加了&amp;&amp; pid != $1,因为出于某种原因progenyof(x) 似乎包含x

现在回到 shell A,运行一些你想检查的代码:

grep 1 <<< 123

我们在 shell B 中的 DTrace 程序将成功捕获在 shell A 中启动的子进程。

有一点噪音需要筛选。也许shell会启动各种孩子。不知道如何更有选择性。


看看 dtruss 如何实现 -f(“跟随孩子分叉”)很有教育意义...

less "$(which dtruss)"

相关子句是那些使用OPT_follow &amp;&amp; 过滤器(表示-f 已启用)或self-&gt;child 变量(表示该线程是-p PID 中指定进程的子进程)的子句。

知道ppid 是一个为您提供父PID 的内置变量也很有用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-11-19
    • 1970-01-01
    • 2020-06-01
    • 2021-06-03
    • 2020-01-12
    • 2013-07-21
    • 1970-01-01
    相关资源
    最近更新 更多