什么会使 printk 不立即出现在 dmesg 中?
What would make a printk not show up immediately in dmesg?
我正在 Ubuntu 4.14.12 上制作一个 Linux 内核模块。
我对 printk() 的理解是,它保证在下一行代码 运行 之前立即输出到控制台,而不是将其输出放在最终在某个时间刷新的缓冲区.这是正确的吗?
我在多次 printk 调用之后发生了数百行崩溃,这些调用的输出没有出现在使用 -wH 命令的 dmesg 中,也没有出现在通过 tee 发送到我重新启动后读取的文件的 dmesg 中。
将 printk 发送到控制台的时间与它在 dmesg 中显示的时间之间是否存在延迟,这会使我的系统在我看到输出之前冻结?还是有其他事情发生?
dmesg 在修复有问题的代码行后显示有问题的 printks。控制台日志级别设置为高于相关 printks 的控制台日志级别。
您的模块调用 printk(...)
和控制台上显示的输出之间有很多层。
My understanding of printk() is that it is guaranteed to output to console immediately before the next line of code is run, rather than having its output placed on a buffer that is eventually flushed at some point. Is this correct?
不,这是不正确的。 printk()
实现中没有 "console",也不应该有。总会有一个缓冲区,很多层的缓冲区。 1705 in printk.c 行回答了您的问题。 printk_emit()
函数使用静态分配的缓冲区 static char textbuf[LOG_LINE_MAX];
并在其上调用 vscnprintf(textbuf, sizeof(textbuf), ...)
来解析参数。所以它使用了一个缓冲区。我不认为不使用内部缓冲区就可以编写 printf
函数,至少它更难。 __log_buf
变量是一个静态分配的缓冲区,一个字符数组,它是内核日志缓冲区。
Is there lag between the time a printk is sent to console and it shows up in dmesg that would allow my system to freeze up before I saw the output?
是吗?总是有滞后。我不知道如何定义 "lag"(一毫秒?一秒?一纳秒?)但是 printk
函数后面的汇编指令必须执行,然后所有层直到它们被放置在__log_buf static variable. Then dmesg
which awaits on read()
syscall is woken up I guess somewhere inside console_unlock. After the wakeup dmesg
will finally call devkmsg_read() 函数将 return 缓冲区。然后 dmesg()
将在接收到数据后在 stdout 上调用 write()
系统调用。然后 write()
内核系统调用将尝试在您的屏幕上写入一些内容 - 因此数据必须一直通过控制台驱动程序、显示驱动程序和图形驱动程序。总是有滞后。但它应该是最小的。
dmesg shows the printks in question after fixing the problematic line of code
这只是说 dmesg
没有从内核日志中获取输出。可能还有其他事情正在发生。最简单的是 dmesg
进程没有获得 cpu 时间,在读取系统日志时被阻塞,您的模块在内部执行时禁用了 irq,等等。
我也有类似情况。当我在 msg 末尾添加 '\n' 时很好。
我正在 Ubuntu 4.14.12 上制作一个 Linux 内核模块。
我对 printk() 的理解是,它保证在下一行代码 运行 之前立即输出到控制台,而不是将其输出放在最终在某个时间刷新的缓冲区.这是正确的吗?
我在多次 printk 调用之后发生了数百行崩溃,这些调用的输出没有出现在使用 -wH 命令的 dmesg 中,也没有出现在通过 tee 发送到我重新启动后读取的文件的 dmesg 中。
将 printk 发送到控制台的时间与它在 dmesg 中显示的时间之间是否存在延迟,这会使我的系统在我看到输出之前冻结?还是有其他事情发生?
dmesg 在修复有问题的代码行后显示有问题的 printks。控制台日志级别设置为高于相关 printks 的控制台日志级别。
您的模块调用 printk(...)
和控制台上显示的输出之间有很多层。
My understanding of printk() is that it is guaranteed to output to console immediately before the next line of code is run, rather than having its output placed on a buffer that is eventually flushed at some point. Is this correct?
不,这是不正确的。 printk()
实现中没有 "console",也不应该有。总会有一个缓冲区,很多层的缓冲区。 1705 in printk.c 行回答了您的问题。 printk_emit()
函数使用静态分配的缓冲区 static char textbuf[LOG_LINE_MAX];
并在其上调用 vscnprintf(textbuf, sizeof(textbuf), ...)
来解析参数。所以它使用了一个缓冲区。我不认为不使用内部缓冲区就可以编写 printf
函数,至少它更难。 __log_buf
变量是一个静态分配的缓冲区,一个字符数组,它是内核日志缓冲区。
Is there lag between the time a printk is sent to console and it shows up in dmesg that would allow my system to freeze up before I saw the output?
是吗?总是有滞后。我不知道如何定义 "lag"(一毫秒?一秒?一纳秒?)但是 printk
函数后面的汇编指令必须执行,然后所有层直到它们被放置在__log_buf static variable. Then dmesg
which awaits on read()
syscall is woken up I guess somewhere inside console_unlock. After the wakeup dmesg
will finally call devkmsg_read() 函数将 return 缓冲区。然后 dmesg()
将在接收到数据后在 stdout 上调用 write()
系统调用。然后 write()
内核系统调用将尝试在您的屏幕上写入一些内容 - 因此数据必须一直通过控制台驱动程序、显示驱动程序和图形驱动程序。总是有滞后。但它应该是最小的。
dmesg shows the printks in question after fixing the problematic line of code
这只是说 dmesg
没有从内核日志中获取输出。可能还有其他事情正在发生。最简单的是 dmesg
进程没有获得 cpu 时间,在读取系统日志时被阻塞,您的模块在内部执行时禁用了 irq,等等。
我也有类似情况。当我在 msg 末尾添加 '\n' 时很好。