2

次のように、kext を使用して OS X でシステム コールをログに記録しています。

int hook_read(struct proc *p, struct read_args *u, user_ssize_t *r) {
    /* get som params here... */
    printf("[IDEN] SYS_read called, %s, %d, %d, %d.\n", params);
    return read(p, u, r); 
}

これは に記録されsystem.logます。現在の問題は、printf負荷が高い場合 (多くのシステム コールが呼び出される場合)、出力のsystem.log形式が正しくないことが多いこと ID]SYS_readEN] callparam, 123, ed 123, 123です。たとえば、. 文字列はスクランブルされています。kprintfシリアル ポートに出力するを使用すると、不正な形式のログが発生することはありません。

この動作を引き起こしているアイデアは大歓迎です!

4

1 に答える 1

1

printf/IOLog はメッセージをユーザー空間に送信するためにバッファを使用し、そこでメッセージはシステム ログに記録されます。大量のメッセージを出力すると、ロギング デーモンがバッファをクリアする前にこのバッファがいっぱいになる可能性があり、メッセージが切り詰められて互いに衝突し始めます。(printf/IOLog は、メッセージがバッファに送信されるとすぐに戻り、デーモンが受信するのを待ちません。)

さらに、カーネルの printf/IOLog が何らかの方法でスレッドセーフであるかどうかはわかりません。そのため、複数のスレッドから同時に呼び出すと競合状態が発生する可能性もあります。念のためにソースを確認する必要があります。

kprintf は完全に同期しており、メッセージがシリアル ポートで送信されるか、firewire 経由で送信されるまでブロックされます。また、スレッドセーフです。firewire の場合、kprintf 出力もバッファリングされるため、大量のメッセージを出力すると、これもいっぱいになり、切り捨てが発生する可能性があります。ただし、このfwkpfvコマンドでは、引数を使用してバッファー サイズを指定--bufferできるため、それを打ち消すことができます。kprintf が同期であることの欠点は、大量のメッセージでシステムの速度が大幅に低下する可能性があることです。

于 2016-03-31T11:41:10.807 に答える