解决 redefinition of ‘struct sched_attr’错误的完整指南
解决 redefinition of ‘struct sched_attr’错误的完整指南
一、错误原因
该错误是由于 代码中重复定义了 struct sched_attr结构体 导致的。在 Linux 系统中,sched_attr是用于调度属性的系统调用接口结构体,其定义原本位于 glibc(GNU C Library)中。当以下两种情况同时发生时,会触发此错误:
-
glibc 版本 ≥ 2.41:从 glibc 2.41 开始,
struct sched_attr被引入到标准头文件(如<linux/sched/types.h>)中。 -
代码中手动定义了该结构体:例如内核模块、用户态工具(如
qemu、rt-tests)或第三方库中直接定义了struct sched_attr,导致与 glibc 的定义冲突。
二、解决方案
1. 条件编译避免重复定义
在代码中添加条件编译,仅在 glibc 未定义 sched_attr时才定义该结构体。
修改前(冲突代码):
struct sched_attr { // 直接定义
uint32_t size;
uint32_t sched_policy;
// ... 其他字段
};
修改后(安全代码):
#ifndef SCHED_ATTR_SIZE_VER0 // 检查 glibc 是否已定义
struct sched_attr {
uint32_t size;
uint32_t sched_policy;
// ... 其他字段
};
#endif /* SCHED_ATTR_SIZE_VER0 */
-
原理:glibc 2.41+ 会定义
SCHED_ATTR_SIZE_VER0宏,通过条件编译避免重复定义。
2. 更新代码以使用 glibc 的定义
若代码需要兼容新版 glibc,应直接使用 glibc 提供的 sched_attr定义,而非手动定义。
步骤:
-
移除代码中手动定义的
struct sched_attr。 -
包含 glibc 头文件:
#include <linux/sched/types.h> // 包含 sched_attr 的官方定义 -
使用
syscall调用接口时,直接传递struct sched_attr变量。
3. 降级 glibc 版本(不推荐)
若无法修改代码,可临时降级 glibc 到 2.40 或更低版本。
风险提示:此方法可能导致其他依赖 glibc 新特性的程序异常,仅建议在隔离环境中使用。
三、实际案例修复
以 qemu编译为例(参考搜索结果
-
定位冲突文件:
找到
linux-user/syscall.c中定义sched_attr的位置(如第 363 行)。 -
添加条件编译:
修改代码如下:
下载复制运行/* From GLIBC 2.41 it is defined! */ #ifndef SCHED_ATTR_SIZE_VER0 struct sched_attr { uint32_t size; uint32_t sched_policy; uint64_t sched_flags; int32_t sched_nice; uint32_t sched_priority; uint64_t sched_runtime; uint64_t sched_deadline; uint64_t sched_period; uint32_t sched_util_min; uint32_t sched_util_max; }; #endif -
重新编译:
复制meson setup .. && ninja
四、其他相关修复
1. 重命名冲突函数
若代码中同时定义了与 glibc 同名的函数(如 sched_setattr),需重命名函数:
// 原函数名(冲突)
int sched_setattr(pid_t pid, const struct sched_attr *attr, unsigned int flags);
// 修改后(避免冲突)
int syscall_sched_setattr(pid_t pid, const struct sched_attr *attr, unsigned int flags);
2. 使用 #pragma GCC diagnostic忽略警告
临时忽略重复定义警告(不推荐,仅用于调试):
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wredefinition"
struct sched_attr { ... };
#pragma GCC diagnostic pop
五、验证修复
-
清理构建缓存:
复制rm -rf build/ && mkdir build && cd build -
重新编译:
复制meson setup .. && ninja -
检查日志:确认编译日志中不再出现
redefinition of 'struct sched_attr'错误。
六、总结
|
场景 |
解决方案 |
|---|---|
|
内核模块或工具开发 |
添加条件编译
|
|
第三方库兼容性问题 |
提交补丁给维护者,或联系供应商获取支持 |
|
临时调试环境 |
降级 glibc 或使用 |
通过条件编译或适配 glibc 的定义,可有效解决此问题。建议优先采用条件编译方案以保持代码兼容性。
posted on 2025-09-30 18:44 ENGINEER-F 阅读(14) 评论(0) 收藏 举报
浙公网安备 33010602011771号