【发布时间】:2019-06-11 13:47:36
【问题描述】:
我正在开发具有 Linux 的嵌入式系统。 客户端线程正在套接字中写入一些数据,但另一端正在读取的服务器线程与写入的不同。这导致线程(和父进程)崩溃。
我是网络和 Linux 的新手。 我已经转储了正在写入的每条数据,一切都很好。
gdb 中的函数跟踪显示以下信息。
(gdb)
#0 0x00007f62be8e8670 in getenv () from /lib/libc.so.6
#1 0x00007f62be92057a in __libc_message () from /lib/libc.so.6
#2 0x00007f62be99f927 in __fortify_fail () from /lib/libc.so.6
#3 0x00007f62be99f8f0 in __stack_chk_fail () from /lib/libc.so.6
#4 0x0000000000406471 in reading (sockFd=15) at __line_number_in_the_program__
#5 0x793bcf318b18bb01 in ?? ()
#6 0x117d0300942ff567 in ?? ()
#7 0x0000000100000000 in ?? ()
..
..
..
直到 #785 带有一些 [随机] 地址。
reading() 是在服务器线程中处理读取数据的函数。
我怀疑套接字内部出了点问题。 有什么方法可以查看套接字(客户端/服务器)缓冲区中的数据而不读取它? 或者有什么其他方法可以用 gdb 进一步调试?
已经有一些检查可以正确处理读取的数据,但这些也无济于事。
【问题讨论】:
-
不行,socket发送/接收缓冲区是由内核管理的,不能暴露给用户空间,否则会出现linux内核的安全问题
-
如果这些是 AF_INET or AF_INET6 套接字(TCP 或 UDP),那么像 Wireshark 和 Fiddler 这样的工具对于调试此类问题非常有用。 Wireshark 可让您查看数据包中发生的情况。如果您的协议基于 HTTP,Fiddler 非常有用,并且即使对于加密的 HTTPS 连接也可以显示请求/响应的完整历史记录。
-
套接字内部几乎可以肯定没有任何问题。虽然从技术上讲,您可能在 Linux 内核中发现了一个错误,但请记住,Linux 在数亿台机器上使用,其中大多数依赖于网络。因此,极不可能找到会更改套接字内数据的错误。您很有可能在自己的代码中出错。
-
谢谢@PhilipCouling。使用 Wireshark 是个好主意。如果有帮助,我会检查一下。由于通信是在 localhost 中进行的,因此将使用带有环回地址的 Wireshark。我也承认你的第二条评论。
-
是的,有。查找
recv(2)的MSG_PEEK标志。这对于调试程序是否有用是完全不同的问题——这是非常值得怀疑的。您的“服务器”应该能够处理格式错误的数据,而不是像表面上那样进行递归旅行或炸毁堆栈。
标签: linux networking linux-kernel c