我现在正在使用 Linux 跟踪点进行练习。基本上,我正在尝试制作一个内核模块,其中定义了探测函数并将其连接到 Linux 内核中的跟踪点(内核源文件 dev.c 中的“trace_netif_receive_skb”)。当我在 SLES11 上编译并运行内核模块时,它运行良好。但是当我在 SLES12 上做同样的事情时,它抱怨符号未定义。内核模块源代码为:
1 #include <linux/module.h>
2 #include <linux/kernel.h>
3 #include <linux/init.h>
4 #include <linux/skbuff.h>
5 #include <trace/events/net.h>
6
7 static void probe(void *ignore, struct sk_buff *skb)
8 {
9 printk(KERN_INFO "probe, protocol[0X%04X]\n", ntohs(skb->protocol));
10 }
11
12 static int __init init_tracepoint(void)
13 {
14 if (0 != register_trace_netif_receive_skb(probe, NULL))
15 {
16 printk(KERN_INFO "tracepoint init fails\n");
17 }
18
19 printk(KERN_INFO "tracepoint init succeeds\n");
20 return 0;
21 }
22
23 static void __exit cleanup_tracepoint(void)
24 {
25 unregister_trace_netif_receive_skb(probe, NULL);
26 tracepoint_synchronize_unregister();
27
28 printk(KERN_INFO "tracepoint exit\n");
29 }
30
31 module_init(init_tracepoint);
32 module_exit(cleanup_tracepoint);
33
34 MODULE_LICENSE("GPL");
这是SLES11上的输出,没有报错。
suse11-1:~/works/tracepoint # make
make -C /lib/modules/3.0.76-0.11-default/build M=/root/works/tracepoint modules
make[1]: Entering directory `/usr/src/linux-3.0.76-0.11-obj/x86_64/default'
make -C ../../../linux-3.0.76-0.11 O=/usr/src/linux-3.0.76-0.11-obj/x86_64/default/. modules
CC [M] /root/works/tracepoint/tracepoint.o
Building modules, stage 2.
MODPOST 1 modules
CC /root/works/tracepoint/tracepoint.mod.o
LD [M] /root/works/tracepoint/tracepoint.ko
make[1]: Leaving directory `/usr/src/linux-3.0.76-0.11-obj/x86_64/default'
suse11-1:~/works/tracepoint # insmod tracepoint.ko
这是 SLES12 上的输出,上面写着: WARNING: "__tracepoint_netif_receive_skb" [/root/works/codes/tracepoint/tracepoint.ko] undefined!我可以在 /var/log/messages 中找到“未知符号 __tracepoint_netif_receive_skb (err 0)”。
suse12-1:~/works/codes/tracepoint # make
make -C /lib/modules/4.4.21-69-default/build M=/root/works/codes/tracepoint modules
make[1]: Entering directory '/usr/src/linux-4.4.21-69-obj/x86_64/default'
CC [M] /root/works/codes/tracepoint/tracepoint.o
Building modules, stage 2.
MODPOST 1 modules
WARNING: "__tracepoint_netif_receive_skb" [/root/works/codes/tracepoint/tracepoint.ko] undefined!
CC /root/works/codes/tracepoint/tracepoint.mod.o
LD [M] /root/works/codes/tracepoint/tracepoint.ko
make[1]: Leaving directory '/usr/src/linux-4.4.21-69-obj/x86_64/default'
suse12-1:~/works/codes/tracepoint #
suse12-1:~/works/codes/tracepoint # insmod tracepoint.ko
insmod: ERROR: could not insert module tracepoint.ko: Unknown symbol in module
我检查了 SLES11 和 SLES12 的跟踪点框架的内核源代码,除非调用 EXPORT_TRACEPOINT_SYMBOL() 或 EXPORT_TRACEPOINT_SYMBOL_GPL(),否则不会导出定义的“__tracepoint_##name”“include/linux/tracepoint.h”,但我没有在 Linux 内核代码中找到调用 EXPORT_TRACEPOINT_SYMBOL(netif_receive_skb) 或 EXPORT_TRACEPOINT_SYMBOL_GPL(netif_receive_skb) 以导出符号 __tracepoint_netif_receive_skb 的任何地方。那为什么我在 SLES11 上没有遇到问题呢?我怎样才能让它在 SLES12 上工作?