一、报错情况
Ubuntu中QT应用程序突然崩溃,控制台最后报错:
GLib-ERROR **: 11:21:59.132: Creating pipes for GWakeup: 打开的文件过多
查看程序日志,发现程序崩溃前一小时,即出现错误,日志:
2023-11-09 10:33:09 - [DEBUG] (dnbscomdef.cpp:56, bool DNBSComDef::open()): [INFO] open com error: "Too many open files"
2023-11-09 10:33:10 - [DEBUG] (dnbscomdef.cpp:56, bool DNBSComDef::open()): [INFO] open com error: "Too many open files"
2023-11-09 10:33:11 - [DEBUG] (dnbscomdef.cpp:56, bool DNBSComDef::open()): [INFO] open com error: "Too many open files"
2023-11-09 10:33:12 - [DEBUG] (iotcpcli.cpp:44, virtual bool IoTcpCli::open(QString&)): 2404 "192.168.30.1"
2023-11-09 10:33:12 - [DEBUG] (onekeysc.cpp:949, virtual void Onekeysc::run()): reson: "拒绝连接"
2023-11-09 10:33:12 - [DEBUG] (dnbscomdef.cpp:56, bool DNBSComDef::open()): [INFO] open com error: "Permission error while locking the device"
2023-11-09 10:33:13 - [DEBUG] (dnbscomdef.cpp:56, bool DNBSComDef::open()): [INFO] open com error: "Permission error while locking the device"
2023-11-09 10:33:15 - [DEBUG] (onekeysc.cpp:949, virtual void Onekeysc::run()): reson: "打开的文件过多"
根据报错日志,得知问题出在打开串口,以及Tcp客户端的连接上。
二、问题分析
为了分析具体情况,重新启动程序,观察文件打开数量。
首先找到程序进程:
fang@ubuntu:~$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.1 168456 11824 ? Ss 11:26 0:03 /sbin/init auto noprompt
.
.
.
fang 6649 1.1 2.0 1439080 163016 ? Sl 14:19 0:12 /home/wufang/work/jmlwf30/src20230807/bin/runview
ps aux 命令可以帮我们找到进程的ID,command列是程序目录,记得输入命令前,把窗口宽度拉大些,不然看不到。
然后,查看进程使用的文件数:
fang@ubuntu:~$ lsof -p "6649" | wc -l
721
可以看到数量是721,而且数量还在随着时间增长而增大。
可以把使用文件的详细信息输出到文件中,进一步分析:
fang@ubuntu:~$ lsof -p 6649 > /home/wufang/openfiles.log
输出的文件内容:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
...
runview 6649 wufang 38r REG 8,5 32768 1835137 /home/wufang/.local/share/gvfs-metadata/trash:-e509eb34.log
runview 6649 wufang 39u sock 0,8 0t0 89987 protocol: TCP
runview 6649 wufang 40u sock 0,8 0t0 89959 protocol: TCP
runview 6649 wufang 41u sock 0,8 0t0 89956 protocol: TCP
runview 6649 wufang 42u sock 0,8 0t0 89957 protocol: TCP
runview 6649 wufang 43u sock 0,8 0t0 89958 protocol: TCP
runview 6649 wufang 44u sock 0,8 0t0 89990 protocol: TCP
runview 6649 wufang 45u sock 0,8 0t0 89991 protocol: TCP
runview 6649 wufang 46u sock 0,8 0t0 89988 protocol: TCP
runview 6649 wufang 47u sock 0,8 0t0 89993 protocol: TCP
runview 6649 wufang 48u sock 0,8 0t0 89992 protocol: TCP
runview 6649 wufang 49u sock 0,8 0t0 90025 protocol: TCP
runview 6649 wufang 50u sock 0,8 0t0 89997 protocol: TCP
runview 6649 wufang 51u sock 0,8 0t0 90026 protocol: TCP
runview 6649 wufang 52u sock 0,8 0t0 90028 protocol: TCP
...
可以看到大量的TYPE:sock,NAME:protocol:TCP的文件信息。
结合报错日志,就可以确定问题来源了。
在Ubuntu系统中,打开串口、创建TCP连接,实际上都是针对文件的操作。
也就可以确定,是创建的tcp文件未及时关闭,日志文件也进一步确认。是创建的TCP客户端一直未连接上服务器,在重试的时候,未关闭原来的tcp socket,直接创建新连接,导致的报错。
日志中,串口通讯出现的错误,也是由此带来的。
本来正常的串口通讯也受到影响,无法通讯。
三、处理解决
sock = socket(AF_INET,SOCK_STREAM,0);
if(sock < 0)
{
reson = strerror(errno);
return false;
}
//连接 省略...
.
.
.
int ret = connect(sock, (struct sockaddr *)&serverAddr, sizeof(serverAddr));
if(ret < 0)
{
reson = strerror(errno);
::close(sock); // fix "open files too many" error
return false;
}
启动程序,运行一段后,检查文件使用数量:
fang@ubuntu:~$ lsof -p 9212 | wc -l
319
fang@ubuntu:~$ lsof -p 9212 | wc -l
320
fang@ubuntu:~$ lsof -p 9212 | wc -l
319
fang@ubuntu:~$ lsof -p 9212 | wc -l
319
fang@ubuntu:~$
未出现文件数量不停增长的情况。