В течение последних нескольких дней я отлаживал странную проблему, связанную с lambdas на С++. Я уменьшил проблему до следующих симптомов:
- Указатель
this
поврежден внутри лямбда (примечание:this
всегда записывается копией, поэтому лямбда должна получить свой собственный указательthis
, который указывает наApp
объект) - Это происходит только в том случае, если <<24 > присутствует и вызывается до создания лямбда. Оператор печати может казаться совершенно не связанным (например, печатать "Hello!" ).
printf()
также демонстрирует то же поведение. - Это происходит только при кросс-компиляции.
- Он компилируется и отлично работает со стандартным компилятором для архитектуры
x86
(см. пример). - Если я создаю лямбду в куче (и сохраняю указатель на нее внутри объекта
App
), ошибка не возникает. - Ошибка, если оптимизация отключена (т.е. если я устанавливаю флаг
-O0
). Это происходит, когда оптимизация установлена на-O2
.
Ниже приведен самый простой, компилируемый пример кода, который может возникнуть из-за проблемы.
#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();
}
При запуске на целевом устройстве я получаю следующий вывод:
This print statement causes the bug below!
ERROR: 'this' returned from lambda (0xbec92dd4) is NOT the same as 'this'
(0xbec92c68) !?!?!?!?!
Если я попытаюсь разыменовать поврежденный this
, я обычно получаю ошибку сегментации, именно так я обнаружил ошибку в первую очередь.
Настройки компилятора
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.
Может ли это быть ошибкой компилятора?