読者です 読者をやめる 読者になる 読者になる

φ(.. )メモシテオコウ printk:%pの拡張機能

linux kernel

カーネル/VM探検隊の懇親会でLinuxのprintkの%pが拡張されてるということを聞いてちょっと調べてみました。
カーネルに付属しているprintk-formats.txtに説明が色々書かれています。また、%pFと%pSで何が違うの?というところはvsprintf.cのコメントに書かれてました。

とりあえず、適当にカーネルモジュールを書いて試してみます。

[masami@saga:~/codes/printk_test]$ cat printk_test.c
#include <linux/module.h>
#include <linux/kernel.h>

MODULE_DESCRIPTION("printk test module");
MODULE_AUTHOR("masami256");
MODULE_LICENSE("GPL");

static char *str = "moimoi";

static void
foobar(void)
{

        struct task_struct *task = current;

        printk(KERN_INFO"Test %%pF at %s\n%pF\n\n", __func__, &foobar);
        printk(KERN_INFO"Test %%pf at %s\n%pf\n\n", __func__, &foobar);

        printk(KERN_INFO"Test %%pB\n%pB\n\n", &foobar);

        printk(KERN_INFO"Test %%pK\n%pK\n\n", str);
        printk(KERN_INFO"Test %%pk\n%pk\n\n", str);

        printk(KERN_INFO"Test %%pR\n%pR\n\n", task);
        printk(KERN_INFO"Test %%pr\n%pr\n\n", task);

}

static int
printk_test_init(void)
{
        printk(KERN_INFO"[-]printk_test module is loaded\n");
        foobar();

        return 0;
}

static void
printk_test_cleanup(void)
{
        printk(KERN_INFO"[-]printk_test module is unloaded\n");
}

module_init(printk_test_init);
module_exit(printk_test_cleanup);

これをmake->insmodしてdmesgで確認するとこのようになりました。

[ 4021.186188] [-]printk_test module is loaded
[ 4021.186193] Test %pF at foobar
foobar+0x0/0xc0 [printk_test]

[ 4021.186204] Test %pf at foobar
foobar [printk_test]

[ 4021.186218] Test %pB
0xffffffffa0509fff

[ 4021.186221] Test %pK
ffffffffa050b066

[ 4021.186224] Test %pk
ffffffffa050b066

[ 4021.186228] Test %pR
[??? 0x00000000-0xffff8807e7694000 flags 0x0]

[ 4021.186232] Test %pr
[??? 0x00000000-0xffff8807e7694000 flags 0x0]

んー、%pBの出力がprintk-formats.txtと違ってアドレスしか出てないですね。