QT5.15.0 编译时 cc1plus进程占用大量CPU资源卡死问题解决

环境:

  • CPU: Intel 4 Cores
  • Memory: 8GB
  • SUSE-SEL-15

1. 问题描述。

Build Qt5.15.0时, 编译到qtwebengine 后半段[15829/19634] 时,出现频繁卡死,系统崩溃,terminal又没有任何出错信息。top监控实时系统资源信息, 发现同时有6个ccplus 进程,每个cpu占用率达到70左右,并且总的cpu占用率达到96.8。如下图(由于死机无法截图只能拍照片)
在这里插入图片描述

2. 问题分析

csdn上有个很流行的方案是在 QT的pro文件里添加:CONFIG += resources_big。 尝试了,没用。由于不确定原博主是否指的是 Src/qt.pro, 结合qtwebengine/src/core 下生成Makefile.gn_run时用到的是gn_run.pro,所以也修改了gn_run.pro文件。然并卵。

3. 方案。

根据top的启示, cc1plus 起了6 个线程,每个线的cpu程资源占用率都很高,尝试降低cc1plus线程数,即改用make -j 2 编译,发现cc1plus依然是6个。为了弄清楚6个cc1plus线程是怎么起的,切换到私有工程下 make, 发现只起一个cc1plus, 改用make -j 4 发现起了4个cc1plus, 初步猜想是ninja内部自定义的。网上没找到有用的资源,尝试修改ninja源码,搜索发现int GetProcessorCount()有很大嫌疑,cout打印出来返回值是4 (正好等于cpu核数,但是调用的地方判断如果>=4 都+2, 所以只能在这里减去), 改成直接return 2, 重新编译。用top 命令检测系统资源消耗情况,发现cc1plus 线程数变成3 个了。 qtwebengine 编译也不死机了。(至于 -j 参数为什么不起作用,还有待调查,欢迎大家留言讨论。, 我尝试在ninja.cc ReadFlags函数中用cout打印出来-j参数值和config->parallelism, 发现job数没问题)
在这里插入图片描述

4. 扩展

4.1 What is cc1plus?

cc1plus is ++ preprocessor, which is in package gcc-c++. (location: /usr/lib64/gcc/x86_64-suse-linux/7)

GCC has a number of phases to its compilation, and it uses different internal commands to do each phase. C in particular is first preprocessed with cpp, then is compiled into assembly, assembled into machine language, and then linked together.

cc1 is the internal command which takes preprocessed C-language files and converts them to assembly. It’s the actual part that compiles C. For C++, there’s cc1plus, and other internal commands for different languages.

There is a book on Wikibooks that explains the process with pictures. GNU_C_Compiler_Architecture
Figure 1

The purpose of the front end is to read the source file, parse it, and convert it into the standard abstract syntax tree (AST) representation. There is one front end for each programming language. Because of the differences in languages, the format of the generated ASTs is slightly different for each language. The next step after AST generation is the unification step in which the AST tree is converted into a unified form called generic. After this, the middle end part of the compiler takes control. First, the tree is converted into another representation called GIMPLE. In this form, each expression contains no more than three operands, all control flow constructs are represented as combinations of conditional statements and goto operators, arguments of a function call can only be variables, etc. Figure 2 illustrates the differences between a tree in generic form and a tree in GIMPLE form. GIMPLE is a convenient representation for optimizing the source code.

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值