一个奇葩bug的解决

公司做的网络视频监控产品正在做测试,这两天测试人员报告说多台设备出现奇怪的问题,现象如下:
(1)PC端接收不到设备端应用程序采集通过网络发送的图像
(2)PC端可以ping通设备端,telnet可以登录设备,设备ping PC端只能通一个数据包


于是我telnet登录异常设备,通过tftp http ftp上传下载文件到PC,发现都正常。

起初怀疑是设备网卡driver出现问题,但是细想网卡driver处于数据链路层,

上层(不管应用层是哪种协议)传下来的数据包对于driver来说是一样的。tftp ftp http能正常工作,说明网卡driver能正常收发数据, ping应该也能正常工作才对。

仔细看ping返回的结果,发现有一些不一样的地方,如下:

# ping 10.0.14.198
PING 10.0.14.198 (10.0.14.198): 56 data bytes
64 bytes from 10.0.14.198: seq=0 ttl=127 time=0.817 ms
^C
--- 10.0.14.198 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.817/0.817/0.817 ms

ping通一个icmp包,之后就没有反应,ctrl+c程序退出显示没有丢包。
从现象上来看,并不是ping出现丢包,而是感觉ping好像在完成一次数据包通讯后阻塞。
想到这里,就不再怀疑是网卡driver的问题,想再找找看系统其他的异常现象。

ps查看系统进程时发现异常设备pid已经到了2万多,并且不再增加,而对比正常设备pid在1万多,pid还在增加。
于是想是不是异常设备的图像采集程序产生进程过多,系统进程数到达最大值,无法创建进程导致这个bug
写一段测试代码如下:

#include 
#include 
#include 
#include 
#define MAXPROCESS 65535
#define SLEEPTIME 1
void main (int argc , char ** argv)
{
    pid_t pid;
    int count = 0;
    int maxprocess = MAXPROCESS;

    if (argc == 2) {
        maxprocess = atoi(argv[1]);
    }

    for (count = 0; count < maxprocess; count++)
    {
        pid = fork();
        if (pid < 0) {
            perror("fork error");
            exit(1);
        } else if (pid == 0) {
            printf("child %d start\n", count);
            sleep(SLEEPTIME);
            printf("child %d end\n", count);
            exit(0);
        }
        printf("parent:create %d child\n", count);
    }

    for (count = 0; count < MAXPROCESS; count++) {
        wait();
    }
    exit(0);
}

创建指定个数子进程sleep 1s,父进程等待子进程退出后回收资源然后退出。
编译运行,结果如下:

# ./fork_test 1
parent:create 0 child
child 0 start
^C
#
发现程序不退出,根据打印发现是子进程sleep没有退出,咦,这是什么情况。
直接在console下执行sleep命令,发现也是阻塞不退出,只能ctrl+c退出。
这是该bug的另一个现象:sleep阻塞。
查看系统的pid限制,如下:

# cat /proc/sys/kernel/pid_max
32768
观察正常设备pid,发现系统pid在达到32768后会从0-32768中再找已释放的pid使用。
所以也不再怀疑是系统进程数限制,还得再找其他线索。

date查看系统时间与hwclock获取的RTC时间对比,发现系统时间跟RTC时间差距较大,但是kernel启动加载RTCdriver后会同步系统时间和RTC时间,系统时间与RTC时间应该一致呀?
观察找到原因,发现又一个重要bug现象,系统时间走的是准的,晚于RTC时间的原因是,系统时间在某个时间值上往前走180s左右就会回跳回来再往前走,来回循环,导致系统时间晚于RTC时间!

到这里,关于这个bug已经发现4种现象:
(1)PC端接收不到设备端应用程序采集通过网络发送的图像
(2)PC端可以ping通设备端,telnet可以登录设备,设备ping PC端只能通一个数据包
(3)设备端sleep会阻塞

(4)设备端date系统时间走180s回跳

你可能感兴趣的:(linux,kernel)