我正在尝试调试我的内核模块。当我运行它时,我收到以下内核警告,但似乎没有像我见过的其他警告那样的信息性消息。是否有可能从中获得任何有用的信息?
更多信息:
该模块称为firewall
,它将 tcp 数据包转移到用户空间中的代理服务器,然后代理将其收到的 tcp 数据发送到预定目的地。
当通过简单地接收一个套接字上的所有数据并在另一个套接字上调用 sendall 来处理 http 响应时,就会发生这种情况。当所有响应都在一个数据包中时,不会出现警告,但当 http 有效负载数据被分段为多个 tcp 数据包时,则会出现警告。
代理是用 python 编写的。我觉得奇怪的是,警告中写着“python tainted”。用户空间应用程序会导致内核警告吗?
我尝试只在代理中接收一个大文件,但不发送它,并且没有收到任何错误,并且系统在任何时候都没有冻结。该问题仅发生在调用 socket.sendall/socket.send 时
减小读取缓冲区大小然后发送较小的块会导致系统更快锁定。
关闭两个gso
, tso
withethtool
可以防止出现错误消息,但系统在相同的时间后仍然锁定,这让我想知道警告是否与锁定有关
[16795.153478] ------------[ cut here ]------------
[16795.153489] WARNING: at /build/buildd/linux-3.2.0/net/core/dev.c:1970 skb_gso_segment+0x2e9/0x360()
[16795.153492] Hardware name: VirtualBox
[16795.153495] e1000: caps=(0x40014b89, 0x401b4b89) len=2948 data_len=0 ip_summed=0
[16795.153497] Modules linked in: firewall(O) vesafb vboxsf(O) snd_intel8x0 snd_ac97_codec ac97_bus snd_pcm snd_seq_midi snd_rawmidi snd_seq_midi_event snd_seq snd_timer snd_seq_device joydev psmouse snd soundcore serio_raw i2c_piix4 snd_page_alloc vboxguest(O) video bnep mac_hid rfcomm bluetooth parport_pc ppdev lp parport usbhid hid e1000 [last unloaded: firewall]
[16795.153529] Pid: 7644, comm: python Tainted: G W O 3.2.0-37-generic-pae #58-Ubuntu
[16795.153532] Call Trace:
[16795.153540] [<c105a822>] warn_slowpath_common+0x72/0xa0
[16795.153544] [<c14ad2b9>] ? skb_gso_segment+0x2e9/0x360
[16795.153548] [<c14ad2b9>] ? skb_gso_segment+0x2e9/0x360
[16795.153551] [<c105a8f3>] warn_slowpath_fmt+0x33/0x40
[16795.153555] [<c14ad2b9>] skb_gso_segment+0x2e9/0x360
[16795.153561] [<c14b01ce>] dev_hard_start_xmit+0xae/0x4c0
[16795.153568] [<f9a6f2fd>] ? divertPacket+0x7d/0xe0 [firewall]
[16795.153574] [<c14c8151>] sch_direct_xmit+0xb1/0x180
[16795.153578] [<f9a6f941>] ? hook_localout+0x71/0xe0 [firewall]
[16795.153582] [<c14b06d6>] dev_queue_xmit+0xf6/0x370
[16795.153586] [<c14c6459>] ? eth_header+0x29/0xc0
[16795.153590] [<c14b73f0>] neigh_resolve_output+0x100/0x1c0
[16795.153594] [<c14c6430>] ? eth_rebuild_header+0x80/0x80
[16795.153598] [<c14dec62>] ip_finish_output+0x152/0x2e0
[16795.153602] [<c14df75f>] ip_output+0xaf/0xc0
[16795.153605] [<c14dd340>] ? ip_forward_options+0x1d0/0x1d0
[16795.153609] [<c14deec0>] ip_local_out+0x20/0x30
[16795.153612] [<c14defee>] ip_queue_xmit+0x11e/0x3c0
[16795.153617] [<c10841c5>] ? getnstimeofday+0x55/0x120
[16795.153622] [<c14f4de7>] tcp_transmit_skb+0x2d7/0x4a0
[16795.153626] [<c14f5786>] tcp_write_xmit+0x146/0x3a0
[16795.153630] [<c14f5a4c>] __tcp_push_pending_frames+0x2c/0x90
[16795.153634] [<c14e7d2b>] tcp_sendmsg+0x71b/0xae0
[16795.153638] [<c104a33d>] ? update_curr+0x1ed/0x360
[16795.153642] [<c1509c23>] ? inet_recvmsg+0x73/0x90
[16795.153646] [<c1509ca0>] inet_sendmsg+0x60/0xa0
[16795.153650] [<c149ae27>] sock_sendmsg+0xf7/0x120
[16795.153655] [<c1044648>] ? ttwu_do_wakeup+0x28/0x130
[16795.153660] [<c1036a98>] ? default_spin_lock_flags+0x8/0x10
[16795.153667] [<c149ce7e>] sys_sendto+0x10e/0x150
[16795.153672] [<c1117e7f>] ? handle_pte_fault+0x28f/0x2c0
[16795.153675] [<c111809e>] ? handle_mm_fault+0x15e/0x2c0
[16795.153679] [<c15ab9c7>] ? do_page_fault+0x227/0x490
[16795.153681] [<c149cefb>] sys_send+0x3b/0x40
[16795.153684] [<c149d842>] sys_socketcall+0x162/0x2c0
[16795.153687] [<c15af55f>] sysenter_do_call+0x12/0x28
[16795.153689] ---[ end trace 3170256120cbbc8f ]---
答案1
您是否尝试过从堆栈跟踪末尾向后跟踪addr2line
?
例如查看最后一行sysenter_do_call+0x12/0x28
它告诉我们偏移量是0x12
,长度是0x28
$ addr2line -e [path-to-kernel-module-with-issue] 0xc15af55f
等等......gdb
是将堆栈跟踪分解为行的另一种选择。
但是,我不完全确定您是如何到达内核恐慌的,因为我在您提供的日志摘录中看到的只是一个警告。在您发布堆栈跟踪之后,它是否会导致崩溃/内核恐慌消息?
--------就发布的堆栈跟踪而言:它与一般分段卸载有关,并且 skbuffer 对 ip_summed 校验和不满意,因此禁用大型\一般接收器卸载
$ethtool -k [NIC] lro off
$ethtool -k [NIC] gro off
可能是一个可能的解决方法。此外,跳过校验和检查skb->ip_summed = CHECKSUM_UNNECESSARY
也可能解决此问题,具体取决于设置的目的。