我在我的内核可加载模块中使用printk来记录系统调用的参数。对于每个系统调用,都会使用几个printks来打印变量,它们以"\t“作为分隔符出现。为了将内核日志缓冲区中的数据重定向到system /var/ log /messages之外的其他文件,我使用"klogd -f“绕过syslog接口。获取的日志数据是每个系统调用一行。然而,在对数据进行分析后,我发现存在两个问题。
问题1:数据可能丢失。
问题2:一个系统调用的数据与属于另一个系统调用的数据混合在一起,可能在中间。
问题1:内核日志缓冲区溢出是否会导致数据丢失,从而覆盖缓冲区中最旧的日志?如果是这样,如何克服它?我计划增加内核日志缓冲区的大小。你认为它合适吗?多大的尺寸最好?
问题2:系统调用能否抢占另一个系统调用?或者在某些情况下,一个系统调用可能会调用另一个系统调用,并且除非被调用的系统调用完成,否则无法完成?这就是数据相互混淆的原因吗?
问题3: printk是原子的吗?如果不是,如何使printk原子化?添加锁以使其不可中断?
发布于 2012-10-04 04:28:55
如果您只想转储某个程序正在进行的所有系统调用(带参数),可以对strace命令执行check out命令。
问题1:某种程度上。内核日志缓冲区被实现为环形缓冲区。如果环形缓冲区是128K,并且内核自启动以来总共写入了129K的数据,那么第一个1K将被最新的数据覆盖。您可以通过内核引导参数log_buf_len或在编译时在内核的.config文件中增加此缓冲区的大小。您还可以使用dmesg更改环形缓冲区的大小,方法是运行dmesg -s524288,该命令会将其设置为512KiB。您必须根据您输出的数据量来确定最佳大小。
问题2:一个系统调用可能会抢占另一个系统调用,在内核中有很多其他抢占的情况--中断服务例程就是一个主要的例子。另外,如果你在一个多核系统上,你可以有多个活动的内核线程。
问题3:我相信printk试图锁定内核的环形缓冲区。不过,这有点复杂,因为您可以在恐慌状态下调用printk。
https://stackoverflow.com/questions/12716154
复制相似问题