From e5658307d5fa1c9ddffc9641b7e3cddfeb86dde7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=91=E6=B2=A7?= <1050706328@qq.com> Date: Tue, 29 Oct 2024 01:12:42 +0800 Subject: [PATCH] =?UTF-8?q?OSPP2024-LLVM=E6=9E=84=E5=BB=BAopenEuler?= =?UTF-8?q?=E8=BD=AF=E4=BB=B6=E5=8C=85=E5=85=BC=E5=AE=B9=E6=80=A7=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E5=88=86=E6=9E=90=E5=8F=8A=E8=A7=A3=E5=86=B3(Part=20I?= =?UTF-8?q?I)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...15\345\217\212\344\277\256\345\244\215.md" | 192 ++++++++++ ...15\345\217\212\344\277\256\345\244\215.md" | 345 ++++++++++++++++++ ...15\345\217\212\344\277\256\345\244\215.md" | 117 ++++++ ...15\345\217\212\344\277\256\345\244\215.md" | 62 ++++ ...15\345\217\212\344\277\256\345\244\215.md" | 83 +++++ ...15\345\217\212\344\277\256\345\244\215.md" | 67 ++++ ...15\345\217\212\344\277\256\345\244\215.md" | 115 ++++++ ...15\345\217\212\344\277\256\345\244\215.md" | 255 +++++++++++++ ...15\345\217\212\344\277\256\345\244\215.md" | 88 +++++ ...15\345\217\212\344\277\256\345\244\215.md" | 192 ++++++++++ ...15\345\217\212\344\277\256\345\244\215.md" | 95 +++++ 11 files changed, 1611 insertions(+) create mode 100644 "LLVM Parallel Universe Project/\351\227\256\351\242\230\345\256\232\344\275\215\346\200\273\347\273\223/OSPP2024-LLVM\346\236\204\345\273\272openEuler\350\275\257\344\273\266\345\214\205\345\205\274\345\256\271\346\200\247\351\227\256\351\242\230\345\210\206\346\236\220\345\217\212\350\247\243\345\206\263(Part II)/lcr\351\227\256\351\242\230\345\256\232\344\275\215\345\217\212\344\277\256\345\244\215.md" create mode 100644 "LLVM Parallel Universe Project/\351\227\256\351\242\230\345\256\232\344\275\215\346\200\273\347\273\223/OSPP2024-LLVM\346\236\204\345\273\272openEuler\350\275\257\344\273\266\345\214\205\345\205\274\345\256\271\346\200\247\351\227\256\351\242\230\345\210\206\346\236\220\345\217\212\350\247\243\345\206\263(Part II)/libevent\351\227\256\351\242\230\345\256\232\344\275\215\345\217\212\344\277\256\345\244\215.md" create mode 100644 "LLVM Parallel Universe Project/\351\227\256\351\242\230\345\256\232\344\275\215\346\200\273\347\273\223/OSPP2024-LLVM\346\236\204\345\273\272openEuler\350\275\257\344\273\266\345\214\205\345\205\274\345\256\271\346\200\247\351\227\256\351\242\230\345\210\206\346\236\220\345\217\212\350\247\243\345\206\263(Part II)/libreswan\351\227\256\351\242\230\345\256\232\344\275\215\345\217\212\344\277\256\345\244\215.md" create mode 100644 "LLVM Parallel Universe Project/\351\227\256\351\242\230\345\256\232\344\275\215\346\200\273\347\273\223/OSPP2024-LLVM\346\236\204\345\273\272openEuler\350\275\257\344\273\266\345\214\205\345\205\274\345\256\271\346\200\247\351\227\256\351\242\230\345\210\206\346\236\220\345\217\212\350\247\243\345\206\263(Part II)/libseccomp\351\227\256\351\242\230\345\256\232\344\275\215\345\217\212\344\277\256\345\244\215.md" create mode 100644 "LLVM Parallel Universe Project/\351\227\256\351\242\230\345\256\232\344\275\215\346\200\273\347\273\223/OSPP2024-LLVM\346\236\204\345\273\272openEuler\350\275\257\344\273\266\345\214\205\345\205\274\345\256\271\346\200\247\351\227\256\351\242\230\345\210\206\346\236\220\345\217\212\350\247\243\345\206\263(Part II)/libsecret\351\227\256\351\242\230\345\256\232\344\275\215\345\217\212\344\277\256\345\244\215.md" create mode 100644 "LLVM Parallel Universe Project/\351\227\256\351\242\230\345\256\232\344\275\215\346\200\273\347\273\223/OSPP2024-LLVM\346\236\204\345\273\272openEuler\350\275\257\344\273\266\345\214\205\345\205\274\345\256\271\346\200\247\351\227\256\351\242\230\345\210\206\346\236\220\345\217\212\350\247\243\345\206\263(Part II)/lvm2\351\227\256\351\242\230\345\256\232\344\275\215\345\217\212\344\277\256\345\244\215.md" create mode 100644 "LLVM Parallel Universe Project/\351\227\256\351\242\230\345\256\232\344\275\215\346\200\273\347\273\223/OSPP2024-LLVM\346\236\204\345\273\272openEuler\350\275\257\344\273\266\345\214\205\345\205\274\345\256\271\346\200\247\351\227\256\351\242\230\345\210\206\346\236\220\345\217\212\350\247\243\345\206\263(Part II)/lxc\351\227\256\351\242\230\345\256\232\344\275\215\345\217\212\344\277\256\345\244\215.md" create mode 100644 "LLVM Parallel Universe Project/\351\227\256\351\242\230\345\256\232\344\275\215\346\200\273\347\273\223/OSPP2024-LLVM\346\236\204\345\273\272openEuler\350\275\257\344\273\266\345\214\205\345\205\274\345\256\271\346\200\247\351\227\256\351\242\230\345\210\206\346\236\220\345\217\212\350\247\243\345\206\263(Part II)/open-iscsi\351\227\256\351\242\230\345\256\232\344\275\215\345\217\212\344\277\256\345\244\215.md" create mode 100644 "LLVM Parallel Universe Project/\351\227\256\351\242\230\345\256\232\344\275\215\346\200\273\347\273\223/OSPP2024-LLVM\346\236\204\345\273\272openEuler\350\275\257\344\273\266\345\214\205\345\205\274\345\256\271\346\200\247\351\227\256\351\242\230\345\210\206\346\236\220\345\217\212\350\247\243\345\206\263(Part II)/opensc\351\227\256\351\242\230\345\256\232\344\275\215\345\217\212\344\277\256\345\244\215.md" create mode 100644 "LLVM Parallel Universe Project/\351\227\256\351\242\230\345\256\232\344\275\215\346\200\273\347\273\223/OSPP2024-LLVM\346\236\204\345\273\272openEuler\350\275\257\344\273\266\345\214\205\345\205\274\345\256\271\346\200\247\351\227\256\351\242\230\345\210\206\346\236\220\345\217\212\350\247\243\345\206\263(Part II)/proftpd\351\227\256\351\242\230\345\256\232\344\275\215\345\217\212\344\277\256\345\244\215.md" create mode 100644 "LLVM Parallel Universe Project/\351\227\256\351\242\230\345\256\232\344\275\215\346\200\273\347\273\223/OSPP2024-LLVM\346\236\204\345\273\272openEuler\350\275\257\344\273\266\345\214\205\345\205\274\345\256\271\346\200\247\351\227\256\351\242\230\345\210\206\346\236\220\345\217\212\350\247\243\345\206\263(Part II)/zziplib\351\227\256\351\242\230\345\256\232\344\275\215\345\217\212\344\277\256\345\244\215.md" diff --git "a/LLVM Parallel Universe Project/\351\227\256\351\242\230\345\256\232\344\275\215\346\200\273\347\273\223/OSPP2024-LLVM\346\236\204\345\273\272openEuler\350\275\257\344\273\266\345\214\205\345\205\274\345\256\271\346\200\247\351\227\256\351\242\230\345\210\206\346\236\220\345\217\212\350\247\243\345\206\263(Part II)/lcr\351\227\256\351\242\230\345\256\232\344\275\215\345\217\212\344\277\256\345\244\215.md" "b/LLVM Parallel Universe Project/\351\227\256\351\242\230\345\256\232\344\275\215\346\200\273\347\273\223/OSPP2024-LLVM\346\236\204\345\273\272openEuler\350\275\257\344\273\266\345\214\205\345\205\274\345\256\271\346\200\247\351\227\256\351\242\230\345\210\206\346\236\220\345\217\212\350\247\243\345\206\263(Part II)/lcr\351\227\256\351\242\230\345\256\232\344\275\215\345\217\212\344\277\256\345\244\215.md" new file mode 100644 index 0000000..c311823 --- /dev/null +++ "b/LLVM Parallel Universe Project/\351\227\256\351\242\230\345\256\232\344\275\215\346\200\273\347\273\223/OSPP2024-LLVM\346\236\204\345\273\272openEuler\350\275\257\344\273\266\345\214\205\345\205\274\345\256\271\346\200\247\351\227\256\351\242\230\345\210\206\346\236\220\345\217\212\350\247\243\345\206\263(Part II)/lcr\351\227\256\351\242\230\345\256\232\344\275\215\345\217\212\344\277\256\345\244\215.md" @@ -0,0 +1,192 @@ +来源:https://gitee.com/src-openeuler/lcr (openEuler-24.03-LTS) + +# 相关PR + +openEuler:[backport(rm attribute "visibility" before struct),add -Wno-error,fix changelog ,support clang build · Pull Request !344 · src-openEuler/lcr - Gitee.com](https://gitee.com/src-openeuler/lcr/pulls/344) + +上游社区:https://gitee.com/openeuler/lcr/pulls/332 + +# 问题一:attribute 'visibility' is ignored, place it after "struct"问题 + +## 1、问题现象 + +`[ 98s] /home/abuild/rpmbuild/BUILD/lcr-v2.1.4/src/runtime/lcrcontainer.h:43:1: error: attribute 'visibility' is ignored, place it after "struct" to apply attribute to type declaration [-Werror,-Wignored-attributes]` + +## 2、问题定位 + +### 2.1、问题复现 + +小例子复现: + +#### 第一种:__attribute__((visibility("default"))) struct A{...}; + +lcrcontainer_1.h + +```c +__attribute__((visibility("default"))) struct A { + int n; +}; +``` + +main.c + +```c +#include +#include "lcrcontainer_1.h" + +int main() { + struct A a={1}; + printf("%d\n",a.n); + return 0; +} +``` + +执行编译与运行命令,gcc正常,clang报错: + +```c +[root@localhost lcr]# gcc main.c -fvisibility=hidden -Werror -o gcc1.out +[root@localhost lcr]# ./gcc1.out +1 +[root@localhost lcr]# clang main.c -fvisibility=hidden -Werror -o clang1.out +In file included from main.c:2: +./lcrcontainer_1.h:1:16: error: attribute 'visibility' is ignored, place it after "struct" to apply attribute to type declaration [-Werror,-Wignored-attributes] + 1 | __attribute__((visibility("default"))) struct A { + | ^ +1 error generated. +``` + +#### 第二种:struct __attribute__((visibility("default"))) A{...}; + +lcrcontainer_2.h + +```c +struct __attribute__((visibility("default"))) A { + int n; +}; +``` + +执行编译与运行命令,gcc报错,clang正常: + +```c +[root@localhost lcr]# gcc main.c -fvisibility=hidden -Werror -o gcc2.out +In file included from main.c:2: +lcrcontainer_2.h:3:1: 错误:‘visibility’属性在类型上被忽略 [-Werror=attributes] + 3 | }; + | ^ +cc1:所有的警告都被当作是错误 +[root@localhost lcr]# clang main.c -fvisibility=hidden -Werror -o clang2.out +[root@localhost lcr]# ./clang2.out +1 +``` + +#### 第三种:删去__attribute__((visibility("default"))) + +lcrcontainer_3.h + +```c +#include +#include "lcrcontainer_3.h" + +int main() { + struct A a={1}; + printf("%d\n",a.n); + return 0; +} +``` + +执行编译与运行命令,gcc与clang都正常: + +```c +[root@localhost lcr]# gcc main.c -fvisibility=hidden -Werror -o gcc3.out +[root@localhost lcr]# ./gcc3.out +1 +[root@localhost lcr]# clang main.c -fvisibility=hidden -Werror -o clang3.out +[root@localhost lcr]# ./clang3.out +1 +``` + +### 2.2、关于attribute 'visibility' + +可以通过查阅GNU([Visibility - GCC Wiki (gnu.org)](https://gcc.gnu.org/wiki/Visibility))以及LLVM官方文档([LTO Visibility — Clang 20.0.0git documentation (llvm.org)](https://clang.llvm.org/docs/LTOVisibility.html))去了解。 + +#### 2.2.1、visibility的作用 + +简单来说,Visibility在编译和链接过程中控制着符号(如函数、变量和类型信息)的可见性,即它们是否可以被其他编译单元或动态共享对象(DSO)引用。以下是Visibility的几个主要作用: + +1. **优化加载时间**:通过减少不必要的符号导出,可以减少动态共享对象(DSO)的大小,从而加快加载时间。 +2. **提高代码优化**:Visibility允许编译器生成更优化的代码。例如,通过避免全局偏移表(GOT)的间接寻址,可以减少处理器流水线停顿,提高代码执行速度。 +3. **减少DSO大小**:通过减少导出的符号数量,可以显著减少DSO的大小,因为ELF的导出符号表格式占用较多空间。 +4. **降低符号冲突**:减少不必要的符号导出可以降低不同库之间符号名称冲突的可能性。 +5. **支持链接时优化(LTO)** :Visibility对于使用链接时优化特性(如全程序虚拟表优化和控制流完整性检查)至关重要,因为这些特性需要在整个程序级别上可见的类层次结构。 +6. **避免ODR违规**:Visibility属性需要在不同翻译单元之间保持一致,以避免违反C++的One Definition Rule(ODR),确保每个非内联函数或变量在整个程序中只有一个定义。 +7. **跨平台兼容性**:Visibility提供了一种机制,使得在不同平台(如Windows和POSIX系统)上进行编译的代码可以有一致的行为,这对于开发可移植的应用程序非常重要。 +8. **细粒度控制**:开发者可以细粒度地控制哪些符号应该公开,哪些应该隐藏,从而优化程序的性能和安全性。 +9. **简化构建系统**:通过使用Visibility属性,可以简化构建系统,因为可以减少对链接器脚本的依赖,从而减少维护成本。 + +#### 2.2.2、关于attribute 'visibility'在类型(type)上的应用 + +参考[Type Attributes - Using the GNU Compiler Collection (GCC)](https://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Type-Attributes.html#Type-Attributes)可知, + +`In C++, attribute visibility (see Function Attributes) can also be applied to class, struct, union and enum types. Unlike other type attributes, the attribute must appear between the initial keyword and the name of the type; it cannot appear after the body of the type.` + +即,在C++中attribute 'visibility'可以应用于class,struct,union以及enum类型,并且用法是将其置于关键字和类型名称之间,例如`struct __attribute__((visibility("default"))) A{...};` + +然而,经过上面的小例子测试可知,在C中,gcc并不支持将attribute 'visibility'应用于type,然而clang是支持的,这就是问题的根源 + +### 2.3、问题总结及根因确认 + +在C++中attribute 'visibility'可以应用于class,struct,union以及enum类型,并且用法是将其置于关键字和类型名称之间,在C中,gcc并不支持将attribute 'visibility'应用于type,然而clang是支持的。所以对于struct及attribute 'visibility'的顺序,无论是谁前谁后,必定有一个编译器报错,唯一的二者兼顾方法是删去__attribute__ ((visibility("default")))。 + +## 3、问题修改建议 + +想要兼顾gcc和clang,目前能想到的方法只能是C语言中不将attribute 'visibility'应用于type。参考:[https://gitee.com/openeuler/lcr/pulls/332](https://gitee.com/openeuler/lcr/pulls/332) + +# 问题二:bad date in %changelog问题 + +## 1、问题现象 + +出自:https://gitee.com/src-openeuler/lcr (openEuler-24.03-LTS) + + +`bad date in %changelog: Tue June 11 2024 jikai - 2.1.4-8` + +## 2、changelog日期写法规范 + +规范写法是: + +星期(简写) 月(简写) 日 年 名称 邮箱 - 版本 + +例如:`Tue Jun 11 2024 jikai - 2.1.4-8` + +以下是星期与月份的规范简写: + +一月:January 简写:Jan +二月:February 简写:Feb +三月:March 简写:Mar +四月:April 简写:Apr +五月:May 简写:May +六月:June 简写:Jun +七月:July 简写:Jul +八月:August 简写:Aug +九月:September 简写:Sep +十月:October 简写:Oct +十一月:November 简写:Nov +十二月:December 简写:Dec + +星期一:Monday 简写:Mon +星期二:Tuesday 简写:Tue +星期三:Wednesday 简写:Wed +星期四:Thursday 简写:Thu +星期五:Friday 简写:Fri +星期六:Saturday 简写:Sat +星期日:Sunday 简写:Sun + +## 3、修改建议 + +June改为Jun + +# LLVM兼容性问题总结 + +lcr包中的LLVM兼容性问题主要体现在问题二。 + +问题二是由于clang与gcc对于C++中的'visibility'特性用于TYPE(类型)时的支持标准不统一。解决方法为,在不影响功能的情况下,暂时对类型不使用该特性。 \ No newline at end of file diff --git "a/LLVM Parallel Universe Project/\351\227\256\351\242\230\345\256\232\344\275\215\346\200\273\347\273\223/OSPP2024-LLVM\346\236\204\345\273\272openEuler\350\275\257\344\273\266\345\214\205\345\205\274\345\256\271\346\200\247\351\227\256\351\242\230\345\210\206\346\236\220\345\217\212\350\247\243\345\206\263(Part II)/libevent\351\227\256\351\242\230\345\256\232\344\275\215\345\217\212\344\277\256\345\244\215.md" "b/LLVM Parallel Universe Project/\351\227\256\351\242\230\345\256\232\344\275\215\346\200\273\347\273\223/OSPP2024-LLVM\346\236\204\345\273\272openEuler\350\275\257\344\273\266\345\214\205\345\205\274\345\256\271\346\200\247\351\227\256\351\242\230\345\210\206\346\236\220\345\217\212\350\247\243\345\206\263(Part II)/libevent\351\227\256\351\242\230\345\256\232\344\275\215\345\217\212\344\277\256\345\244\215.md" new file mode 100644 index 0000000..0ba0888 --- /dev/null +++ "b/LLVM Parallel Universe Project/\351\227\256\351\242\230\345\256\232\344\275\215\346\200\273\347\273\223/OSPP2024-LLVM\346\236\204\345\273\272openEuler\350\275\257\344\273\266\345\214\205\345\205\274\345\256\271\346\200\247\351\227\256\351\242\230\345\210\206\346\236\220\345\217\212\350\247\243\345\206\263(Part II)/libevent\351\227\256\351\242\230\345\256\232\344\275\215\345\217\212\344\277\256\345\244\215.md" @@ -0,0 +1,345 @@ +来源:https://gitee.com/src-openeuler/libevent (openEuler-24.03-LTS) + +# 相关PR + +openEuler:[Fix function undeclared,incompatible pointer and parameter lack in 'add-testcases-for-event.c-apis.patch',support clang build · Pull Request !74 · src-openEuler/libevent - Gitee.com](https://gitee.com/src-openeuler/libevent/pulls/74) + +上游社区:不涉及 + +# 问题一:call to undeclared function问题 + +## 1、问题现象 + +`[ 705s] test/regress.c:3689:12: error: call to undeclared function 'event_base_start_iocp_'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]` + +`[ 705s] test/regress.c:3691:2: error: call to undeclared function 'event_base_stop_iocp_'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]` + +## 2、问题定位 + +### 2.1、问题定位分析 + +[add-testcases-for-event.c-apis.patch](https://gitee.com/src-openeuler/libevent/blob/6fd712438bafd9eafdb3cf3b3e9d66913378b2a3/add-testcases-for-event.c-apis.patch)是对regress.c的patch,该patch中调用了函数`event_base_start_iocp_`与`event_base_stop_iocp_`但忘记了#include其所在的头文件"iocp-internal.h" + +### 2.2 gcc与clang对于调用未声明函数的差异处理 + +对于调用未声明的函数,c语言曾有一种叫隐式声明的特性,能规避编译构建的报错,然而该特性在C99以后已经被移除,clang17默认执行gnu17标准(见[官方文档](https://clang.llvm.org/docs/UsersManual.html#extensions-supported-by-clang)),因此不支持。 + +![gcc遇到未声明函数时的表现](https://foruda.gitee.com/images/1725034630272359183/577103f3_13034847.png "屏幕截图") + +### 2.3、问题总结及根因确认 + +[add-testcases-for-event.c-apis.patch](https://gitee.com/src-openeuler/libevent/blob/6fd712438bafd9eafdb3cf3b3e9d66913378b2a3/add-testcases-for-event.c-apis.patch)是对regress.c的patch,该patch中调用了函数`event_base_start_iocp_`与`event_base_stop_iocp_`但忘记了#include其所在的头文件"iocp-internal.h",gcc对于调用未声明函数会使用隐式声明,仅仅warning,而clang会报error + +## 3、修改建议 + +补充打一个patch,在regress.c中#include "iocp-internal.h" + +# 问题二:call, expected 2, have 1问题 + +## 1、问题现象 + +```c +[ 142s] test/regress.c:3691:39: error: call, expected 2, have 1 +[ 142s] 3691 | int res = event_base_start_iocp_(base); +[ 142s] | ~~~~~~~~~~~~~~~~~~~~~~ ^ +[ 142s] ./iocp-internal.h:197:5: note: 'event_base_start_iocp_' declared here +[ 142s] 197 | int event_base_start_iocp_(struct event_base *base, int n_cpus); +[ 142s] | ^ +``` + +## 2、问题定位 + +### 2.1、问题定位分析 + +错误出处:`int res = event_base_start_iocp_(base);` + +查找`event_base_start_iocp_`函数的定义,在event.c中: + +```c +int +event_base_start_iocp_(struct event_base *base, int n_cpus) +{ +#ifdef _WIN32 + if (base->iocp) + return 0; + base->iocp = event_iocp_port_launch_(n_cpus); + if (!base->iocp) { + event_warnx("%s: Couldn't launch IOCP", __func__); + return -1; + } + return 0; +#else + return -1; +#endif +} +``` + +可见,该函数要求两个参数,而该处错误只传入了一个参数 + +![输入图片说明](https://foruda.gitee.com/images/1725034687466247382/59733cb3_13034847.png "屏幕截图") + +综合其他所有地方的用处来看,参数改为(base,0)是保险的修复方法 + +### 2.2、问题总结及根因确认 + +调用函数时,传入的参数的数量不符合预期,要求2,实际1 + +## 3、修改建议 + +使用合理的参数补全参数个数要求,即将int res = event_base_start_iocp_(base);改为int res = event_base_start_iocp_(base,0); + +# 问题三:错误调用导致的incompatible function pointer types问题 + +## 1、问题现象 + +```c +[ 140s] test/regress.c:3707:2: error: incompatible function pointer types initializing 'testcase_fn' (aka 'void (*)(void *)') with an expression of type 'void (void)' [-Wincompatible-function-pointer-types] +[ 140s] 3707 | BASIC(event_config_set_max_dispatch_interval, TT_FORK|TT_NEED_BASE), +[ 140s] | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +[ 140s] test/regress.h:105:11: note: expanded from macro 'BASIC' +[ 140s] 105 | { #name, test_## name, flags, &basic_setup, NULL } +[ 140s] | ^~~~~~~~~~~~ +[ 140s] :168:1: note: expanded from here +[ 140s] 168 | test_event_config_set_max_dispatch_interval +[ 140s] | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +[ 140s] test/regress.c:3708:2: error: incompatible function pointer types initializing 'testcase_fn' (aka 'void (*)(void *)') with an expression of type 'void (void)' [-Wincompatible-function-pointer-types] +[ 140s] 3708 | BASIC(event_config_set_num_cpus_hint, TT_FORK|TT_NEED_BASE), +[ 140s] | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +[ 140s] test/regress.h:105:11: note: expanded from macro 'BASIC' +[ 140s] 105 | { #name, test_## name, flags, &basic_setup, NULL } +[ 140s] | ^~~~~~~~~~~~ +[ 140s] :170:1: note: expanded from here +[ 140s] 170 | test_event_config_set_num_cpus_hint +[ 140s] | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +[ 140s] 2 errors generated. +``` + +## 2、问题定位 + +### 2.1、问题定位分析 + +错误定位: + +```c +struct testcase_t main_testcases[] = { ++ /* event.c api tests */ ++ BASIC(event_base_del_virtual_, TT_FORK|TT_NEED_BASE), ++ BASIC(event_deferred_cb_set_priority_, TT_FORK|TT_NEED_BASE), ++ BASIC(event_callback_init_, TT_FORK|TT_NEED_BASE), ++ BASIC(event_del_noblock, TT_FORK|TT_NEED_BASE), ++ BASIC(event_del_block, TT_FORK|TT_NEED_BASE), ++ BASIC(event_get_events, TT_FORK|TT_NEED_BASE|TT_NEED_SOCKETPAIR), ++ BASIC(event_config_set_max_dispatch_interval, TT_FORK|TT_NEED_BASE), ++ BASIC(event_config_set_num_cpus_hint, TT_FORK|TT_NEED_BASE), ++ BASIC(event_base_stop_iocp_, TT_FORK|TT_NEED_BASE), +``` + +main_testcases[]的元素类型为struct testcase_t,而struct testcase_t的定义为: + +```c +/** A single test-case that you can run. */ +struct testcase_t { + const char *name; /**< An identifier for this case. */ + testcase_fn fn; /**< The function to run to implement this case. */ + unsigned long flags; /**< Bitfield of TT_* flags. */ + const struct testcase_setup_t *setup; /**< Optional setup/cleanup fns*/ + void *setup_data; /**< Extra data usable by setup function */ +}; +``` + +错误就出现在第二个元素testcase_fn fn,其类型定义为: + +```c +typedef void (*testcase_fn)(void *); +``` + +也就是说,要求类型为void\*(void\*) + +我们再来看看BASIC是什么,他是一个宏,定义如下,同时还需要注意,与他一同定义的LEGACY宏 + +```c +#define BASIC(name,flags) \ + { #name, test_## name, flags, &basic_setup, NULL } + +#define LEGACY(name,flags) \ + { #name, run_legacy_test_fn, flags|TT_LEGACY, &legacy_setup, \ + test_## name } +``` + +我们再回来看一开始报错的地方 + +```c ++ BASIC(event_config_set_max_dispatch_interval, TT_FORK|TT_NEED_BASE), ++ BASIC(event_config_set_num_cpus_hint, TT_FORK|TT_NEED_BASE), +``` + +也就是说,问题出在函数test_event_config_set_max_dispatch_interval和test_event_config_set_num_cpus_hint的类型不符合void\*(void\*)的要求,那我们来看看这两个函数的定义: + +```c ++static void ++test_event_config_set_max_dispatch_interval(void) ++{ ++ struct event_config *cfg = NULL; ++ struct timeval tv; ++ int max_dispatch_cbs = 100; ++ int min_priority = 2; ++ ++ evutil_timerclear(&tv); ++ tv.tv_sec = 3; ++ tv.tv_usec = 0; ++ ++ cfg = event_config_new(); ++ event_config_set_max_dispatch_interval(cfg, &tv, max_dispatch_cbs, min_priority); ++ ++ tt_assert(max_dispatch_cbs == cfg->max_dispatch_callbacks); ++ tt_assert(min_priority == cfg->limit_callbacks_after_prio); ++ tt_assert(3 == cfg->max_dispatch_interval.tv_sec); ++ tt_assert(0 == cfg->max_dispatch_interval.tv_usec); ++end: ++ if (cfg) ++ event_config_free(cfg); ++} ++ ++static void ++test_event_config_set_num_cpus_hint(void) ++{ ++ struct event_config *cfg = NULL; ++ int n_cpus = 4; ++ ++ cfg = event_config_new(); ++ event_config_set_num_cpus_hint(cfg, 4); ++ tt_assert(4 == cfg->n_cpus_hint); ++end: ++ if (cfg) ++ event_config_free(cfg); ++} +``` + +可见他们的类型是void(void) + +除了这两个函数之外,其他BASIC宏传入的函数(没有被报错的)的类型例如下: + +```c ++static void ++test_event_del_noblock(void *ptr) { ++ struct basic_test_data *data = ptr; ++ struct event_base *base = data->base; ++ struct timeval tv; ++ struct event ev; ++ int count = 0; ++ int res_del = 0; ++ ++ evutil_timerclear(&tv); ++ tv.tv_usec = 10000; ++ ++ event_assign(&ev, base, -1, EV_TIMEOUT|EV_PERSIST, ++ timeout_cb, &count); ++ event_add(&ev, &tv); ++ ++ res_del = event_del_noblock(&ev); ++ tt_int_op(res_del, ==, 0); ++end: ++ ; ++} ++ +``` + +修改方法显然不能直接改参数要求,如果将void改为void*,那么凭空要求传入一个参数,显然不对,那么还有其他方法吗?我在上游社区没有发现类似的issue,然而,我们可以去找找看,对于void(void)类型的函数,上游社区是如何将其传入testcase的,我们大致看一部分: + +```c +struct testcase_t main_testcases[] = { + /* Some converted-over tests */ + { "methods", test_methods, TT_FORK, NULL, NULL }, + { "version", test_version, 0, NULL, NULL }, + BASIC(base_features, TT_FORK|TT_NO_LOGS), + { "base_environ", test_base_environ, TT_FORK, NULL, NULL }, + + BASIC(event_base_new, TT_FORK|TT_NEED_SOCKETPAIR), + BASIC(free_active_base, TT_FORK|TT_NEED_SOCKETPAIR), + + BASIC(manipulate_active_events, TT_FORK|TT_NEED_BASE), + BASIC(event_new_selfarg, TT_FORK|TT_NEED_BASE), + BASIC(event_assign_selfarg, TT_FORK|TT_NEED_BASE), + BASIC(event_base_get_num_events, TT_FORK|TT_NEED_BASE), + BASIC(event_base_get_max_events, TT_FORK|TT_NEED_BASE), + BASIC(evmap_invalid_slots, TT_FORK|TT_NEED_BASE), + + BASIC(bad_assign, TT_FORK|TT_NEED_BASE|TT_NO_LOGS), + BASIC(bad_reentrant, TT_FORK|TT_NEED_BASE|TT_NO_LOGS), + BASIC(active_later, TT_FORK|TT_NEED_BASE|TT_NEED_SOCKETPAIR|TT_RETRIABLE), + BASIC(event_remove_timeout, TT_FORK|TT_NEED_BASE|TT_NEED_SOCKETPAIR), + + /* These are still using the old API */ + LEGACY(persistent_timeout, TT_FORK|TT_NEED_BASE), + { "persistent_timeout_jump", test_persistent_timeout_jump, TT_FORK|TT_NEED_BASE, &basic_setup, NULL }, + { "persistent_active_timeout", test_persistent_active_timeout, + TT_FORK|TT_NEED_BASE|TT_RETRIABLE, &basic_setup, NULL }, + LEGACY(priorities, TT_FORK|TT_NEED_BASE), + BASIC(priority_active_inversion, TT_FORK|TT_NEED_BASE), + { "common_timeout", test_common_timeout, TT_FORK|TT_NEED_BASE|TT_RETRIABLE, + &basic_setup, NULL }, + + /* These legacy tests may not all need all of these flags. */ + LEGACY(simpleread, TT_ISOLATED), + LEGACY(simpleread_multiple, TT_ISOLATED), + LEGACY(simplewrite, TT_ISOLATED), + { "simpleclose_rw", test_simpleclose_rw, TT_FORK, &basic_setup, NULL }, + /* simpleclose */ + { "simpleclose_close", test_simpleclose, + TT_FORK|TT_NEED_SOCKETPAIR|TT_NEED_BASE, + &basic_setup, (void *)"close" }, + { "simpleclose_shutdown", test_simpleclose, + TT_FORK|TT_NEED_SOCKETPAIR|TT_NEED_BASE, + &basic_setup, (void *)"shutdown" }, +``` + +可见,除了BASIC,有时也用LEGACY,那么什么时候用BASIC,什么时候用LEGACY呢?本人查看了上文的所有testcase中的测试函数,发现BASIC用于传入void(void*),而LEGACY用于传入void(void),全部贴上来篇幅过长,因此此处只放一个例子: + +```c +LEGACY(persistent_timeout, TT_FORK|TT_NEED_BASE) +``` + +```c +static void +test_persistent_timeout(void) +{ + struct timeval tv; + struct event ev; + int count = 0; + + evutil_timerclear(&tv); + tv.tv_usec = 10000; + + event_assign(&ev, global_base, -1, EV_TIMEOUT|EV_PERSIST, + periodic_timeout_cb, &count); + event_add(&ev, &tv); + + event_dispatch(); + + event_del(&ev); +} +``` + +### 2.2、问题总结及根因确认 + +[add-testcases-for-event.c-apis.patch](https://gitee.com/src-openeuler/libevent/blob/6fd712438bafd9eafdb3cf3b3e9d66913378b2a3/add-testcases-for-event.c-apis.patch)该patch试图增加对一些函数的testcase,对于void(void)类型的函数,正确的方法是调用LEGACY宏将函数加入测试行列,错误在于调用了BASIC宏(其用于void(void*)类型的函数) + +## 3、修改建议 + +把报错两处的BASIC改为LEGACY + +# 问题四:autoreconf: command not found问题 + +## 1、问题现象 + +出自:https://gitee.com/src-openeuler/libevent (openEuler-24.03-LTS) + +`[ 119s] /var/tmp/rpm-tmp.PicZ3O: line 47: autoreconf: command not found` + +## 2、问题成因 + +rpm打包时使用了autoreconf命令,但是在BuildRequires中没有写该命令的软件依赖 + +## 3、修改建议 + +在spec文件的BuildRequires中添加autoconf automake libtool \ No newline at end of file diff --git "a/LLVM Parallel Universe Project/\351\227\256\351\242\230\345\256\232\344\275\215\346\200\273\347\273\223/OSPP2024-LLVM\346\236\204\345\273\272openEuler\350\275\257\344\273\266\345\214\205\345\205\274\345\256\271\346\200\247\351\227\256\351\242\230\345\210\206\346\236\220\345\217\212\350\247\243\345\206\263(Part II)/libreswan\351\227\256\351\242\230\345\256\232\344\275\215\345\217\212\344\277\256\345\244\215.md" "b/LLVM Parallel Universe Project/\351\227\256\351\242\230\345\256\232\344\275\215\346\200\273\347\273\223/OSPP2024-LLVM\346\236\204\345\273\272openEuler\350\275\257\344\273\266\345\214\205\345\205\274\345\256\271\346\200\247\351\227\256\351\242\230\345\210\206\346\236\220\345\217\212\350\247\243\345\206\263(Part II)/libreswan\351\227\256\351\242\230\345\256\232\344\275\215\345\217\212\344\277\256\345\244\215.md" new file mode 100644 index 0000000..deb9624 --- /dev/null +++ "b/LLVM Parallel Universe Project/\351\227\256\351\242\230\345\256\232\344\275\215\346\200\273\347\273\223/OSPP2024-LLVM\346\236\204\345\273\272openEuler\350\275\257\344\273\266\345\214\205\345\205\274\345\256\271\346\200\247\351\227\256\351\242\230\345\210\206\346\236\220\345\217\212\350\247\243\345\206\263(Part II)/libreswan\351\227\256\351\242\230\345\256\232\344\275\215\345\217\212\344\277\256\345\244\215.md" @@ -0,0 +1,117 @@ +来源:https://gitee.com/src-openeuler/libreswan (openEuler-24.03-LTS) + +# 相关PR + +openEuler:[Fix prototype deprecated and expression result unused,as well rewrite spec to support clang build · Pull Request !99 · src-openEuler/libreswan - Gitee.com](https://gitee.com/src-openeuler/libreswan/pulls/99) + +上游社区:https://github.com/libreswan/libreswan/pull/1791 + +# 问题一:function definition without a prototype is deprecated问题 + +## 1、问题现象 + +`a function definition without a prototype is deprecated in all versions of C and is not supported in C2x [-Werror,-Wdeprecated-non-prototype]` + +## 2、问题定位 + +有两处使用的函数原型定义方式(形参的类型单独在括号外说明)已经被弃用,一处在上游有commit + +[building: prototype maskcount() definition; clang-16 · libreswan/libreswan@e52a0af (github.com)](https://github.com/libreswan/libreswan/commit/e52a0af61990754b26a2825fb775fd5d1680112b) + +另一处找不到上游对应的文件,但也可以用同样的改法 + +```c +size_t /* length required for full conversion */ +ultot(n, base, dst, dstlen) +unsigned long n; +int base; +char *dst; /* need not be valid if dstlen is 0 */ +size_t dstlen; +{ + ... +} + +``` + +改为 + +```c +size_t /* length required for full conversion */ +ultot(unsigned long n, int base, char *dst, size_t dstlen) + /* char *dst need not be valid if dstlen is 0 */ +{ + ... +} +``` + +## 3、修改建议 + +将函数原型定义方式改为现在支持的形式。 + +# 问题二:语句误用","而非";"结尾而引起的expression result unused问题 + +## 1、问题现象 + + +```c +[ 97s] /home/abuild/rpmbuild/BUILD/libreswan-4.15/lib/libswan/ckaid.c:85:2: error: expression result unused [-Werror,-Wunused-value] +[ 97s] 85 | pexpect(ckaid.len == nss_ckaid_len); +[ 97s] | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +[ 97s] ../../include/lswlog.h:489:29: note: expanded from macro 'pexpect' +[ 97s] 489 | #define pexpect(ASSERTION) PEXPECT(&global_logger, ASSERTION) +[ 97s] | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +[ 97s] ../../include/lswlog.h:486:3: note: expanded from macro 'PEXPECT' +[ 97s] 486 | assertion__; /* result */ \ +[ 97s] | ^~~~~~~~~~~ +[ 97s] 1 error generated. +``` + +## 2、问题定位 + +### 2.1、问题定位分析 + +* 问题定位: + +```c +ckaid_t ckaid_from_secitem(const SECItem *const nss_ckaid) +{ + size_t nss_ckaid_len = nss_ckaid->len; + /* ckaid = { .len = min(...), } barfs with gcc 11.2.1 */ + ckaid_t ckaid = {0}; + /* should not be truncated but can be */ + ckaid.len = min(nss_ckaid_len, sizeof(ckaid.ptr/*array*/)), + pexpect(ckaid.len == nss_ckaid_len); + memmove(ckaid.ptr, nss_ckaid->data, ckaid.len); + return ckaid; +} +``` + +发现其实是因为ckaid.len = min(nss_ckaid_len, sizeof(ckaid.ptr/\*array *** /)),结尾是逗号,而不是分号 + +在上游提交了pr:https://github.com/libreswan/libreswan/pull/1791修正了问题 + +### 2.2、问题总结及根因确认 + +语句误用","而非";"结尾,编译器没有识别出这个错误,而是错误地将其识别成了expression result unused错误,gcc对于这种类型的错误可能较为宽松,导致gcc编译时没有发现这个错误。 + +## 3、修改建议 + +ckaid.len = min(nss_ckaid_len, sizeof(ckaid.ptr/\*array *** /)),结尾的","改为";" + +# 问题三:unknown warning option问题 + +## 1、问题现象 + + +```c +[ 537s] error: unknown warning option '-Wno-maybe-uninitialized'; did you mean '-Wno-uninitialized'? [-Werror,-Wunknown-warning-option] +[ 537s] error: unknown warning option '-Wno-lto-type-mismatch'; did you mean '-Wno-selector-type-mismatch'? [-Werror,-Wunknown-warning-option] +``` + +## 2、问题分析 + +`-Wno-maybe-uninitialized`和`-Wno-lto-type-mismatch`是gcc的编译器选项,而查阅资料得知,clang没有这两个选项 + +## 3、修改建议 + +clang构建时,不设置这两个选项 \ No newline at end of file diff --git "a/LLVM Parallel Universe Project/\351\227\256\351\242\230\345\256\232\344\275\215\346\200\273\347\273\223/OSPP2024-LLVM\346\236\204\345\273\272openEuler\350\275\257\344\273\266\345\214\205\345\205\274\345\256\271\346\200\247\351\227\256\351\242\230\345\210\206\346\236\220\345\217\212\350\247\243\345\206\263(Part II)/libseccomp\351\227\256\351\242\230\345\256\232\344\275\215\345\217\212\344\277\256\345\244\215.md" "b/LLVM Parallel Universe Project/\351\227\256\351\242\230\345\256\232\344\275\215\346\200\273\347\273\223/OSPP2024-LLVM\346\236\204\345\273\272openEuler\350\275\257\344\273\266\345\214\205\345\205\274\345\256\271\346\200\247\351\227\256\351\242\230\345\210\206\346\236\220\345\217\212\350\247\243\345\206\263(Part II)/libseccomp\351\227\256\351\242\230\345\256\232\344\275\215\345\217\212\344\277\256\345\244\215.md" new file mode 100644 index 0000000..cf670c8 --- /dev/null +++ "b/LLVM Parallel Universe Project/\351\227\256\351\242\230\345\256\232\344\275\215\346\200\273\347\273\223/OSPP2024-LLVM\346\236\204\345\273\272openEuler\350\275\257\344\273\266\345\214\205\345\205\274\345\256\271\346\200\247\351\227\256\351\242\230\345\210\206\346\236\220\345\217\212\350\247\243\345\206\263(Part II)/libseccomp\351\227\256\351\242\230\345\256\232\344\275\215\345\217\212\344\277\256\345\244\215.md" @@ -0,0 +1,62 @@ +来源:https://gitee.com/src-openeuler/libseccomp (openEuler-24.03-LTS) + +# 相关PR + +openEuler:[fix undefined behavior in scmp_bpf_sim.c causing issues when building with clang · Pull Request !50 · src-openEuler/libseccomp - Gitee.com](https://gitee.com/src-openeuler/libseccomp/pulls/50) + +上游社区:不涉及 + +# 问题:undefined behavior in scmp\_bpf\_sim.c causing issues问题 + +## 1、问题现象 + + +```c +[ 377s] Regression Test Summary +[ 377s] tests run: 5761 +[ 377s] tests skipped: 122 +[ 377s] tests passed: 4615 +[ 377s] tests failed: 1146 +[ 377s] tests errored: 0 +``` + +然后发现,这些tests failed都是因为bpf_sim的result不正确 + +```c +[ 340s] Test 42-sim-adv_chains%%003-00001 result: FAILURE bpf_sim resulted in KILL +[ 340s] Test 42-sim-adv_chains%%004-00001 result: SUCCESS +[ 340s] Test 42-sim-adv_chains%%005-00001 result: FAILURE bpf_sim resulted in ALLOW +[ 341s] Test 42-sim-adv_chains%%006-00001 result: SUCCESS +[ 341s] Test 42-sim-adv_chains%%007-00001 result: SUCCESS +[ 341s] Test 42-sim-adv_chains%%008-00001 result: FAILURE bpf_sim resulted in TRAP +[ 341s] Test 42-sim-adv_chains%%009-00001 result: SUCCESS +[ 341s] Test 42-sim-adv_chains%%010-00001 result: SUCCESS +[ 341s] Test 42-sim-adv_chains%%011-00001 result: SUCCESS +[ 341s] Test 42-sim-adv_chains%%012-00001 result: SUCCESS +[ 341s] Test 42-sim-adv_chains%%013-00001 result: FAILURE bpf_sim resulted in KILL +[ 341s] Test 42-sim-adv_chains%%014-00001 result: FAILURE bpf_sim resulted in KILL +``` + +# 2、问题定位 + +问题出在`scmp_bpf_sim.c`中的 + +```c +uint32_t val = *((uint32_t *)&sys_data_b[k]); +``` + +这行代码试图通过将`sys_data_b[k]`的地址转换为`uint32_t`指针,然后解引用该指针来获取一个`uint32_t`类型的值。这里的问题在于如果`sys_data_b`的元素不是以`uint32_t`对齐的,这种直接解引用会导致未定义行为,因为不是所有的硬件平台都支持不对齐的内存访问。 + +# 3、修改建议 + +修改后的代码: + +```c +uint32_t val; +memcpy(&val, &sys_data_b[k], sizeof(val)); +``` + +使用`memcpy`函数从`sys_data_b`数组的第`k`个元素的地址复制`sizeof(val)`个字节到`val`的地址。这种方式的好处包括: + +1. **类型安全**:`memcpy`不关心数据的类型,它只是简单地复制字节,因此不会因为类型不对齐而引发问题。 +2. **可移植性**:`memcpy`是标准库函数,它在所有平台上的行为都是一致的,因此这段代码在不同的编译器和硬件平台上都能可靠地工作。 \ No newline at end of file diff --git "a/LLVM Parallel Universe Project/\351\227\256\351\242\230\345\256\232\344\275\215\346\200\273\347\273\223/OSPP2024-LLVM\346\236\204\345\273\272openEuler\350\275\257\344\273\266\345\214\205\345\205\274\345\256\271\346\200\247\351\227\256\351\242\230\345\210\206\346\236\220\345\217\212\350\247\243\345\206\263(Part II)/libsecret\351\227\256\351\242\230\345\256\232\344\275\215\345\217\212\344\277\256\345\244\215.md" "b/LLVM Parallel Universe Project/\351\227\256\351\242\230\345\256\232\344\275\215\346\200\273\347\273\223/OSPP2024-LLVM\346\236\204\345\273\272openEuler\350\275\257\344\273\266\345\214\205\345\205\274\345\256\271\346\200\247\351\227\256\351\242\230\345\210\206\346\236\220\345\217\212\350\247\243\345\206\263(Part II)/libsecret\351\227\256\351\242\230\345\256\232\344\275\215\345\217\212\344\277\256\345\244\215.md" new file mode 100644 index 0000000..8d838d9 --- /dev/null +++ "b/LLVM Parallel Universe Project/\351\227\256\351\242\230\345\256\232\344\275\215\346\200\273\347\273\223/OSPP2024-LLVM\346\236\204\345\273\272openEuler\350\275\257\344\273\266\345\214\205\345\205\274\345\256\271\346\200\247\351\227\256\351\242\230\345\210\206\346\236\220\345\217\212\350\247\243\345\206\263(Part II)/libsecret\351\227\256\351\242\230\345\256\232\344\275\215\345\217\212\344\277\256\345\244\215.md" @@ -0,0 +1,83 @@ +来源:https://gitee.com/src-openeuler/libsecret (openEuler-24.03-LTS) + +# 相关PR + +openEuler:[fix `incompatible function pointer types passing`errors in test-vala-unstable.vala and test-vala-lang.vala · Pull Request !23 · src-openEuler/libsecret - Gitee.com](https://gitee.com/src-openeuler/libsecret/pulls/23) + +上游社区:https://gitlab.gnome.org/GNOME/libsecret/-/issues/95 + +# 问题一:错误调用导致的incompatible function pointer types问题 + +## 1、问题现象 + +```c +[ 103s] libsecret/test-vala-unstable.p/test-vala-unstable.c:129:59: error: incompatible function pointer types passing 'void (gpointer)' (aka 'void (void *)') to parameter of type 'GTestDataFunc' (aka 'void (*)(const void *)') [-Wincompatible-function-pointer-types] +``` + +## 2.1、问题定位 + +在test-vala-unstable.vala和test-vala-lang.vala中,错误性质相同,这里以test-vala-unstable.vala为例: + +```vala +private void test_read_alias () { + try { + var service = Secret.Service.get_sync(Secret.ServiceFlags.NONE); + var path = service.read_alias_dbus_path_sync("default", null); + GLib.assert (path != null); + } catch ( GLib.Error e ) { + GLib.error (e.message); + } +} + +private static int main (string[] args) { + GLib.Test.init (ref args); + + try { + MockService.start ("mock-service-normal.py"); + } catch ( GLib.Error e ) { + GLib.error ("Unable to start mock service: %s", e.message); + } + + GLib.Test.add_data_func ("/vala/unstable/read-alias", test_read_alias); + + var res = GLib.Test.run (); + Secret.Service.disconnect (); + MockService.stop (); + return res; +} +``` + +而GLib.Test.add_data_func实际上是调用glib库中的: + +```c +void g_test_add_data_func (const char *testpath, + gconstpointer test_data, + GTestDataFunc test_func); +``` + +GTestDataFunc的类型定义为: + +```c +void (*)(gconstpointer) +``` + +而GLib.Test.add_func调用的是: + +```c +void g_test_add_func (const char *testpath, + GTestFunc test_func); +``` + +GTestFunc的类型定义为: + +```c +void (*)() +``` + +## 2.2、问题总结及根因确认 + +使用GLib.Test.add\_data\_func时,参数要求为(const char \*testpath,gconstpointer test\_data,GTestDataFunc test\_func),实际为(const char \*testpath,GTestFunc test\_func),参数不匹配。 + +## 3、修改建议 + +改为使用GLib.Test.add\_func,其参数要求为(const char \*testpath,GTestFunc test\_func),符合实际传入的参数 \ No newline at end of file diff --git "a/LLVM Parallel Universe Project/\351\227\256\351\242\230\345\256\232\344\275\215\346\200\273\347\273\223/OSPP2024-LLVM\346\236\204\345\273\272openEuler\350\275\257\344\273\266\345\214\205\345\205\274\345\256\271\346\200\247\351\227\256\351\242\230\345\210\206\346\236\220\345\217\212\350\247\243\345\206\263(Part II)/lvm2\351\227\256\351\242\230\345\256\232\344\275\215\345\217\212\344\277\256\345\244\215.md" "b/LLVM Parallel Universe Project/\351\227\256\351\242\230\345\256\232\344\275\215\346\200\273\347\273\223/OSPP2024-LLVM\346\236\204\345\273\272openEuler\350\275\257\344\273\266\345\214\205\345\205\274\345\256\271\346\200\247\351\227\256\351\242\230\345\210\206\346\236\220\345\217\212\350\247\243\345\206\263(Part II)/lvm2\351\227\256\351\242\230\345\256\232\344\275\215\345\217\212\344\277\256\345\244\215.md" new file mode 100644 index 0000000..d6a77aa --- /dev/null +++ "b/LLVM Parallel Universe Project/\351\227\256\351\242\230\345\256\232\344\275\215\346\200\273\347\273\223/OSPP2024-LLVM\346\236\204\345\273\272openEuler\350\275\257\344\273\266\345\214\205\345\205\274\345\256\271\346\200\247\351\227\256\351\242\230\345\210\206\346\236\220\345\217\212\350\247\243\345\206\263(Part II)/lvm2\351\227\256\351\242\230\345\256\232\344\275\215\345\217\212\344\277\256\345\244\215.md" @@ -0,0 +1,67 @@ +来源:https://gitee.com/src-openeuler/lvm2 (openEuler-24.03-LTS) + +# 相关PR + +openEuler:[fix 2 undeclared functions,and changelog format,support clang build · Pull Request !183 · src-openEuler/lvm2 - Gitee.com](https://gitee.com/src-openeuler/lvm2/pulls/183) + +上游:不涉及 + +# 问题一:call to undeclared function问题 + +## 1、问题现象 + +```bash +[ 104s] libdm-common.c:137:3: error: call to undeclared function 'vsyslog'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] +[ 104s] 137 | vsyslog(level, f, copyap); +[ 104s] | ^ +[ 122s] device/dev-cache.c:1021:7: error: call to undeclared function 'gettimeofday'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] +[ 122s] 1021 | if (!gettimeofday(&end, NULL)) { +[ 122s] | ^ +[ 122s] device/dev-cache.c:1041:8: error: call to undeclared function 'gettimeofday'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] +[ 122s] 1041 | ret = gettimeofday(&start,NULL); +[ 122s] | ^ +[ 122s] 2 errors generated. +``` + +## 2、问题定位 + +[0010-bugfix-lvm2-fix-the-reuse-of-va_list.patch](https://gitee.com/src-openeuler/lvm2/blob/fb6a5827c6c2fbfb26e6e531fc29da497745de7d/0010-bugfix-lvm2-fix-the-reuse-of-va_list.patch)在libdm-common.c中调用vsyslog函数,但是没有包含其头文件syslog.h + +[0012-lvm-code-reduce-cyclomatic-complexity.patch](https://gitee.com/src-openeuler/lvm2/blob/fb6a5827c6c2fbfb26e6e531fc29da497745de7d/0012-lvm-code-reduce-cyclomatic-complexity.patch)在dev-cache.c中调用gettimeofday函数,但是没有包含其头文件sys/time.h + +## 3、修改建议 + +在libdm-common.c中#include + +在dev-cache.c中#include + +# 问题二:%changelog entries must start with \*问题 + +## 1、问题现象 + +`[ 90s] error: %changelog not in descending chronological order` + +## 2、问题定位 + +### 2.1、问题定位分析 + +```c +* Wed Nov 22 2023 wangxiaomeng - 8:2.03.22-3 +- lvmlockd: add suport for loongarch64 + +* Tue Dec 19 2023 wangzhiqiang - 8:2.03.22-2 +- dm-event: release buffer on dm_event_get_version + +* Fri Nov 03 2023 liweigang - 8:2.03.22-1 +- update to version 2.03.22 +``` + +问题出在[lvmlockd: add suport for loongarch64 · dee4806 · 云沧/lvm2 - Gitee.com](https://gitee.com/yuncang123/lvm2/commit/dee4806fb29598db7cbd4d9abe56db348cc79baa)这个commit在`Tue Jan 9 2024`提交,而changelog里写的是`Wed Nov 22 2023`,导致其提交比上一个晚,但是changelog里写的日期比上一个早 + +### 2.2、问题总结及根因确认 + +changelog的日期应该按从上到下时间降序,本问题由于changelog中写的日期与实际提交日期大大不符导致 + +## 3、修改建议 + +将`Wed Nov 22 2023 wangxiaomeng - 8:2.03.22-3`的日期修改成commit对应的日期,即将`Wed Nov 22 2023`改为`Tue Jan 9 2024` \ No newline at end of file diff --git "a/LLVM Parallel Universe Project/\351\227\256\351\242\230\345\256\232\344\275\215\346\200\273\347\273\223/OSPP2024-LLVM\346\236\204\345\273\272openEuler\350\275\257\344\273\266\345\214\205\345\205\274\345\256\271\346\200\247\351\227\256\351\242\230\345\210\206\346\236\220\345\217\212\350\247\243\345\206\263(Part II)/lxc\351\227\256\351\242\230\345\256\232\344\275\215\345\217\212\344\277\256\345\244\215.md" "b/LLVM Parallel Universe Project/\351\227\256\351\242\230\345\256\232\344\275\215\346\200\273\347\273\223/OSPP2024-LLVM\346\236\204\345\273\272openEuler\350\275\257\344\273\266\345\214\205\345\205\274\345\256\271\346\200\247\351\227\256\351\242\230\345\210\206\346\236\220\345\217\212\350\247\243\345\206\263(Part II)/lxc\351\227\256\351\242\230\345\256\232\344\275\215\345\217\212\344\277\256\345\244\215.md" new file mode 100644 index 0000000..ab7509b --- /dev/null +++ "b/LLVM Parallel Universe Project/\351\227\256\351\242\230\345\256\232\344\275\215\346\200\273\347\273\223/OSPP2024-LLVM\346\236\204\345\273\272openEuler\350\275\257\344\273\266\345\214\205\345\205\274\345\256\271\346\200\247\351\227\256\351\242\230\345\210\206\346\236\220\345\217\212\350\247\243\345\206\263(Part II)/lxc\351\227\256\351\242\230\345\256\232\344\275\215\345\217\212\344\277\256\345\244\215.md" @@ -0,0 +1,115 @@ +来源:https://gitee.com/src-openeuler/lxc (openEuler-24.03-LTS) + +# 相关PR + +openEuler:[backport:fix clang build error on AARCH64 · Pull Request !531 · src-openEuler/lxc - Gitee.com](https://gitee.com/src-openeuler/lxc/pulls/531) + +上游社区:https://github.com/lxc/lxc/pull/4481 + +# 问题一:meson.build中cc.compiles returns unexpected false问题 + +## 1、问题现象 + +```c +[ 112s] clang: warning: argument unused during compilation: '-fstack-clash-protection' [-Wunused-command-line-argument] +[ 112s] In file included from ../src/lxc/error.c:10: +[ 112s] ../src/lxc/log.h:310:6: error: conflicting types for 'strerror_r' +[ 112s] 310 | int strerror_r(int errnum, char *buf, size_t buflen); +[ 112s] | ^ +[ 112s] /usr/include/string.h:444:14: note: previous declaration is here +[ 112s] 444 | extern char *strerror_r (int __errnum, char *__buf, size_t __buflen) +[ 112s] | ^ +[ 112s] 1 error generated. +``` + +## 2、问题定位 + +### 2.1、问题定位分析 + +已同步提交上游PR:[fix possible clang compile error on AARCH by yuncang123 · Pull Request #4479 · lxc/lxc (github.com)](https://github.com/lxc/lxc/pull/4479) + +* 报错的地方在log.h + +```c +#if HAVE_STRERROR_R + #if STRERROR_R_CHAR_P + char *strerror_r(int errnum, char *buf, size_t buflen); + #else + int strerror_r(int errnum, char *buf, size_t buflen); + #endif +``` + +STRERROR_R_CHAR_P的取值定义在下段代码中: + +```c +have_func_strerror_r = cc.has_function('strerror_r', prefix: '#include ', args: '-D_GNU_SOURCE') +srcconf.set10('HAVE_STRERROR_R', have_func_strerror_r) + +have_func_strerror_r_char_p = false + +if have_func_strerror_r + code = ''' +#define _GNU_SOURCE +#include +int func (void) { + char error_string[256]; + char *ptr = strerror_r (-2, error_string, 256); + char c = *strerror_r (-2, error_string, 256); + return c != 0 && ptr != (void*) 0L; +} +''' + +have_func_strerror_r_char_p = cc.compiles(code, name : 'strerror_r() returns char *') +endif + +srcconf.set10('STRERROR_R_CHAR_P', have_func_strerror_r_char_p) +``` + +问题关键: + +```c +[ 94s] Checking if "strerror_r() returns char *" compiles: NO +``` + + +而这个结果本该是YES,因为openEuler-24.03-LTS中strerror_r的返回值类型就是char *没错。 + +问题出在cc.compiles结果出错: + +```c +cc.compiles(code, name : 'strerror_r() returns char *') +``` + +最后发现是由于`'-fstack-clash-protection'`在aarch中暂时并未支持,再加上默认开启了‘-Werror’,因此导致-Wunused-command-line-argument升级为error,导致编译结果为false + +### 2.2、关于meson中的Compiler properties + +详见:https://mesonbuild.com/Compiler-properties.html + +这里只简单介绍一下`compiler.compiles` + +```c +compiler = meson.get_compiler('c') +code = '''#include +void func() { printf("Compile me.\n"); } +''' +result = compiler.compiles(code, name : 'basic check') +``` + +`compiler = meson.get_compiler('c')`是获取c语言的编译器 + +`result = compiler.compiles(code, name : 'basic check')`如果编译器编译code通过,则返回true,反之返回false + +`name : 'basic check'`是可选参数选项 + +此外,还可以加入`args:`参数,这个参数的作用是给这一次`compiler.compiles`添加编译器选项 + +例如本修改法中,就是当编译器为clang时,将`cc.compiles(code, name : 'strerror_r() returns char *')`改为`cc.compiles(code, args : '-Wno-error=unused-command-line-argument', name : 'strerror_r() returns char *')`从而避免`'-fstack-clash-protection'`导致的error + +### 2.3、问题总结及根因确认 + +meson中的`compiler.compiles(code, name : 'basic check')`函数是用来测试code是否能够编译成功,本例使用该函数来测试strerror_r函数在当前系统中的返回值类型,然而由于aarch中没有实现`'-fstack-clash-protection'`,该编译器选项在Werror的影响下由warning升级成为了error,从而使`compiler.compiles`返回结果为false(这与测试strerror_r函数在当前系统中的返回值类型的本意是违背的)。 + +## 3、修改建议 + +当编译器为clang时,将`cc.compiles(code, name : 'strerror_r() returns char *')`改为`cc.compiles(code, args : '-Wno-error=unused-command-line-argument', name : 'strerror_r() returns char *')`从而避免`'-fstack-clash-protection'`导致的error \ No newline at end of file diff --git "a/LLVM Parallel Universe Project/\351\227\256\351\242\230\345\256\232\344\275\215\346\200\273\347\273\223/OSPP2024-LLVM\346\236\204\345\273\272openEuler\350\275\257\344\273\266\345\214\205\345\205\274\345\256\271\346\200\247\351\227\256\351\242\230\345\210\206\346\236\220\345\217\212\350\247\243\345\206\263(Part II)/open-iscsi\351\227\256\351\242\230\345\256\232\344\275\215\345\217\212\344\277\256\345\244\215.md" "b/LLVM Parallel Universe Project/\351\227\256\351\242\230\345\256\232\344\275\215\346\200\273\347\273\223/OSPP2024-LLVM\346\236\204\345\273\272openEuler\350\275\257\344\273\266\345\214\205\345\205\274\345\256\271\346\200\247\351\227\256\351\242\230\345\210\206\346\236\220\345\217\212\350\247\243\345\206\263(Part II)/open-iscsi\351\227\256\351\242\230\345\256\232\344\275\215\345\217\212\344\277\256\345\244\215.md" new file mode 100644 index 0000000..7bcdafc --- /dev/null +++ "b/LLVM Parallel Universe Project/\351\227\256\351\242\230\345\256\232\344\275\215\346\200\273\347\273\223/OSPP2024-LLVM\346\236\204\345\273\272openEuler\350\275\257\344\273\266\345\214\205\345\205\274\345\256\271\346\200\247\351\227\256\351\242\230\345\210\206\346\236\220\345\217\212\350\247\243\345\206\263(Part II)/open-iscsi\351\227\256\351\242\230\345\256\232\344\275\215\345\217\212\344\277\256\345\244\215.md" @@ -0,0 +1,255 @@ +来源:https://gitee.com/src-openeuler/open-iscsi (openEuler-24.03-LTS) + +# 相关PR + +openEuler:[Backport:fix several bugs, support clang build · Pull Request !162 · src-openEuler/open-iscsi - Gitee.com](https://gitee.com/src-openeuler/open-iscsi/pulls/162) + +上游社区:[fix 4 issues which are finded when building with clang 17 by yuncang123 · Pull Request #478 · open-iscsi/open-iscsi (github.com)](https://github.com/open-iscsi/open-iscsi/pull/478) + +[fix: add usr/iscsid_req.h missinig underline (#431) by hanqingwu · Pull Request #436 · open-iscsi/open-iscsi (github.com)](https://github.com/open-iscsi/open-iscsi/pull/436) + +# 问题一:'linker' input unused问题 + +## 1、问题现象 + +```c +[ 102s] clang: error: -Wl,-z,relro: 'linker' input unused [-Werror,-Wunused-command-line-argument] +[ 102s] clang: error: -Wl,-z,now: 'linker' input unused [-Werror,-Wunused-command-line-argument] +[ 102s] clang: error: -lkmod: 'linker' input unused [-Werror,-Wunused-command-line-argument] +``` + +## 2、问题定位 + +open-iscsi.spec中: + +`%make_build OPTFLAGS="%{optflags} %{?__global_ldflags} -DUSE_KMOD -lkmod" LIB_DIR=%{_libdir}` + +在open-iscisi-2.1.5/Makefile中: + +```c +# Compatibility: parse old OPTFLAGS argument +ifdef OPTFLAGS +CFLAGS = $(OPTFLAGS) +endif +``` + + +也就是将`%{?__global_ldflags}`(即-Wl,-z,relro -Wl,-z,now)、`-lkmod`等链接器(linker)选项设置给了编译器CFLAGS,这在clang看来是多余的、无用的 + +## 3、修改建议 + +当toolchain为clang时,将`%{?__global_ldflags}`(即-Wl,-z,relro -Wl,-z,now)、`-lkmod`等链接器(linker)选项设置给LDFLAGS + +即将 + +```c +%make_build OPTFLAGS="%{optflags} %{?__global_ldflags} -DUSE_KMOD -lkmod" LIB_DIR=%{_libdir} +``` + +改为: + +```c +%if "%toolchain"=="clang" +CFLAGS="%{optflags} -DUSE_KMOD" \ +LDFLAGS="%{?__global_ldflags} -lkmod" \ +LIB_DIR=%{_libdir} +%make_build +%else +%make_build OPTFLAGS="%{optflags} %{?__global_ldflags} -DUSE_KMOD -lkmod" LIB_DIR=%{_libdir} +%endif +``` + +# 问题二:header guard followed by #define of a different macro问题 + +## 1、问题现象 + +```c +[ 89s] In file included from session_info.c:19: +[ 89s] ./iscsid_req.h:21:9: error: 'ISCSID_REQ_H_' is used as a header guard here, followed by #define of a different macro [-Werror,-Wheader-guard] +[ 89s] 21 | #ifndef ISCSID_REQ_H_ +[ 89s] | ^~~~~~~~~~~~~ +[ 89s] ./iscsid_req.h:22:9: note: 'ISCSID_REQ_H' is defined here; did you mean 'ISCSID_REQ_H_'? +[ 89s] 22 | #define ISCSID_REQ_H +[ 89s] | ^~~~~~~~~~~~ +[ 89s] | ISCSID_REQ_H_ +[ 89s] 1 error generated. +``` + +## 2、问题成因 + +前后名字不一致,少了个_,clang语法检测更加严格,因此发现问题 + +## 3、修改建议 + +回合上游commit:[fix: add usr/iscsid_req.h missinig underline (#431) · hanqingwu/open-iscsi@2989724 (github.com)](https://github.com/hanqingwu/open-iscsi/commit/29897249ab77739f6b233677d761e24705b33f6a) + +# 问题三:declaration will not be visible outside of this function问题 + +## 1、问题现象 + +```c +[ 95s] In file included from discoveryd.c:31: +[ 95s] ./iface.h:61:29: error: declaration of 'struct iovec' will not be visible outside of this function [-Werror,-Wvisibility] +[ 95s] 61 | int iface_all, struct iovec *iovs); +[ 95s] | ^ +[ 95s] 1 error generated. +``` + +## 2、问题定位 + +iface.h + +```c +extern int iface_build_net_config(struct iface_rec *iface_primary, + int iface_all, struct iovec *iovs); +``` + +经过查询,struct iovec的定义在系统库 中,而iface.h中既没有对struct iovec的定义,也没有包含该头文件 + +## 3、修改建议 + +在iface.h头文件中#include + +# 问题三:attribute declaration must precede definition问题 + +## 1、问题现象 + +```c +[ 93s] In file included from io.c:41: +[ 93s] In file included from ./iface.h:23: +[ 93s] In file included from ../libopeniscsiusr/libopeniscsiusr/libopeniscsiusr.h:30: +[ 93s] ../libopeniscsiusr/libopeniscsiusr/libopeniscsiusr_common.h:75:8: error: attribute declaration must precede definition [-Werror,-Wignored-attributes] +[ 93s] 75 | struct __DLL_EXPORT iscsi_session; +[ 93s] | ^ +[ 93s] ../libopeniscsiusr/libopeniscsiusr/libopeniscsiusr_common.h:64:38: note: expanded from macro '__DLL_EXPORT' +[ 93s] 64 | #define __DLL_EXPORT __attribute__ ((visibility ("default"))) +[ 93s] | ^ +[ 93s] ./initiator.h:198:16: note: previous definition is here +[ 93s] 198 | typedef struct iscsi_session { +[ 93s] | ^ +``` + +## 2、问题定位 + +### 2.1、问题定位分析 + +网上搜索该问题,发现问题出在头文件的顺序上 + +头文件"iface.h"中声明了struct iscsi_session且声明了__DLL_EXPORT(该宏展开为\_\_attribute\_\_ ((visibility ("default")))),"initiator.h"中定义了struct iscsi_session,clang要求"attribute declaration must precede definition"即带有attribute的声明要先于其定义 + +以io.c为例 + +```c +... +#include "types.h" +#include "iscsi_proto.h" +#include "iscsi_settings.h" +#include "initiator.h" +#include "iscsi_ipc.h" +#include "log.h" +#include "transport.h" +#include "idbm.h" +#include "iface.h" +#include "sysdeps.h" +... +``` + +问题就出在\#include "initiator.h"和\#include "iface.h"的顺序上 + +只要将\#include "iface.h"移动到\#include "initiator.h"之前就能解决报错 + +### 2.2、问题总结及根因确认 + +clang要求"attribute declaration must precede definition"即带有attribute的声明必须先于定义,在该问题情境中体现为头文件的顺序,\#include "iface.h"要先于\#include "initiator.h" + +## 3、修改建议 + +通过移动头文件顺序的方式,使带有attribute的声明先于其定义 + +# 问题四:implicit truncation from 'int' to a one-bit wide bit-field changes value from 1 to -1问题 + +## 1、问题现象 + +```c +[ 88s] mgmt_ipc.c:511:19: error: implicit truncation from 'int' to a one-bit wide bit-field changes value from 1 to -1 [-Werror,-Wsingle-bit-bitfield-constant-conversion] +[ 88s] 511 | qtask->allocated = 1; +[ 88s] | ^ ~ +[ 88s] 1 error generated. +``` + +## 2、问题定位 + +### 2.1、问题定位分析 + +qtask的类型为queue_task_t,而queue_task_t的定义在usr/initiator.h中: + +```c +typedef struct queue_task { + iscsi_conn_t *conn; + iscsiadm_req_t req; + iscsiadm_rsp_t rsp; + int mgmt_ipc_fd; + int allocated : 1; + /* Newer request types include a + * variable-length payload */ + void *payload; +} queue_task_t; +``` + +这个错误是由于在代码中存在一个隐式截断问题。试图将一个 `int` 类型的值(这里是 `1`)赋给一个一位宽的位域(allocated),但由于位域的宽度为1位,这样的操作可能会导致值从`1`被截断为`-1` + +### 2.2、关于位域(bit-field) + +有些信息在存储时,并不需要占用一个完整的字节,而只需占几个或一个二进制位。例如在存放一个开关量时,只有 0 和 1 两种状态,用 1 位二进位即可。为了节省存储空间,并使处理简便,C 语言又提供了一种数据结构,称为"位域"或"位段"。 + +所谓"位域"是把一个字节中的二进位划分为几个不同的区域,并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。这样就可以把几个不同的对象用一个字节的二进制位域来表示。 + +详见:[C 位域 | 菜鸟教程 (runoob.com)](https://www.runoob.com/cprogramming/c-bit-fields.html) + +这里的allocated本意是利用位域来节省空间,只有0和1两种状态,但是错误地将其类型设定为了int,这就会出现隐式截断的问题,正确的做法是将其类型设定为unsigned int + +### 2.3、问题总结及根因确认 + +clang比gcc检查更加严格,检测出了给位域赋值时可能出现的隐式截断问题 + +## 3、修改建议 + +方案一: + +修改`int allocated : 1`为`unsigned int allocated : 1` + +参考: + +方案二: + +改为适用bool类型赋值,而不是1 + +修改`qtask->allocated = 1;`为`qtask->allocated = true;` + + +方案一能从根源解决问题,因此方案一更优 + +# 问题五:unused-but-set-variable问题 + +## 1、问题现象 + +```c +[ 93s] discovery.c:698:6: error: variable 'num_targets' set but not used [-Werror,-Wunused-but-set-variable] +[ 93s] 698 | int num_targets = 0; +[ 93s] | ^ +[ 93s] 1 warning and 1 error generated. +``` + +## 2、问题定位 + +查找num_targets在全文中的用法可知,该变量在定义之后只有两处自增的操作,除此之外并没有被实际使用过 + +## 3、修改建议 + +方案一: + +理论上,这里的num_targets只有自增操作,并没有被具体使用,所以是可以将这三处出现的地方删除的 + +方案二: + +clang开启Werror将`unused-but-set-variable`当做error,所以可以添加-Wno-error=unused-but-set-variable将error降级为warning,使llvm能够构建 \ No newline at end of file diff --git "a/LLVM Parallel Universe Project/\351\227\256\351\242\230\345\256\232\344\275\215\346\200\273\347\273\223/OSPP2024-LLVM\346\236\204\345\273\272openEuler\350\275\257\344\273\266\345\214\205\345\205\274\345\256\271\346\200\247\351\227\256\351\242\230\345\210\206\346\236\220\345\217\212\350\247\243\345\206\263(Part II)/opensc\351\227\256\351\242\230\345\256\232\344\275\215\345\217\212\344\277\256\345\244\215.md" "b/LLVM Parallel Universe Project/\351\227\256\351\242\230\345\256\232\344\275\215\346\200\273\347\273\223/OSPP2024-LLVM\346\236\204\345\273\272openEuler\350\275\257\344\273\266\345\214\205\345\205\274\345\256\271\346\200\247\351\227\256\351\242\230\345\210\206\346\236\220\345\217\212\350\247\243\345\206\263(Part II)/opensc\351\227\256\351\242\230\345\256\232\344\275\215\345\217\212\344\277\256\345\244\215.md" new file mode 100644 index 0000000..9de2a2b --- /dev/null +++ "b/LLVM Parallel Universe Project/\351\227\256\351\242\230\345\256\232\344\275\215\346\200\273\347\273\223/OSPP2024-LLVM\346\236\204\345\273\272openEuler\350\275\257\344\273\266\345\214\205\345\205\274\345\256\271\346\200\247\351\227\256\351\242\230\345\210\206\346\236\220\345\217\212\350\247\243\345\206\263(Part II)/opensc\351\227\256\351\242\230\345\256\232\344\275\215\345\217\212\344\277\256\345\244\215.md" @@ -0,0 +1,88 @@ +来源:https://gitee.com/src-openeuler/opensc (openEuler-24.03-LTS) + +# 相关PR + +openEuler:[backport 1 commit,fix clang build error · Pull Request !79 · src-openEuler/opensc - Gitee.com](https://gitee.com/src-openeuler/opensc/pulls/79) + +上游社区:https://github.com/OpenSC/OpenSC/commit/3f485ff28cecf0cdddecef369442df2efed80a99 + +openEuler社区会默认将这个error降级为warning,实际情况中不影响构建。 + +# 问题一:unused-but-set-variable问题 + +## 1、问题现象 + +```c +[ 117s] pkcs11-tool.c:7304:6: error: variable 'errors' set but not used [-Werror,-Wunused-but-set-variable] +[ 117s] 7304 | int errors = 0; +[ 117s] | ^ +[ 117s] 1 error generated. +[ 117s] make[3]: *** [Makefile:1356: pkcs11_tool-pkcs11-tool.o] Error 1 +[ 117s] make[3]: *** Waiting for unfinished jobs.... +[ 117s] cardos-tool.c:1146:6: error: variable 'action_count' set but not used [-Werror,-Wunused-but-set-variable] +[ 117s] 1146 | int action_count = 0; +[ 117s] | ^ +[ 117s] 1 error generated. +``` + +## 2、问题根因分析 + +存在定义了但是未使用的变量,clang开启Werror将`unused-but-set-variable`当做error + +## 3、修改建议 + +方案一: + +删去没有被具体使用的变量,不会产生实际的影响 + +方案二: + +可以添加-Wno-error=unused-but-set-variable将error降级为warning,使llvm能够构建 + +# 问题二:passing arguments to a function without a prototype问题 + +## 1、问题现象 + +```c +[ 100s] card-openpgp.c:1164:7: error: passing arguments to a function without a prototype is deprecated in all versions of C and is not supported in C2x [-Werror,-Wdeprecated-non-prototype] +[ 100s] 1164 | func(blob); +[ 100s] | ^ +[ 100s] 1 error generated. +``` + +## 2、问题定位 + +```c +/** + * Internal: iterate through the blob tree, calling a function for each blob. + */ +static void +pgp_iterate_blobs(pgp_blob_t *blob, void (*func)()) +{ + if (blob) { + pgp_blob_t *child = blob->files; + + while (child != NULL) { + pgp_blob_t *next = child->next; + + pgp_iterate_blobs(child, func); + child = next; + } + func(blob); + } +} +``` + +参数列表里func应该是一个不接受任何参数的函数的指针,而实际运用上传入了blob + +上游commit: + +[pgp: avoid calling functions without prototype · OpenSC/OpenSC@3f485ff (github.com)](https://github.com/OpenSC/OpenSC/commit/3f485ff28cecf0cdddecef369442df2efed80a99) + +更改了代码逻辑,弃用`pgp_iterate_blobs`函数,改为使用`pgp_free_blobs`函数 + +## 3、修改建议 + +回合上游commit,消除错误: + +[pgp: avoid calling functions without prototype · OpenSC/OpenSC@3f485ff (github.com)](https://github.com/OpenSC/OpenSC/commit/3f485ff28cecf0cdddecef369442df2efed80a99) \ No newline at end of file diff --git "a/LLVM Parallel Universe Project/\351\227\256\351\242\230\345\256\232\344\275\215\346\200\273\347\273\223/OSPP2024-LLVM\346\236\204\345\273\272openEuler\350\275\257\344\273\266\345\214\205\345\205\274\345\256\271\346\200\247\351\227\256\351\242\230\345\210\206\346\236\220\345\217\212\350\247\243\345\206\263(Part II)/proftpd\351\227\256\351\242\230\345\256\232\344\275\215\345\217\212\344\277\256\345\244\215.md" "b/LLVM Parallel Universe Project/\351\227\256\351\242\230\345\256\232\344\275\215\346\200\273\347\273\223/OSPP2024-LLVM\346\236\204\345\273\272openEuler\350\275\257\344\273\266\345\214\205\345\205\274\345\256\271\346\200\247\351\227\256\351\242\230\345\210\206\346\236\220\345\217\212\350\247\243\345\206\263(Part II)/proftpd\351\227\256\351\242\230\345\256\232\344\275\215\345\217\212\344\277\256\345\244\215.md" new file mode 100644 index 0000000..3126a5f --- /dev/null +++ "b/LLVM Parallel Universe Project/\351\227\256\351\242\230\345\256\232\344\275\215\346\200\273\347\273\223/OSPP2024-LLVM\346\236\204\345\273\272openEuler\350\275\257\344\273\266\345\214\205\345\205\274\345\256\271\346\200\247\351\227\256\351\242\230\345\210\206\346\236\220\345\217\212\350\247\243\345\206\263(Part II)/proftpd\351\227\256\351\242\230\345\256\232\344\275\215\345\217\212\344\277\256\345\244\215.md" @@ -0,0 +1,192 @@ +来源:https://gitee.com/src-openeuler/proftpd (openEuler-24.03-LTS) + +# 相关PR + +openEuler:[给函数pr_ctrls_recv_request加上 __attribute__((optnone)),使得LLVM能够成功构建 · Pull Request !70 · src-openEuler/proftpd - Gitee.com](https://gitee.com/src-openeuler/proftpd/pulls/70) + +上游社区:不涉及(上游社区已经弃用有问题的代码,但是由于别的原因弃用的) + +# 问题:编译优化选项导致即使if条件为真但不执行 + +## 1、问题现象 + +clang不通过原因是,一处test结果FAILURE(没有按照预期处理特定情况): + +```c +[ 254s] api/ctrls.c:883:F:base:ctrls_recv_request_actions_test:0: Failed to handle too-long reqarg +[ 254s] ------------------------------------------------- +[ 254s] FAILED 1 test +[ 254s] +[ 254s] Please send email to: +[ 254s] +[ 254s] proftp-devel@lists.sourceforge.net +[ 254s] +[ 254s] containing the `api-tests.log' file (in the tests/ directory) +[ 254s] and the output from running `proftpd -V' +``` + +## 2、问题定位与分析 + +### 2.1、问题定位 + +api/ctrls.c具体报错代码片段,位于START_TEST (ctrls_recv_request_actions_test){...}中: + +```c +mark_point(); +fd = reset_fd(fd); +if (fd < 0) { + return; +} +clear_array(cl->cl_ctrls); +cl->cl_fd = fd; + +reqarglen = 500; +(void) write(fd, &status, sizeof(status)); +(void) write(fd, &nreqargs, sizeof(nreqargs)); +(void) write(fd, &actionlen, sizeof(actionlen)); +(void) write(fd, action, actionlen); +(void) write(fd, &reqarglen, sizeof(reqarglen)); +rewind_fd(fd); +res = pr_ctrls_recv_request(cl); +ck_assert_msg(res < 0, "Failed to handle too-long reqarg"); +ck_assert_msg(errno == ENOMEM, "Expected ENOMEM (%d), got %s (%d)", ENOMEM, + strerror(errno), errno); +ck_assert_msg(cl->cl_ctrls->nelts == 0, "Expected 0 ctrl, got %d", + cl->cl_ctrls->nelts); +``` + +ck_assert_msg断言了res<0,否则就会提示"Failed to handle too-long reqarg",与此同时,还断言了errno==ENOMEM(12)。 + + +而pr_ctrls_recv_request函数体内能让errno==ENOMEM的只有三处: + +```c + if (nreqargs > CTRLS_MAX_NREQARGS) { + (void) pr_trace_msg(trace_channel, 3, + "nreqargs (%u) exceeds max (%u), rejecting", nreqargs, + CTRLS_MAX_NREQARGS); + pr_signals_unblock(); + errno = ENOMEM; + return -1; + } +``` + +```c + if (reqarglen >= sizeof(reqaction)) { + pr_signals_unblock(); + errno = ENOMEM; + return -1; + } +``` + +```c + if (reqarglen > CTRLS_MAX_REQARGLEN) { + (void) pr_trace_msg(trace_channel, 3, + "reqarglen (#%u) of %u bytes exceeds max (%u bytes), rejecting", + i+1, reqarglen, CTRLS_MAX_REQARGLEN); + pr_signals_unblock(); + errno = ENOMEM; + return -1; + } +``` + +我利用ck_assert_msg进行了如下测试: + +#### 测试一:具体是哪一行出错的? + +```c ++ errno=0; ++ res=10; + reqarglen = 500; + (void) write(fd, &status, sizeof(status)); + (void) write(fd, &nreqargs, sizeof(nreqargs)); +@@ -880,12 +882,13 @@ START_TEST (ctrls_recv_request_actions_test) { + (void) write(fd, &reqarglen, sizeof(reqarglen)); + rewind_fd(fd); ++ ck_assert_msg(res < 0, "Failed to handle too-long reqarg,res:%d,errno:%d(%s)",res,errno,strerror(errno)); + res = pr_ctrls_recv_request(cl); +- ck_assert_msg(res < 0, "Failed to handle too-long reqarg"); + ck_assert_msg(errno == ENOMEM, "Expected ENOMEM (%d), got %s (%d)", ENOMEM, + strerror(errno), errno); + ck_assert_msg(cl->cl_ctrls->nelts == 0, "Expected 0 ctrl, got %d", + cl->cl_ctrls->nelts); +``` + +```c +[ 216s] api/ctrls.c:884:F:base:ctrls_recv_request_actions_test:0: Failed to handle too-long reqarg,res:10,errno:0(Success) +``` + +将断言放到`res = pr_ctrls_recv_request(cl);`之前一句,errno和res都还是我手动初始化的值,这说明了错误就只是在`res = pr_ctrls_recv_request(cl);`产生的。 + +#### 测试二:出错时res和errno分别为什么值? + +让ck_assert_msg额外打印断言失败时,res的值与errno的值,发现执行完`res = pr_ctrls_recv_request(cl);`后res为0,而非预期的<0,errno为1(Operation not permitted),而非预期的12(ENOMEM) + +**这说明了:代码并没有运行进入上面那三处能让errno==ENOMEM的控制语句内,不然res一定返回-1;** + +#### 测试三:为什么没有进入控制语句内? + +经过一些调试,我最终将问题范围缩小到了if (reqarglen > CTRLS_MAX_REQARGLEN){...}这一语句块内 + +* 测试在if (reqarglen > CTRLS_MAX_REQARGLEN) 之前reqarglen的值,**结果:500** + +```c ++ return reqarglen; + if (reqarglen > CTRLS_MAX_REQARGLEN) { +``` + +* 测试在if (reqarglen > CTRLS_MAX_REQARGLEN) 之前CTRLS_MAX_REQARGLE,**结果:256** + +```c ++ return CTRLS_MAX_REQARGLEN; + if (reqarglen > CTRLS_MAX_REQARGLEN) { +``` + +* 测试if (reqarglen > CTRLS_MAX_REQARGLEN)之前reqarglen > CTRLS_MAX_REQARGLEN的值,**结果:1** + +```c ++ return reqarglen > CTRLS_MAX_REQARGLEN; + if (reqarglen > CTRLS_MAX_REQARGLEN) { +``` + +* 如果进入了控制语句,则令其立即返回(reqarglen > CTRLS_MAX_REQARGLEN)+1000,**预期结果为1001,实际结果为0**,已知函数pr_ctrls_recv_request如果没有进入任何if控制语句内,最后会返回0,这说明即使在上述已知reqarglen > CTRLS_MAX_REQARGLEN条件下,依然没有进入if控制语句内。 + +```c ++ + if (reqarglen > CTRLS_MAX_REQARGLEN) { +- (void) pr_trace_msg(trace_channel, 3, +- "reqarglen (#%u) of %u bytes exceeds max (%u bytes), rejecting", +- i+1, reqarglen, CTRLS_MAX_REQARGLEN); +- pr_signals_unblock(); ++ return (reqarglen > CTRLS_MAX_REQARGLEN)+1000; ++ //(void) pr_trace_msg(trace_channel, 3, ++ // "reqarglen (#%u) of %u bytes exceeds max (%u bytes), rejecting", ++ // i+1, reqarglen, CTRLS_MAX_REQARGLEN); ++ // return CTRLS_MAX_REQARGLEN+1000; ++ //pr_signals_unblock(); + errno = ENOMEM; + return -1; + } +``` + +```c +[ 206s] api/ctrls.c:885:F:base:ctrls_recv_request_actions_test:0: Failed to handle too-long reqarg,res:0,errno:1(Operation not permitted) +``` + +### 2.2、问题分析 + +#### 经过查阅资料发现,该问题很可能为优化选项导致的 + +尝试给函数pr_ctrls_recv_request加上 __attribute__((optnone)),即改为`int __attribute__((optnone)) pr_ctrls_recv_request(pr_ctrls_cl_t *cl) {...}`,加上之后成功构建! + +#### 进一步分析 + +一般这种优化导致的问题把编译命令拿出来看下汇编IR会比较清晰,如果想要进一步分析具体是哪个优化选项使得if控制失效,还需要检查每个优化pass之后的IR。由于目前本人在该方面的技术与知识并不熟悉,因此将进一步分析的工作暂时搁置。 + +### 2.3、问题总结及根因确认 + +LLVM优化选项导致函数pr_ctrls_recv_request中的一处if控制语句失效,即在即使满足条件的情况下,依然未执行相应的语句。给函数pr_ctrls_recv_request加上 __attribute__((optnone)),即改为`int __attribute__((optnone)) pr_ctrls_recv_request(pr_ctrls_cl_t *cl) {...}`之后成功构建。 + +## 3、修改建议 + +给函数pr_ctrls_recv_request加上 __attribute__((optnone)),即改为`int __attribute__((optnone)) pr_ctrls_recv_request(pr_ctrls_cl_t *cl) {...}`。 \ No newline at end of file diff --git "a/LLVM Parallel Universe Project/\351\227\256\351\242\230\345\256\232\344\275\215\346\200\273\347\273\223/OSPP2024-LLVM\346\236\204\345\273\272openEuler\350\275\257\344\273\266\345\214\205\345\205\274\345\256\271\346\200\247\351\227\256\351\242\230\345\210\206\346\236\220\345\217\212\350\247\243\345\206\263(Part II)/zziplib\351\227\256\351\242\230\345\256\232\344\275\215\345\217\212\344\277\256\345\244\215.md" "b/LLVM Parallel Universe Project/\351\227\256\351\242\230\345\256\232\344\275\215\346\200\273\347\273\223/OSPP2024-LLVM\346\236\204\345\273\272openEuler\350\275\257\344\273\266\345\214\205\345\205\274\345\256\271\346\200\247\351\227\256\351\242\230\345\210\206\346\236\220\345\217\212\350\247\243\345\206\263(Part II)/zziplib\351\227\256\351\242\230\345\256\232\344\275\215\345\217\212\344\277\256\345\244\215.md" new file mode 100644 index 0000000..ab602c4 --- /dev/null +++ "b/LLVM Parallel Universe Project/\351\227\256\351\242\230\345\256\232\344\275\215\346\200\273\347\273\223/OSPP2024-LLVM\346\236\204\345\273\272openEuler\350\275\257\344\273\266\345\214\205\345\205\274\345\256\271\346\200\247\351\227\256\351\242\230\345\210\206\346\236\220\345\217\212\350\247\243\345\206\263(Part II)/zziplib\351\227\256\351\242\230\345\256\232\344\275\215\345\217\212\344\277\256\345\244\215.md" @@ -0,0 +1,95 @@ +来源:https://gitee.com/src-openeuler/zziplib (openEuler-24.03-LTS) + +# 相关PR + +openEuler:[backport 3 commits,and fix changelog,to support build with clang · Pull Request !58 · src-openEuler/zziplib - Gitee.com](https://gitee.com/src-openeuler/zziplib/pulls/58) + +上游社区:https://github.com/gdraheim/zziplib/pull/141) + +# 问题一:%changelog entries must start with \*问题 + +## 1、问题现象 + +`[ 94s] error: %changelog entries must start with *` + +## 2、问题定位 + +原spec文件中changelog报错处: + +`-* Wed Jul 5 2023 dillon chen - 0.13.72-2` + +## 3、修改建议 + +删去最前面的`-`,每个changelog应该以*起始 + +# 问题二:incompatible pointer-integer conversion问题 + +## 1、问题现象 + +`[ 99s] /home/abuild/rpmbuild/BUILD/zziplib-0.13.72/zzip/mmapped.c:664:11: error: incompatible pointer to integer conversion initializing 'off_t' (aka 'long') with an expression of type 'zzip_byte_t *' (aka 'unsigned char *') [-Wint-conversion]` + +`[ 99s] /home/abuild/rpmbuild/BUILD/zziplib-0.13.72/zzip/mmapped.c:685:24: error: incompatible integer to pointer conversion assigning to 'Bytef *' (aka 'unsigned char *') from 'off_t' (aka 'long') [-Wint-conversion]` + +## 2、问题定位分析与解决思路 + +### 2.1、问题定位 + +` off_t offset = zzip_file_header_to_data(header);` + +等号左边类型为`long`,右边为`unsigned char *` + +` offset = zzip_extra_zip64_offset(zip64);` + +等号左边类型为`unsigned char *`(上面的初始化使它成为这个类型),等号右边为`long` + +### 2.2、问题分析 + +首先,上游社区的情况是:这个问题曾经有人提出过,目前上游社区的代码已经没有这个问题了。 + +#### 按照时间顺序分析该问题来龙去脉, + +首先,A发现了这个问题并且提出Issue: + +[Build failure with Clang 15 (](https://github.com/gdraheim/zziplib/issues/140)​[`error: incompatible pointer to integer conversion initializing &apos;off\_t&apos; (aka &apos;long&apos;) with an expression of type &apos;zzip\_byte\_t \*&apos; (aka &apos;unsigned char \*&apos;)`](https://github.com/gdraheim/zziplib/issues/140)​[) · Issue #140 · gdraheim/zziplib (github.com)](https://github.com/gdraheim/zziplib/issues/140) + +然后,B提出pr修复了这个Issue,并且被作者合入: + +[Fix incompatible pointer error by nvinson · Pull Request #141 · gdraheim/zziplib (github.com)](https://github.com/gdraheim/zziplib/pull/141) + +然而,作者本人认为这样的改动不够完美,不能够完全解决问题,于是重写了代码逻辑: + +[disable zzip_use_file_header_zip64_offset · gdraheim/zziplib@bf539bd (github.com)](https://github.com/gdraheim/zziplib/commit/bf539bd6a434f56f7ad7685fc0bc8496f652b5e8) + +#### 单独回合最终解决问题的commit:[disable zzip_use_file_header_zip64_offset · gdraheim/zziplib@bf539bd (github.com)](https://github.com/gdraheim/zziplib/commit/bf539bd6a434f56f7ad7685fc0bc8496f652b5e8) + +会出现error:end没有定义以及几处warning + +![输入图片说明](https://foruda.gitee.com/images/1725096824495708622/2f4c0753_13034847.png "屏幕截图") + +因为oE社区这边软件包里的是这样的 + +![输入图片说明](https://foruda.gitee.com/images/1725096829734701348/acb700f2_13034847.png "屏幕截图") + +所以需要找到是哪个commit修改了这里 + +#### 查看这个commit与社区版本差了几个commit,一并回合相关commit + +两个commit之间隔了5个commit + +![输入图片说明](https://foruda.gitee.com/images/1725096842107442652/8cd74b85_13034847.png "屏幕截图") + +#### commit:[#69 assert full zzip_file_header · gdraheim/zziplib@803f49a (github.com)](https://github.com/gdraheim/zziplib/commit/803f49aaae16b7f2899e4769afdfc673a21fa9e8)引入end变量,将其回合 + +#### commit:[Merge pull request #150 from Schievel1/fix-incompat-pointers · gdraheim/zziplib@1db4fe9 (github.com)](https://github.com/gdraheim/zziplib/commit/1db4fe922266d55279265e0e11ff63fb692068a0)解决一处类型转换warning,将其回合 + +#### 这三个commit只改格式,未改变功能,不考虑回合 + +![输入图片说明](https://foruda.gitee.com/images/1725096872545998012/88dd48f0_13034847.png "屏幕截图") + +### 2.3、问题总结及根因确认 + +源代码最初使用了不恰当的代码逻辑,产生了pointer与integer之间的不恰当类型转换,新的源码版本中author已经意识到问题并重写了代码,解决了问题。gcc对于类型转换的错误处理并不严格,而clang发现了错误,最终使其得以解决。 + +## 3、修改建议 + +回合上游pr以及相关commit:[#69 assert full zzip_file_header · gdraheim/zziplib@803f49a (github.com)](https://github.com/gdraheim/zziplib/commit/803f49aaae16b7f2899e4769afdfc673a21fa9e8)引入end;[Merge pull request #150 from Schievel1/fix-incompat-pointers · gdraheim/zziplib@1db4fe9 (github.com)](https://github.com/gdraheim/zziplib/commit/1db4fe922266d55279265e0e11ff63fb692068a0)解决一处类型转换warning;[disable zzip_use_file_header_zip64_offset · gdraheim/zziplib@bf539bd (github.com)](https://github.com/gdraheim/zziplib/commit/bf539bd6a434f56f7ad7685fc0bc8496f652b5e8)最终解决指针类型错误问题。 \ No newline at end of file -- Gitee