“这个"由 lambda 捕获是不正确的.GCC 编译器错误? [英] "this" captured by lambda is incorrect. GCC compiler bug?

查看:32
本文介绍了“这个"由 lambda 捕获是不正确的.GCC 编译器错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近几天,我一直在调试一个涉及 C++ 中 lambda 的奇怪问题.我已将问题简化为以下症状:

For the last few days, I have been debugging a weird issue involving lambdas in C++. I have reduced the problem down to the following symptoms:

  • this 指针在 lambda 内部被破坏(注意:this 总是被副本捕获,因此 lambda 应该获得自己的 this 指针,指向 App 对象)
  • 它仅在 std::cout 打印语句存在时发生,并在创建 lambda 之前调用.打印语句可能看起来完全不相关(例如打印你好!").printf() 也表现出相同的行为.
  • 仅在交叉编译时发生.
  • 它与 x86 架构的标准编译器一起编译并运行良好(参见 示例).
  • 如果我在堆上创建 lambda(并将指向它的指针保存在 App 对象中),则不会发生错误.
  • 如果优化被关闭(即如果我设置了 -O0 标志),则该错误不会发生.当优化设置为 -O2 时会发生这种情况.
  • The this pointer gets corrupted inside a lambda (note: this is always captured by copy, so the lambda should get its own this pointer, which points to the App object)
  • It only occurs if a std::cout print statement is present, and called before the lambda is created. The print statement can be seemingly completely unrelated (e.g. print "Hello!"). printf() also exhibits the same behaviour.
  • It only occurs when cross-compiling.
  • It compiles and runs fine with the standard compiler for x86 architecture (see example).
  • If I create the lambda on the heap (and save a pointer to it inside the App object), the bug does not occur.
  • The bug does not occur if optimizations are turned off (i.e. if I set the -O0 flag). It occurs when optimization is set to -O2.

以下是我能想到的最简单的、可编译的代码示例,它会导致问题.

The following is the simplest, compilable code example I could come up with that causes the problem.

#include <iostream>
#include <functional>

class App {

public:

    std::function<void*()> test_;

    void Run() {

        // Enable this line, ERROR is printed
        // Disable this line, app runs o.k.
        std::cout << "This print statement causes the bug below!" << std::endl;

        test_ = [this] () {
            return this;
        };

        void* returnedThis = test_();
        if(returnedThis != this) {
            std::cout << "ERROR: 'this' returned from lambda (" << returnedThis 
                      << ") is NOT the same as 'this' (" << this << ") !?!?!?!?!"
                      << std::endl;
        } else {
            std::cout << "Program run successfully." << std::endl;
        }

    }
};

int main(void) {
    App app;
    app.Run();
}

在目标设备上运行时,我得到以下输出:

When running on the target device, I get the following output:

This print statement causes the bug below!
ERROR: 'this' returned from lambda (0xbec92dd4) is NOT the same as 'this' 
(0xbec92c68) !?!?!?!?!

如果我尝试取消引用损坏的this,我通常会遇到分段错误,这就是我首先发现错误的方式.

If I try and dereference the corrupted this, I usually get a segmentation fault, which is how I discovered the bug in the first place.

arm-poky-linux-gnueabi-g++ -march=armv7-a -marm -mfpu=neon -std=c++14 \
-mfloat-abi=hard -mcpu=cortex-a9 \
--sysroot=/home/ghunter/sysroots/cortexa9hf-neon-poky-linux-gnueabi \
-O2 -pipe -g -feliminate-unused-debug-types

链接器设置

arm-poky-linux-gnueabi-ld \
--sysroot=/home/ghunter/sysroots/cortexa9hf-neon-poky-linux-gnueabi \
-Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed

编译器版本

~$ arm-poky-linux-gnueabi-g++ --version

arm-poky-linux-gnueabi-g++ (GCC) 6.2.0
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

这可能是编译器错误吗?

Could this be a compiler bug?

推荐答案

这似乎是 gcc 6.2 中的编译器错误,请参阅:

This seems to be a compiler bug in gcc 6.2, see:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77686

解决方法:

  • 使用 -fno-schedule-insns2 标志(如 gbmhunter 所指出的,见下面的评论).
  • 不要使用 -O2 或更高的优化.
  • Use -fno-schedule-insns2 flag (as pointed out by gbmhunter, see comment below).
  • Do not use -O2 optimizations or higher.

这篇关于“这个"由 lambda 捕获是不正确的.GCC 编译器错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆