对于 GNU ld 'legacy __sync_synchronize' 警告,我能做些啥?

Posted

技术标签:

【中文标题】对于 GNU ld \'legacy __sync_synchronize\' 警告,我能做些啥?【英文标题】:what can I do about GNU ld 'legacy __sync_synchronize' warning?对于 GNU ld 'legacy __sync_synchronize' 警告,我能做些什么? 【发布时间】:2019-01-02 16:50:07 【问题描述】:

我有一些使用本地范围的程序生命周期对象的 C++ 代码,例如

void testFunction(int arg) 
   static Tested tested(0);
   tested.use(arg);

在旧版本的 GCC 中构建良好。 使用 GCC 8.2.0,我在链接时收到一个令人费解的警告:

警告:使用了旧版兼容的 __sync_synchronize。不适合多线程应用

它指向定义测试的行,并且确实存在对编译器生成的 __sync_synchronize() 的调用。我想这是为了确保没有两个线程可以同时运行初始化代码,并让延迟初始化产生与加载时初始化相同的结果。

Tested 类的这个实现重现了问题:

class Tested 
  int sum;
public:
  Tested(int init) : sum(init) 
  void use(int arg) 
    sum += arg;
  
  int current() const 
    return sum;
  
;

此代码预计将在单线程嵌入式平台上运行。

我是否认为该警告与我无关?

我可以做什么(除了停止使用静态对象)来消除警告消息?

【问题讨论】:

minimal reproducible example 请。 Tested 是什么?当然,静态函数仍有望整体发挥作用。 由于void testFunction(arg),代码甚至无法编译。修复后,norepro with GCC 8.1 但您确实说过它从 8.2 开始。你看过 Bugzilla 吗?请记住8.2.0 indicates a development/trunk build,不是真实的特定版本。你试过the actual releases 8.2.1 or 8.2.2吗? @LightnessRacesinOrbit 你完全倒退了,8.2.0 是正式版本。 8.1.0 是 8.x 分支的第一个版本,8.2.0 是第二个。而 8.2.1 是在 8.2.0 之后和 8.3.0 之前某个时间来自 gcc-8-branch 的未发布快照 @LightnessRacesinOrbit 你一直都错了。自从 gcc 5 引入新的numbering scheme 以来就是这样,并且之前完全不同(x.y.z 数字中没有区分“发布”与“快照”的部分,这是新方案的好处)。 x.0.0 是主干构建,x.0.1 是主干分支后不久的预发布版本,用于新版本,并且该方案不允许 x.0.z 具有 z > 1。 @LightnessRacesinOrbit 这不是错误,不。它只是一个支持 armv4t 和其他平台的多线程的工具链。 OP 有点困惑。 【参考方案1】:

您会收到由该版本的 newlib 生成的链接器警告,告诉您您的应用程序调用了 __sync_synchronize,并且该函数没有实际同步的实现。该函数在 newlib 中的实现是一个什么都不做的存根(它可能只是为了确保没有对该函数的未定义引用而存在)。

这些调用可能来自 libstdc++.so,因为 ARM 上的 GCC 会针对库内发生的一些原子操作(例如,std::stringshared_ptr 对象中的引用计数更新)发出对 __sync_synchronize 的调用。

要获得使原子正确的工作__sync_synchronize,您可能需要链接到libatomic(使用-latomic),它将具有该功能的实现。因为您没有链接到它,所以您在 newlib 中获得了后备存根实现。如果您不需要同步原子(因为您的应用程序是单线程的并且从不尝试更新信号处理程序中的原子),那么我认为您可以忽略警告。

另一种选择是使用 libstdc++.so 的构建,以显式禁用所有线程,并且理论上不会引用 __sync_synchronize。但是 libstdc++.so 的构建只能用于单线程应用程序。您现在使用的构建可用于单线程和多线程代码(即使您收到与单线程情况不太相关的警告)。

【讨论】:

【参考方案2】:

您最好等待https://devkitpro.org/viewtopic.php?f=13&t=8822#p16213 的回复,而不是在大多数人不熟悉 devkitARM 的网站上提问。

tl;博士;使用 -fno-threadsafe-statics 编译您的代码,不用担心。

【讨论】:

以上是关于对于 GNU ld 'legacy __sync_synchronize' 警告,我能做些啥?的主要内容,如果未能解决你的问题,请参考以下文章

ld:入口点(_main)未定义。对于架构 x86_64:Xcode 9

UITest 失败,错误为 'ld: entry point (_main) undefined。对于架构 x86_64'

原子集的内置 GCC 是啥?

程序员的自我修养

x86_64-linux-gnu/libgdk-x11-2.0.so: error adding symbols: DSO missing from command line

如何使用 G++/LD 将库链接到共享对象