一个QT程序无法启动问题的分析与解决

这篇具有很好参考价值的文章主要介绍了一个QT程序无法启动问题的分析与解决。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

最近调试设备,遇到了一个奇怪的问题:QT程序无法重启。

查看日志,发现报如下错误:

QLock::QLock: Cannot create semaphore /tmp/qtembedded-0/QtEmbedded-0 'd' (22, Invalid argument)
Cannot get display lock
Aborted

下面整理记录问题的解决过程。

1 首先,说明程序之前奔溃了。
因为这是重启过程中报的信息。后台监控发现程序奔溃后,会再次拉起。这个日志就是拉起过程中出现的。

2 先不管之前为啥崩溃了。我们看看程序为啥无法成功重启。

3 是否是因为程序本身出了什么问题?
因为这个错误之前不曾见过,又因为之前出现过flash上的文件发生损坏的情况,所以猜测会不会是因为坏块导致的执行程序文件损坏。
通过将程序二进制文件拷贝出来以及将新的替换进去,验证程序没有发生变化,但是问题一直存在。
使用其他QT程序,问题也依然存在,所以程序本身的问题被排除

4 是否是因为QT基础库问题导致?
基本思路还是跟3中描述一样,只不过这次怀疑是否是QT的基础库发生了变动。
如果基础库发生变动,那么所有QT程序都可能无法正常运行。
将设备上的QT相关库拷贝出来,跟烧写版本对比,发现基础库没有变化。
重新替换QT基础库,问题仍然存在。

5 是否是因为QT运行环境问题导致?
拷贝异常设备中,root tmp等目录下QT生成的文件,跟正常设备对比,发现没有明显的差异

6 查找错误日志所在代码
既然前面几个怀疑点都排除了,没有明确的验证方向的情况下,决定看看错误日志到底是那块代码打印的。
通过搜索QT程序和QT开发环境,发现Cannot get display lock这一句是QT基础库里的打印
进一步的,确定了代码所在位置:qtapplication_qws.cpp.

跟踪代码,发现是qtlock初始化失败了。
但是,相关的代码有很多编译选项,不确定错误到底是那个if else逻辑出来的。
考虑到整个QT自身的代码比较庞大,搜索也不容易确定宏是否是打开状态,决定添加日志,跟踪定位问题。

7 重新编译QT库
重新编译QT库后,将日志所在的GUI库替换,重新跑程序来看:
 

   QLock::lock(): file name /tmp/qtembedded-0/QtEmbedded-0 id=d create=create 
   QLock::lock(): QT_POSIX_IPC 
   QLock::lock(): QT_POSIX_IPC 1 data id = -1 semkey=1678592551 (2, No such file or directory)
   QLock::lock(): QT_POSIX_IPC 2 data id = -1 semkey=1678592551, (28, No space left on device)
   QLock::lock(): QT_POSIX_IPC 3 data id = -1 arg.val=200, (22, Invalid argument)
   QLock::QLock: Cannot create semaphore /tmp/qtembedded-0/QtEmbedded-0 'd' (22, Invalid argument)
   Cannot get display lock
   Aborted

这是最后确定问题的日志,中间过程不再说明。
我们看到,走了IPC处理分支
关键错误在第四行,errno是28,说明没有空间
这句日志对应的代码接口为semget

8 查看系统调用说明
man semget,查看这个系统调用的使用说明。
其中有关于28错误的说明,ENOSPC,基本是说创建信号量时,达到了系统配置的上限,没有空间创建新的。
到这里,基本可以猜出问题所在了。就是程序之前可能反复重启,消耗了所有的信号量空间,达到一定次数后,无法创建新的信号量,导致启动失败。

9 查看系统配置参数
查看系统对信号量 共享内存等的配置
 # cat /proc/sys/kernel/sem 
  250     32000   32      128

可以看到,信号量给的是128个。
具体查看系统中创建的信号量

  # cat /proc/sysvipc/sem 
         key      semid perms      nsems   uid   gid  cuid  cgid      otime      ctime
  1678576641      32768   600          1     0     0     0     0 1649596772         43
  1678623274      65537   600          1     0     0     0     0 1649596832 1649596774
  1678624879    4259842   600          1     0     0     0     0 1649606005 1649605937
  1678625856     131075   600          1     0     0     0     0 1649596973 1649596905
  ...
  1678593752    4030586   600          1     0     0     0     0 1649604774 1649604707
  1678595070    4063355   600          1     0     0     0     0 1649604848 1649604776
  1678596881    4096124   600          1     0     0     0     0 1649604917 1649604849
  1678598116    4128893   600          1     0     0     0     0 1649604986 1649604918
  1678599937    4161662   600          1     0     0     0     0 1649605054 1649604987
  1678598220    4358271   600          1     0     0     0     0 1649964888 1649964880

统计一下,发现达到了上限。这里多的1是第一行,用于说明各个列段含义的行
  # cat /proc/sysvipc/sem  | wc -l
  129

10 验证
删除一个信号量,重启程序,可以看到重启成功

# ipcrm -s 4194431

  QLock::lock():  file name /tmp/qtembedded-0/QtEmbedded-0 id=d create=create 
  QLock::lock(): QT_POSIX_IPC 
  QLock::lock(): QT_POSIX_IPC 1 data id = -1 semkey=1678598220 (2, No such file or directory)
  QLock::lock(): QT_POSIX_IPC 2 data id = 4358271 semkey=1678598220, (2, No such file or directory)
  QLock::lock(): QT_POSIX_IPC 3 data id = 4358271 arg.val=200, (2, No such file or directory)

关闭程序,再次重启,看到失败,说明问题就是由于空间限制,导致信号量创建失败产生

  QLock::lock():  file name /tmp/qtembedded-0/QtEmbedded-0 id=d create=create 
  QLock::lock(): QT_POSIX_IPC 
  QLock::lock(): QT_POSIX_IPC 1 data id = -1 semkey=1678598276 (2, No such file or directory)
  QLock::lock(): QT_POSIX_IPC 2 data id = -1 semkey=1678598276, (28, No space left on device)
  QLock::lock(): QT_POSIX_IPC 3 data id = -1 arg.val=200, (22, Invalid argument)
  QLock::QLock: Cannot create semaphore /tmp/qtembedded-0/QtEmbedded-0 'd' (22, Invalid argument)
  Cannot get display lock
  Aborted

11 进一步的研究
根据代码来看,每次创建信号量的ftok函数调用参数都是一样的,但是为啥QT每次打印出来的id不一样呢。
因为不一样,所以每次创建的总是保留着,直到空间用完。
  
但是根据接口说明,ftok同样的参数,生成的结果是一样的。专门写了一个程序验证了一下:
  /tmp # /mnt/a.out 
  semkey is 1678611420 
  /tmp # /mnt/a.out 
  semkey is 1678611420 
  /tmp # /mnt/a.out 
  semkey is 1678611420 
  
为啥QT创建的不一样呢?
我们重新创建文件,再跑程序,可以看到生成的不一样了。
ftok是根据的文件的inode信息来生成id的。
  /tmp # rm /tmp/qtembedded-0/QtEmbedded-0
  /tmp # touch /tmp/qtembedded-0/QtEmbedded-0
  /tmp # /mnt/a.out 
  semkey is 1678611403 
  
因此,QT里是每次新建了文件导致id不一样了。对此做针对性修改,问题即解决。

12:其他

涉及的代码文件为:
qt-everywhere-opensource-src\src\gui\kernel\qappliction_qws.cpp
qt-everywhere-opensource-src\src\gui\embedded\qlock.cpp文章来源地址https://www.toymoban.com/news/detail-744060.html

到了这里,关于一个QT程序无法启动问题的分析与解决的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 解决Windows因缺少vcomp100.dll无法启动程序的问题

    其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题,如果是新手第一时间会认为是软件或游戏出错了,其实并不是这样,其主要原因就是你电脑系统的该dll文件丢失了或者损坏了,这时你只需下载这个vcomp100.dll文件进行安装(前提是找到适合的版本),当我们执行

    2024年02月06日
    浏览(70)
  • 解决因缺少xinput1_1.dll无法启动程序的问题

    其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题,如果是新手第一时间会认为是软件或游戏出错了,其实并不是这样,其主要原因就是你电脑系统的该dll文件丢失了或者损坏了,这时你只需下载这个xinput1_1.dll文件进行安装(前提是找到适合的版本),当我们执行

    2024年02月10日
    浏览(76)
  • 解决Windows缺少vcomp120.dll无法启动应用程序的问题

    其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题,如果是新手第一时间会认为是软件或游戏出错了,其实并不是这样,其主要原因就是你电脑系统的该dll文件丢失了或者损坏了,这时你只需下载这个vcomp120.dll文件进行安装(前提是找到适合的版本),当我们执行

    2024年02月08日
    浏览(61)
  • 电脑“应用程序无法启动,因为应用程序的并行配置不正确......“问题的解决方法

    问题 : win10某天开机发现绝大部分exe都无法运行或安装,错误信息提示如下: “应用程序无法启动,因为应用程序的并行配置不正确。有关详细信息,请参阅应用程序事件日志,或使用命令行 sxstrace.exe 工具。” 排查过程 :命令行 sxstrace.exe 工具无法正常打开 查看应用程序

    2024年02月04日
    浏览(73)
  • 解决Windows缺少xerces-c_3_0.dll无法启动程序的问题

    其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题,如果是新手第一时间会认为是软件或游戏出错了,其实并不是这样,其主要原因就是你电脑系统的该dll文件丢失了或者损坏了,这时你只需下载这个xerces-c_3_0.dll文件进行安装(前提是找到适合的版本),当我们执

    2024年02月16日
    浏览(69)
  • VMware虚拟机启动Ubuntu时报错:“另一个程序已锁定文件的一部分,进程无法访问”该怎样解决呢?

    宝子们有木有遇到这样的问题呀“另一个程序已锁定文件的一部分,进程无法访问”,跟着辣面子来解决这个问题吧 按照自己路径寻找 放心将它们删除 出现此文件是因为虚拟机在运行的时候,会锁定文件,防止被修改,如果系统突然崩溃、异常关机等,虚拟机尚未把已经锁

    2024年02月11日
    浏览(61)
  • 解决“无法启动此程序,因为计算机中丢失VCRUNTIME140.dll,尝试重新安装此程序以解决此问题”方案合集

    今天装配mysql的时候,系统出现了报错。 .dll文件是动态链接库文件,是一种可执行文件,很多时候系统会通过调用一些vc的dll文件来运行一些程序。 查阅资料以后发现有几个解决方案,笔者通过第二种解决方案解决该问题。 方案1 : 通过下载 VCRUNTIME140_1.dll文件后直接复制到

    2024年01月16日
    浏览(64)
  • 解决因缺少d3dx9_31.dll程序无法运行启动问题

    其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题,如果是新手第一时间会认为是软件或游戏出错了,其实并不是这样,其主要原因就是你电脑系统的该dll文件丢失了或者损坏了,这时你只需下载这个d3dx9_31.dll文件进行安装(前提是找到适合的版本),当我们执行

    2024年03月14日
    浏览(70)
  • 关于Qt程序打包后运行库依赖的常见问题分析及解决方法

    目录 一. 大致如下常见问题: (1)找不到程序所依赖的Qt库 version `Qt_5\\\' not found (required by (2)Could not Load the Qt platform plugin \\\"xcb\\\" in \\\"\\\" even though it was found (3)打包到在不同的linux系统下,或者打包到高版本的相同系统下,运行程序时,直接提示段错误即segmentation fault,或者I

    2023年04月17日
    浏览(57)
  • 系统错误 无法启动此程序,因为计算机中丢失MSVCP140_1.dll。尝试重新安装该程序已解决此问题

    我在windows10系统,使用Qt5.15.2 打包命令:windeployqt.exe ImageManageSys.exe ,把ImageManageSys.exe 拷贝到windows7系统下,报错:ImageManageSys.exe - 系统错误 无法启动此程序,因为计算机中丢失MSVCP140_1.dll。尝试重新安装该程序已解决此问题。 当您在Windows 10系统上使用windeployqt.exe打包应用程

    2024年02月07日
    浏览(77)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包