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 是完全同步的,并且会一直阻塞,直到您的消息通过串行端口传输或通过火线提交。它也是线程安全的。在火线的情况下,kprintf 输出也被缓冲,所以如果你输出很多消息,这也会填满并导致截断。该fwkpfv命令允许您使用参数指定缓冲区大小--buffer,因此您可以抵消它。kprintf 同步的缺点是它可以通过大量消息显着降低系统速度。

于 2016-03-31T11:41:10.807 回答