On 12/16/20 5:28 PM, Ivan A. Melnikov wrote: > On Sun, Dec 13, 2020 at 03:35:57AM +0300, Vladislav Zavjalov wrote: >> Обнаружил странную регрессию в одной из своих программ: >> на 32-битных архитектурах начались падения (Segmentation fault) >> где-то в районе boost::spirit (очень смешная библиотека для >> синтаксического разбора, когда-то давно она меня радовала). >> Судя по всему, произошло это одновременно с переходом на gcc-10, >> до этого пакет нормально пересобирался. >> >> Сделал тестовый пакет с каким-то минимальным кодом, пытался отлаживать >> на сборочнице, но точное место поймать пока не смог. Как только правила >> spirit становятся достаточно длинными - начинает падать. >> Зато выяснил, что падения лечатся убиранием флага -O2. >> Может быть, кому-нибудь такой рецепт поможет. >> >> Если кто-то захочет покопаться, то код есть тут: >> http://git.altlinux.org/tasks/263387/gears/2200/git >> А типичный лог на сборочнице выглядит так: >> http://git.altlinux.org/tasks/263387/build/2200/i586/log >> Собираю и запускаю программу дважды: без флага -O2 и с ним. >> Первый раз все работает, второй - падает. >> На armh - то же самое. > > > Я просто оставлю здесь то, что успел (пока) увидеть: > > [builder@localhost fig]$ g++ -O2 main.cpp fig_mask.cpp -o main && ./main > Segmentation fault (core dumped) > [builder@localhost fig]$ g++ -O2 -fno-tree-sra main.cpp fig_mask.cpp -o main && ./main > OK > [builder@localhost fig]$ g++-9 -O2 main.cpp fig_mask.cpp -o main && ./main > OK > Подтверждаю падение i386 бинарника, собранного g++-10 (неважно - кросс-компилятором, или "родным"). Достаточно даже не -O2, а просто -O. Программу удалось несколько ужать до #include #include using namespace boost::spirit::classic; int main() { const char str[] = " 1 2 3 4 5 6 7 8"; int f[8] = { 0, -1, -2, -3, -4, -5, -6, -7 }; rule<> myrule = +blank_p >> (ch_p('*') | int_p[assign_a(f[0])]) >> +blank_p >> (ch_p('*') | int_p[assign_a(f[1])]) >> +blank_p >> (ch_p('*') | int_p[assign_a(f[2])]) >> +blank_p >> (ch_p('*') | int_p[assign_a(f[3])]) >> +blank_p >> (ch_p('*') | int_p[assign_a(f[4])]) >> +blank_p >> (ch_p('*') | int_p[assign_a(f[5])]) >> +blank_p >> (ch_p('*') | int_p[assign_a(f[6])]) >> +blank_p >> (ch_p('*') | int_p[assign_a(f[7])]) ; if (!parse(str, myrule).full){ return 1; } return 0; } Если кому интересно - backtrace в приложении. (gdb) frame 20 (gdb) print p.subj.first_.subj.first_.subj.first_.subj.first_.subj.first_.subj.first_.subj.first_.subj.first_.subj.first_.subj.first_.subj.first_.subj.first_.subj.first_.subj.first_.subj.seco nd_.subj.second_.actor { = {}, ref = @0x0}