Bug 39736 - binutils >= 2.35-alt1 при неопределённых условиях генерирует код, работающий неожиданным образом
Summary: binutils >= 2.35-alt1 при неопределённых условиях генерирует код, работающий ...
Status: CLOSED WORKSFORME
Alias: None
Product: Sisyphus
Classification: Development
Component: binutils (show other bugs)
Version: unstable
Hardware: x86_64 Linux
: P5 normal
Assignee: Gleb F-Malinovskiy
QA Contact: qa-sisyphus
URL: https://lists.altlinux.org/pipermail/...
Keywords:
Depends on:
Blocks:
 
Reported: 2021-02-26 11:33 MSK by Aleksei Nikiforov
Modified: 2021-03-04 17:54 MSK (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Aleksei Nikiforov 2021-02-26 11:33:31 MSK
После обновления binutils до версии 2.35-alt1 на x86_64 перестал работать пересобранный qdoc3 из пакета qt4. На архитектурах, отличных от x86_64, проблема не воспроизводится.

Из лога в URL:

(cd /usr/src/RPM/BUILD/qt-everywhere-opensource-src-4.8.7/tools/qdoc3/test
	&& QT_BUILD_TREE=/usr/src/RPM/BUILD/qt-everywhere-opensource-src-4.8.7
	QT_SOURCE_TREE=/usr/src/RPM/BUILD/qt-everywhere-opensource-src-4.8.7
	/usr/src/RPM/BUILD/qt-everywhere-opensource-src-4.8.7/bin/qdoc3
	qt-build-docs-online.qdocconf && cp -f -r
	/usr/src/RPM/BUILD/qt-everywhere-opensource-src-4.8.7/examples/webkit/webkit-guide
	/usr/src/RPM/BUILD/qt-everywhere-opensource-src-4.8.7/doc/html)
	/bin/sh: line 1: 3765906 Segmentation fault
	QT_BUILD_TREE=/usr/src/RPM/BUILD/qt-everywhere-opensource-src-4.8.7
	QT_SOURCE_TREE=/usr/src/RPM/BUILD/qt-everywhere-opensource-src-4.8.7
	/usr/src/RPM/BUILD/qt-everywhere-opensource-src-4.8.7/bin/qdoc3
	qt-build-docs-online.qdocconf
	make: *** [Makefile:1477: adp_docs] Error 139

Откат binutils до версии 2.32-alt1 проблему убирает. Протестировано локально.

Воспроизведение:
1. Взять qt4-4.8.7-alt21. В более новых версиях возможно наличие обхода данной проблемы.
2. Опционально добавить следующее изменение, чтобы сборка завершалась полностью успешно:

http://git.altlinux.org/people/darktemplar/packages/?p=qt4.git;a=commitdiff;h=1d4e1c1b9717e6cf33f7b853d612911ef97eaf73

3. Пересобрать данный qt4 в hasher для sisyphus x86_64.

Ожидаемый результат:
Успешная работа генератора документации qdoc3 при сборке пакета.

Полученный результат:
qdoc3 падает как показано выше, сборка пакета завершается ошибкой.

В qt4 есть следующие фрагменты кода:
http://git.altlinux.org/gears/q/qt4.git?p=qt4.git;a=blob;f=src/corelib/tools/qmap.h;h=8dc4d060d28fc50bd29d2a7de8e32f39821c10a8;hb=5ed4da1985f6aa58eda7800aae4d7d285bfef3af#l61
http://git.altlinux.org/gears/q/qt4.git?p=qt4.git;a=blob;f=src/corelib/tools/qmap.cpp;h=841bd35203af8cae8845df04bdef02d633cac1fe;hb=5ed4da1985f6aa58eda7800aae4d7d285bfef3af#l53

Судя по этому коду, должны выполняться следующие условия:
&QMapData::shared_null == QMapData::shared_null.backward и &QMapData::shared_null == QMapData::shared_null.forward[0].

При использовании binutils >= 2.35-alt1 эти условия не выполняются, проверено в контейнере hasher с установленным gdb и glibc-pthread-debuginfo:

[builder@localhost .in]$ export LD_LIBRARY_PATH=/usr/src/RPM/BUILD/qt-everywhere-opensource-src-4.8.7/lib  
[builder@localhost .in]$ cd /usr/src/RPM/BUILD/qt-everywhere-opensource-src-4.8.7/tools/qdoc3/test      
[builder@localhost test]$ QT_BUILD_TREE=/usr/src/RPM/BUILD/qt-everywhere-opensource-src-4.8.7 QT_SOURCE_TREE=/usr/src/RPM/BUILD/qt-everywhere-opensource-src-4.8.7 gdb /usr/src/RPM/BUILD/qt-everywhere-opensource-src-4.8.7/bin/qdoc3
...
Reading symbols from /usr/src/RPM/BUILD/qt-everywhere-opensource-src-4.8.7/bin/qdoc3...
(gdb) watch QMapData::shared_null
Hardware watchpoint 1: QMapData::shared_null
(gdb) run qt-build-docs.qdocconf
Starting program: /usr/src/RPM/BUILD/qt-everywhere-opensource-src-4.8.7/bin/qdoc3 qt-build-docs.qdocconf

Watchpoint 1: QMapData::shared_null

Old value = 
    {backward = 0x0, forward = {0x0 <repeats 12 times>}, ref = {_q_value = 0}, topLevel = 0, size = 0, randomBits = 0, insertInOrder = 0, sharable = 0, strictAlignment = 0, reserved = 0, static shared_null = {backward = 0x7ffff7f737e0, forward = {0x7ffff7f737e0, 0x0 <repeats 11 times>}, ref = {_q_value = 0}, topLevel = 0, size = 0, randomBits = 0, insertInOrder = 0, sharable = 0, strictAlignment = 0, reserved = 0, static shared_null = <same as static member of an already seen type>}}
New value = 
    {backward = 0x7ffff7f737e0, forward = {0x7ffff7f737e0, 0x0 <repeats 11 times>}, ref = {_q_value = 0}, topLevel = 0, size = 0, randomBits = 0, insertInOrder = 0, sharable = 0, strictAlignment = 0, reserved = 0, static shared_null = {backward = 0x7ffff7f737e0, forward = {0x7ffff7f737e0, 0x0 <repeats 11 times>}, ref = {_q_value = 0}, topLevel = 0, size = 0, randomBits = 0, insertInOrder = 0, sharable = 0, strictAlignment = 0, reserved = 0, static shared_null = <same as static member of an already seen type>}}
memmove () at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:340
340             VMOVU   %VEC(1), VEC_SIZE(%rdi)
(gdb) bt
#0  memmove () at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:340
#1  0x00007ffff7fdd055 in elf_machine_rela (skip_ifunc=<optimized out>, reloc_addr_arg=<optimized out>, version=<optimized out>, sym=0x5555555561e0, reloc=0x555555569c40, map=0x7ffff7ffe190) at ../sysdeps/x86_64/dl-machine.h:501
#2  elf_dynamic_do_Rela (skip_ifunc=<optimized out>, lazy=<optimized out>, nrelative=<optimized out>, relsize=<optimized out>, reladdr=<optimized out>, map=0x7ffff7ffe190) at do-rel.h:137
#3  _dl_relocate_object (l=l@entry=0x7ffff7ffe190, scope=<optimized out>, reloc_mode=<optimized out>, consider_profiling=<optimized out>, consider_profiling@entry=0) at dl-reloc.c:274
#4  0x00007ffff7fd441a in dl_main (phdr=<optimized out>, phdr@entry=0x555555554040, phnum=<optimized out>, phnum@entry=11, user_entry=user_entry@entry=0x7fffffffe3a0, auxv=<optimized out>) at rtld.c:2341
#5  0x00007ffff7fea84b in _dl_sysdep_start (start_argptr=start_argptr@entry=0x7fffffffe460, dl_main=dl_main@entry=0x7ffff7fd2480 <dl_main>) at ../elf/dl-sysdep.c:251
#6  0x00007ffff7fd1fd9 in _dl_start_final (arg=0x7fffffffe460) at rtld.c:504
#7  _dl_start (arg=0x7fffffffe460) at rtld.c:597
#8  0x00007ffff7fd1058 in _start () from /lib64/ld-linux-x86-64.so.2
#9  0x0000000000000002 in ?? ()
#10 0x00007fffffffe6b5 in ?? ()
#11 0x00007fffffffe6f5 in ?? ()
#12 0x0000000000000000 in ?? ()
(gdb) print &QMapData::shared_null
$1 = (QMapData *) 0x5555556b7bc0 <QMapData::shared_null>
(gdb) disable 1
(gdb) c
...
Program received signal SIGSEGV, Segmentation fault.
QString::length (this=0x7ffff7f737d0) at ../../include/QtCore/../../src/corelib/tools/qstring.h:697
697     { return d->size; }
(gdb) bt
#0  QString::length (this=0x7ffff7f737d0) at ../../include/QtCore/../../src/corelib/tools/qstring.h:697
#1  0x00007ffff7d0b4fb in QString::operator< (this=0x7ffff7f737d0, other=...) at tools/qstring.cpp:2257
#2  0x0000555555574084 in qMapLessThanKey<QString> (key1=..., key2=...) at ../../include/QtCore/../../src/corelib/tools/qmap.h:107
#3  0x0000555555577195 in QMap<QString, QString>::findNode (this=0x7fffffffdab8, akey=...) at ../../include/QtCore/../../src/corelib/tools/qmap.h:487
#4  0x00005555555d97ad in QMap<QString, QString>::contains (this=0x7fffffffdab8, akey=...) at ../../include/QtCore/../../src/corelib/tools/qmap.h:555
#5  0x00005555555d6457 in Doc::initialize (config=...) at doc.cpp:3020
#6  0x0000555555619e21 in processQdocconfFile (fileName=...) at main.cpp:186
#7  0x000055555561b199 in main (argc=2, argv=0x7fffffffe468) at main.cpp:445
(gdb) print QMapData::shared_null
$2 = {backward = 0x7ffff7f737e0, forward = {0x7ffff7f737e0, 0x0 <repeats 11 times>}, ref = {_q_value = 56}, topLevel = 0, size = 0, randomBits = 0, insertInOrder = 0, sharable = 1, strictAlignment = 0, reserved = 0, 
  static shared_null = {backward = 0x7ffff7f737e0, forward = {0x7ffff7f737e0, 0x0 <repeats 11 times>}, ref = {_q_value = 56}, topLevel = 0, size = 0, randomBits = 0, insertInOrder = 0, sharable = 1, strictAlignment = 0, reserved = 0, 
    static shared_null = <same as static member of an already seen type>}}
(gdb) print &QMapData::shared_null
$3 = (QMapData *) 0x5555556b7bc0 <QMapData::shared_null>


Как можно увидеть, &QMapData::shared_null равно 0x5555556b7bc0, а QMapData::shared_null.backward и QMapData::shared_null.forward[0] равны 0x7ffff7f737e0, т.е. описанное выше условие не выполняется.

Более точные условия и причины воспроизведения проблемы пока что неизвестны.
Comment 1 Dmitry V. Levin 2021-02-26 16:10:46 MSK
(In reply to Aleksei Nikiforov from comment #0)
> 1. Взять qt4-4.8.7-alt21. В более новых версиях возможно наличие обхода
> данной проблемы.

А что за обход, известно?  Или просто не воспроизводится?
Comment 2 Aleksei Nikiforov 2021-02-26 16:19:48 MSK
Был сделан вот такой хак для обхода этой проблемы до того, как было обнаружено что даунгрейд binutils помогает:

http://git.altlinux.org/people/darktemplar/packages/?p=qt4.git;a=commitdiff;h=dcd0c909db9f751dd40c499a429870b5d0065509

Проблема в том, что мест, где может вылезать подобная проблема, может быть больше, чем то одно обнаруженное на текущий момент место. Таких мест в Qt4 ещё несколько штук, и как минимум одно - в Qt5. Однако, только наличия подобной конструкции в коде не было достаточно для воспроизведения проблемы: похоже есть какие-то дополнительные пока что не обнаруженные условия.
Comment 3 Sergey V Turchin 2021-02-26 16:39:18 MSK
> http://git.altlinux.org/people/darktemplar/packages/?p=qt4.git;a=commitdiff;
> h=dcd0c909db9f751dd40c499a429870b5d0065509
Правда, самому qt4 это не слишком помогло, т.к. сломало ABI. :-( http://git.altlinux.org/tasks/266972/logs/events.3.1.log , поэтому уповаю на исправление тут.
Comment 4 Sergey V Turchin 2021-03-04 17:03:04 MSK
https://bugzilla.redhat.com/show_bug.cgi?id=1900527
Comment 5 Dmitry V. Levin 2021-03-04 17:28:22 MSK
(In reply to Sergey V Turchin from comment #4)
> https://bugzilla.redhat.com/show_bug.cgi?id=1900527

Там пришут "due to miscompilation with LTO", полагаете, это как-то связано с тем, что происходит здесь?
Comment 6 Aleksei Nikiforov 2021-03-04 17:32:11 MSK
Уже выяснили, что можно исправить ситуацию с Qt4, если убрать опцию -reduce-relocations:

http://git.altlinux.org/gears/q/qt4.git?p=qt4.git;a=commitdiff;h=32478a23b6f435e350e9516106c3cfa78a9032b5

Поэтому я думаю, что по ссылке выше тот же баг, что и здесь. Тем более, что наличие двух копий переменной подтверждается.
Comment 7 Aleksei Nikiforov 2021-03-04 17:54:47 MSK
Поскольку в апстриме binutils - WONTFIX, а в Qt есть workaround-ы, предлагаю закрыть.