62

straceOS XにはLinuxがありませんが、Linuxのdtrace方がはるかに優れていると思われます。

ただし、個々のコマンドで単純なトレースを実行する機能がありません。たとえば、Linuxでは、strace -f gcc hello.cすべてのシステムコールをキャプチャするように記述できます。これにより、コンパイラがプログラムをコンパイルするために必要なすべてのファイル名のリストが表示されます(優れたメモ化スクリプトはこのトリックに基づいて構築されています)

Macにメモ化を移植したいので、なんらかのが必要ですstrace。私が実際に必要としているのは、gcc読み取りと書き込みを行うファイルのリストなので、必要なのはもっとですtruss。案の定dtruss -f gcc hello.c、ある程度同じ機能を取得できますが、コンパイラはルート権限で実行されます。これは明らかに望ましくありません(セキュリティ上の大きなリスクは別として、a.outファイルがルートによって所有されているという問題があります:-)

次に試してみdtruss -f sudo -u myusername gcc hello.cましたが、これは少し違和感があり、とにかく機能しません(a.outこの時点ではファイルがまったく取得されないので、理由はわかりません)

その長い話はすべて、私の最初の質問を動機付けようとしています。Linuxの場合と同じように、通常のユーザー権限でコマンドを実行するにはどうすればよいですか。dtracestrace

編集:これを行う方法を疑問に思っているのは私だけではないようです:質問#1204256は私のものとほとんど同じです(そして同じ次善のsudo答えがあります:-)

4

8 に答える 8

53

最も簡単な方法は、sudo を使用することです。

sudo dtruss -f sudo -u $USER whoami

他の解決策は、最初にデバッガーを実行し、新しい特定のプロセスを監視することです。例えば

sudo dtruss -fn whoami

次に、別のターミナルで次を実行します。

whoami

そのような単純な。

マニュアルで見つけることができるよりトリッキーな引数:man dtruss


または、Mac などで実行中のユーザー プロセスに dtruss をアタッチすることもできます。

sudo dtruss -fp PID

または、strace を使用して Linux/Unix で同様の操作を行います。

sudo strace -fp PID

別のハックなトリックは、コマンドを実行し、その直後にプロセスにアタッチすることです。ここではいくつかの例を示します。

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このトリックは、デバッガーがプロセスにアタッチされるまで時間がかかるため、コマンド ラインが短い場合には機能しません。

  • コマンドを 2 か所に入力する必要があります。

  • プロセスをバックグラウンドで実行することを無視できます。&すでに実行している場合は、

  • デバッグが終了したら、バックグラウンド プロセスを手動で強制終了する必要があります (例: killall -v tail) 。

于 2012-07-29T02:46:51.137 に答える
5

あなたの質問に対する答えではありませんが、知っておくべきことがあります。OpenSolaris はこの問題を (部分的に) 「権限」で解決しました -このページを参照してください。OpenSolaris でも、追加の特権がなければ、ユーザーが自分のプロセスを dtruss することを許可することはできません。その理由は、dtrace の動作方法にあります。カーネルでプローブを有効にします。したがって、非特権ユーザーがカーネルをプローブできるようにするということは、ユーザーが多くの不要なことを実行できることを意味します。たとえば、キーボード ドライバーでプローブを有効にして、他のユーザーのパスワードを盗聴するなどです。

于 2011-01-15T12:16:03.733 に答える
5

dtruss を strace のように非侵襲的にできるかどうかはわかりません。

「sudo [to root] dtruss sudo [back to nonroot] cmd」のバリアントは、いくつかの簡単なテストでうまく機能するようです。

sudo dtruss -f su -l `whoami` cd `pwd` && cmd....

外側の sudo は当然なので、dtruss は root として実行されます。

内側の su が戻ってきて、-l を使用すると環境が適切に再作成されます。この時点で、開始した場所に cd で戻る必要があります。

環境をそのユーザーが通常取得するものにしたい場合は、「sudo -u user」よりも「su -l user」の方が優れていると思います。ただし、それがログイン環境になります。代わりに、2 つのユーザー変更によって環境を継承させる良い方法があるかどうかはわかりません。

あなたの質問では、醜さ以外の「sudo dtruss sudo」回避策についての追加の不満は、「今回は a.out ファイルがまったく取得されないため、理由がわからない」というものでした。理由もわかりませんが、私の小さなテスト スクリプトでは、「sudo dtruss sudo」バリアントもテスト出力ファイルへの書き込みに失敗し、上記の「sudo dtruss su」バリアントは出力ファイルを作成しました。

于 2011-01-14T00:09:17.600 に答える
3

OS X は、必要な strace のすべての機能を複製するために dtrace を使用することをサポートしていないようです。ただし、適切なシステムコールのラッパーを作成することをお勧めします。DYLD_INSERT_LIBRARIESは、少しハックしたい環境変数のようですLD_PRELOADこれは基本的に Linuxの場合と同じです。

ライブラリ関数のオーバーライドを行うより簡単な方法は、DY​​LD_INSERT_LIBRARIES 環境変数 (Linux の LD_PRELOAD に類似) を使用することです。概念は単純です。ロード時に、動的リンカー (dyld) は、実行可能ファイルがロードする必要があるライブラリよりも前に、DYLD_INSERT_LIBRARIES で指定された動的ライブラリをロードします。ライブラリ関数内の関数と同じ名前を付けると、元の関数への呼び出しが上書きされます。

元の関数も読み込まれ、dlsym(RTLD_NEXT, “function_name”); を使用して取得できます。関数。これにより、既存のライブラリ関数を簡単にラップできます。

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
于 2014-08-28T14:00:00.300 に答える
1

dtrace を使用する dtruss には su 権限が必要なようです。

ただし、代わりに探していたコマンドだと思います

dtruss -f sudo -u myusername gcc hello.c

sudo dtruss -f gcc hello.c

パスワードを入力すると、dtruss が dtrace を実行して sudo 特権を実行し、トレースと a.out ファイルを取得します。

申し訳ありませんが、これ以上お役に立てませんでした。

于 2011-01-12T08:14:56.243 に答える