У нас есть образ докера на основе centos, который использует gcc 5.4 для создания большой базы кода C ++.Образ docker создает и устанавливает gcc из исходного кода.Из-за некоторой потери данных в нашем частном реестре докеров нам пришлось перестроить / отправить этот образ докера обратно в наш реестр, и мы начали видеть проблему с локальными сборками, использующими этот образ докера.
Ошибка, которой мы являемсявидение таково:
/usr/include/c++/5.4.0/limits:1601:7: internal compiler error: Illegal instruction
max() _GLIBCXX_USE_NOEXCEPT { return __FLT_MAX__; }
^
0xa4f0cf crash_signal
../../gcc-5.4.0/gcc/toplev.c:383
Моя теория заключается в том, что эта ошибка связана с архитектурой базового процессора, на котором выполняется сборка, поскольку мы собираем GCC из исходного кода.
Ранее мы имелиинфраструктура CI, основанная на процессорах Xeon E5 v3 (архитектура Haswell).Построение этого образа докера изначально было сделано на одной из этих CI-машин и, таким образом, отлично работало на локальных блоках разработки Haswell.С тех пор наша инфраструктура CI перешла на использование процессоров Xeon Platinum (архитектура Skylake).Когда я перестроил образ, я сделал это на одном из наших новых блоков Skylake.
Поскольку у меня более новый блок разработки, у меня есть процессор на базе Broadwell и я не могу воспроизвести проблему локально.Наши сборки CI работают отлично.Пользователь, получающий эту ошибку локально, имеет процессор Haswell.
Является ли моя теория обоснованной? Я попросил пользователя построить наш образ докера локально на своем процессоре и проверить результат, но есть лиспособ обойти это более обобщенно?
Я встречал этот ответ , который указал мне на эту документацию , в которой говорится, что я могу сам указать архитектуру процессора через-march=***
.Мои идеи вытекают из этого:
- Установить
-march=haswell
при сборке GCC, чтобы запретить включение новых наборов команд - Установить
-mno-***
при сборке GCC для расширений набора команд, которыенедоступны в Haswell, но существуют в Broadwell / Skylake.
Для справки, вывод lscpu
имел эти флаги Broadwell, которых не было в блоке Haswell (которые связаны -mno-***
flags):
3dnowprefetch
hle
rtm
rdseed
adx
smap
arch_capabilities
Стоит ли тестировать, если какая-либо из этих идей решает проблему?Я надеюсь получить некоторый внешний вклад, поскольку цикл разработки для этой сборки докера довольно длинный, и я, честно говоря, понятия не имею, что эти -m
флаги решат проблему.
Также для справки, воткак мы строим gcc:
# build/install gcc
RUN tar xvf /tmp/archive/gcc-5.4.0.tar.gz && \
mkdir gcc-build && \
pushd gcc-build && \
../gcc-5.4.0/configure --prefix=/usr --enable-languages=c,c++,fortran --disable-multilib --with-gmp=/usr --with-mpfr=/usr --with-mpc=/usr && \
make -j32 && \
popd && \
yum remove -y gcc gcc-c++ gcc-gfortran && \
pushd gcc-build && \
make install && \
popd && \
rm -rf gcc-build gcc-5.4.0