Open DuratarskeyK opened 2 years ago
Я знаю почему может падать, это из-за спекулятивных операций в вызываемой функции, которые помечают регистры как недоступные, и когда они сохраняются в этом месте, то выпадет SIGILL если такие были. Надо подумать, как такое решить. Точно можно решить через проверку rsize на блоки по 4 байта и сделать некрасивый switch на 16 вариантов вызовов (возможно меньше, если структуры выравниваются по 8).
Можно попробовать сделать так, главное чтобы компилятор не сохранил ret на стек перед switch, а держал на регистрах как получил из функции. Если структура больше 64 байт, то она сразу на стеке сохраняется и на регистрах не передаётся.
ret = (*(regs_t(*)(regs_t))fn)(*(regs_t*)frame);
#define COPY4(i) *(int*)(frame + i) = ret.r[i];
#define COPY8(i) frame[i] = ret.r[i];
#define COPY16(i) COPY8(i) COPY8(i+1)
#define COPY32(i) COPY16(i) COPY16(i+2)
if (rvalue)
{
switch((rsize + 3) >> 2)
{
case 1: COPY4(0) break;
case 2: COPY8(0) break;
case 3: COPY8(0) COPY4(1) break;
case 4: COPY16(0) break;
case 5: COPY16(0) COPY4(2) break;
case 6: COPY16(0) COPY8(2) break;
case 7: COPY16(0) COPY8(2) COPY4(3) break;
case 8: COPY32(0) break;
case 9: COPY32(0) COPY4(4) break;
case 10: COPY32(0) COPY8(4) break;
case 11: COPY32(0) COPY8(4) COPY4(5) break;
case 12: COPY32(0) COPY16(4) break;
case 13: COPY32(0) COPY16(4) COPY4(6) break;
case 14: COPY32(0) COPY16(4) COPY8(6) break;
case 15: COPY32(0) COPY16(4) COPY8(6) COPY4(7) break;
case 16: COPY32(0) COPY32(4) break;
}
memcpy(rvalue, frame, rsize);
}
что вообще происходит при конвертации указателя на функцию, которая ничего не возвращает и никаких аргуметов не принимает, в функцию, которая возвращает указатель на структуру и принимает его же.
Первые аргументы передаются на 8-ми регистрах, это просто значит что компилятор инициализирует данные регистры из этой структуры. Тут тонкая игра на том, что компилятор должен правильно это скомпилировать (поэтому важно запускать тесты от libffi для проверки), но видимо ситуация с SIGILL проходит мимо тестов.
Обновил патч, грануляцию по 4 байта невозможно реализовать на Си, но она и не нужна, потому что возвращаемый результат расширяется компилятором до целого регистра.
Хм, фикс похоже не помог, потому что падает там же, где и раньше. В оригинальном патче МЦСТ вроде часть вызова функции на ассемблере написана и она вроде рабочая, а вот касты указателей на функцию из одного типа в другой кажется сломаным. Пример нерабочего - blivet из питона для анаконды например или webkit minibrowser.
Еще про ffi_closure_e2k() забыл, там с приходящими регистрами нужно так же делать.
Обновил патч, сделал то же самое для ffi_closure, судя по ассемблеру компилятор сделал как надо.
Нет, на тестах питона падает, похоже нужна инструкция спекулятивного сохранения в память, даже сохранение находится под условным выполнением и условие не выполнено.
Проблему с "грязными" значениями из спекулятивных вычислений решил, патч обновил.
libffi так и не работает нормально Пробую с libffi-3.3 и патчем отсюда ловлю сегфолт у anaconda
Anaconda received signal 04!.
/usr/lib64/python3.8/site-packages/pyanaconda/_isys.so(+0x1a50)[0x4623c0525a50]
<signal handler called>
/usr/lib64/libffi.so.7(ffi_call+0x708)[0x4623bee9e370]
/usr/lib64/python3.8/site-packages/gi/_gi.cpython-38.so(+0x8e898)[0x4623be93e898]
/usr/lib64/python3.8/site-packages/gi/_gi.cpython-38.so(+0x55f38)[0x4623be905f38]
/usr/lib64/libpython3.8.so.1.0(_PyObject_MakeTpCall+0x480)[0x4623afe517e8]
/usr/lib64/libpython3.8.so.1.0(+0x443928)[0x4623b019a928]
/usr/lib64/libpython3.8.so.1.0(_PyEval_EvalFrameDefault+0x176d0)[0x4623b018f4b0]
/usr/lib64/libpython3.8.so.1.0(PyEval_EvalFrameEx+0x90)[0x4623b0177dc8]
/usr/lib64/libpython3.8.so.1.0(_PyFunction_Vectorcall+0x820)[0x4623afe53740]
/usr/lib64/libpython3.8.so.1.0(+0x444148)[0x4623b019b148]
/usr/lib64/libpython3.8.so.1.0(_PyEval_EvalFrameDefault+0x17730)[0x4623b018f510]
/usr/lib64/libpython3.8.so.1.0(PyEval_EvalFrameEx+0x90)[0x4623b0177dc8]
/usr/lib64/libpython3.8.so.1.0(_PyEval_EvalCodeWithName+0x17f0)[0x4623b0196b00]
/usr/lib64/libpython3.8.so.1.0(+0x444148)[0x4623b019b148]
/usr/lib64/libpython3.8.so.1.0(_PyEval_EvalFrameDefault+0x17730)[0x4623b018f510]
/usr/lib64/libpython3.8.so.1.0(PyEval_EvalFrameEx+0x90)[0x4623b0177dc8]
/usr/lib64/libpython3.8.so.1.0(_PyFunction_Vectorcall+0x820)[0x4623afe53740]
/usr/lib64/libpython3.8.so.1.0(+0x444148)[0x4623b019b148]
/usr/lib64/libpython3.8.so.1.0(_PyEval_EvalFrameDefault+0x17730)[0x4623b018f510]
Пишите что-ли версию компилятора и опции компиляции, и работает ли с либой пропатченной МЦСТ (если у вас есть доступ). Запускали ли тесты в самом libffi после сборки.
Лог сборки, тут есть и флаги и оции сборки https://file-store.rosalinux.ru/api/v1/file_stores/9238cbe3eefe30d13f81515c152624711014b3e3.log?show=true
версия компилятора 1.25.24 спек https://abf.io/import/libffi/blob/rosa2021.1/libffi.spec
--without check
Добавьте проверку в спек, в Альте сделано так:
%check
[ -w /dev/ptmx -a -f /proc/self/maps ] || exit
make -k check
Тесты падают вот таким образом.
=== libffi tests ===
Schedule of variations:
unix
Running target unix
Using /usr/share/dejagnu/baseboards/unix.exp as board description file for target.
Using /usr/share/dejagnu/config/unix.exp as generic interface file for target.
Using ../../testsuite/config/default.exp as tool-and-target-specific interface file.
Running ../../testsuite/libffi.bhaible/bhaible.exp ...
FAIL: libffi.bhaible/test-callback.c -W -Wall -Wno-psabi -DDGTEST=10 -Wno-unused-variable -Wno-unused-parameter -Wno-unused-but-set-variable -Wno-uninitialized -O2 (test for excess errors)
WARNING: program timed out
FAIL: libffi.bhaible/test-callback.c -W -Wall -Wno-psabi -DDGTEST=11 -Wno-unused-variable -Wno-unused-parameter -Wno-unused-but-set-variable -Wno-uninitialized -O2 (test for excess errors)
Running ../../testsuite/libffi.call/call.exp ...
Running ../../testsuite/libffi.closures/closure.exp ...
ERROR: tcl error sourcing ../../testsuite/libffi.closures/closure.exp.
ERROR: tcl error code NONE
ERROR: lcc: error: no input files
while executing
"exec $compiler --print-multi-lib"
(procedure "get_multilibs" line 62)
invoked from within
"get_multilibs"
(procedure "g++_include_flags" line 9)
invoked from within
"g++_include_flags"
(procedure "default_target_compile" line 58)
invoked from within
"default_target_compile $source $destfile $type $options"
(procedure "target_compile" line 6)
invoked from within
"target_compile $source $dest $type $options"
(procedure "libffi_target_compile" line 62)
invoked from within
"libffi_target_compile "$prog" "$output_file" "$compile_type" $options"
(procedure "libffi-dg-test-1" line 52)
invoked from within
"libffi-dg-test-1 target_compile $prog $do_what $extra_tool_flags"
(procedure "libffi-dg-test" line 2)
invoked from within
"${tool}-dg-test $prog [lindex ${dg-do-what} 0] "$tool_flags ${dg-extra-tool-flags}""
(procedure "saved-dg-test" line 112)
invoked from within
"saved-dg-test ../../testsuite/libffi.closures/unwindtest.cc {-W -Wall -Wno-psabi -O0} {}"
("eval" body line 1)
invoked from within
"eval saved-dg-test $args "
(procedure "dg-test" line 6)
invoked from within
"dg-test $test $options """
(procedure "run-many-tests" line 63)
invoked from within
"run-many-tests $tlist $additional_options"
(file "../../testsuite/libffi.closures/closure.exp" line 55)
invoked from within
"source ../../testsuite/libffi.closures/closure.exp"
("uplevel" body line 1)
invoked from within
"uplevel #0 source ../../testsuite/libffi.closures/closure.exp"
invoked from within
"catch "uplevel #0 source $test_file_name" msg"
Running ../../testsuite/libffi.complex/complex.exp ...
Running ../../testsuite/libffi.go/go.exp ...
=== libffi Summary ===
# of expected passes 1534
# of unexpected failures 2
# of unresolved testcases 3
# of unsupported tests 1
ERROR: -------------------------------------------
ERROR: in testcase ../../testsuite/libffi.closures/closure.exp
ERROR: lcc: error: no input files
ERROR: tcl error code NONE
ERROR: tcl error info:
lcc: error: no input files
while executing
"exec $compiler --print-multi-lib"
(procedure "get_multilibs" line 62)
invoked from within
"get_multilibs"
(procedure "g++_include_flags" line 9)
invoked from within
"g++_include_flags"
(procedure "default_target_compile" line 58)
invoked from within
"default_target_compile $source $destfile $type $options"
(procedure "target_compile" line 6)
invoked from within
"target_compile $source $dest $type $options"
(procedure "libffi_target_compile" line 62)
invoked from within
"libffi_target_compile "$prog" "$output_file" "$compile_type" $options"
(procedure "libffi-dg-test-1" line 52)
invoked from within
"libffi-dg-test-1 target_compile $prog $do_what $extra_tool_flags"
(procedure "libffi-dg-test" line 2)
invoked from within
"${tool}-dg-test $prog [lindex ${dg-do-what} 0] "$tool_flags ${dg-extra-tool-flags}""
(procedure "saved-dg-test" line 112)
invoked from within
"saved-dg-test ../../testsuite/libffi.closures/unwindtest.cc {-W -Wall -Wno-psabi -O0} {}"
("eval" body line 1)
invoked from within
"eval saved-dg-test $args "
(procedure "dg-test" line 6)
invoked from within
"dg-test $test $options """
(procedure "run-many-tests" line 63)
invoked from within
"run-many-tests $tlist $additional_options"
(file "../../testsuite/libffi.closures/closure.exp" line 55)
invoked from within
"source ../../testsuite/libffi.closures/closure.exp"
("uplevel" body line 1)
invoked from within
"uplevel #0 source ../../testsuite/libffi.closures/closure.exp"
invoked from within
"catch "uplevel #0 source $test_file_name" msg"
--------------------------------------------------
make[3]: *** [Makefile:452: check-DEJAGNU] Error 1
make[3]: Leaving directory '/root/libffi/BUILD/libffi-3.3/e2kv4-rosa-linux-gnu/testsuite'
make[2]: *** [Makefile:528: check-am] Error 2
make[2]: Target 'check' not remade because of errors.
make[2]: Leaving directory '/root/libffi/BUILD/libffi-3.3/e2kv4-rosa-linux-gnu/testsuite'
Making check in man
make[2]: Entering directory '/root/libffi/BUILD/libffi-3.3/e2kv4-rosa-linux-gnu/man'
make[2]: Nothing to be done for 'check'.
make[2]: Leaving directory '/root/libffi/BUILD/libffi-3.3/e2kv4-rosa-linux-gnu/man'
Making check in doc
make[2]: Entering directory '/root/libffi/BUILD/libffi-3.3/e2kv4-rosa-linux-gnu/doc'
make[2]: Nothing to be done for 'check'.
make[2]: Leaving directory '/root/libffi/BUILD/libffi-3.3/e2kv4-rosa-linux-gnu/doc'
make[2]: Entering directory '/root/libffi/BUILD/libffi-3.3/e2kv4-rosa-linux-gnu'
make[2]: Leaving directory '/root/libffi/BUILD/libffi-3.3/e2kv4-rosa-linux-gnu'
make[1]: *** [Makefile:1344: check-recursive] Error 1
make[1]: Target 'check' not remade because of errors.
make[1]: Leaving directory '/root/libffi/BUILD/libffi-3.3/e2kv4-rosa-linux-gnu'
make: *** [Makefile:2990: check] Error 2
error: Bad exit status from /var/tmp/rpm-tmp.uIVNn7 (%check)
Я так понимаю по большей части make check отрабатывает нормально и ничего интересного тут нет, однако анаконда всегда сегфолтится.
Может каких-то пакетов не хватает для сборки с проверкой, вроде С++ компилятора.
testsuite/libffi.closures содержит два С++ теста.
Также из спеки Альта:
%{?!_without_check:%{?!_disable_check:BuildRequires: dejagnu, gcc-c++, /proc, /dev/pts}}
%configure --disable-exec-static-tramp
Что один из тестов завис нехорошо.
Есть ли в логах ошибки какое-то указание какую функцию вызывает pyanaconda через FFI?
%configure --disable-exec-static-tramp
Я спек альта смотрю тут https://packages.altlinux.org/ru/sisyphus_e2k/srpms/libffi/specfiles/ и там этой опции нет
Вот еще наблюдение я взял libffi_3.3-vd7_e2k-8c.deb из PDK 7.2 и подложил бинарники и все запустилось как надо. Однако в самом pdk патчей никаких в дире с libffi нет /libffi-3.3
-rw-r--r--@ 1 fdrt staff 37B 4 авг 16:53 atom.conf
-rw-r--r--@ 1 fdrt staff 1,2K 17 авг 16:59 libffi.build
-rw-r--r--@ 1 fdrt staff 93B 4 авг 16:53 meta.txt
-rw-r--r--@ 1 fdrt staff 120B 17 авг 16:59 x86.sh
опции сборки тоже не хитрые
src_config() {
autoconf
econf \
--enable-debug \
--libdir="/usr/lib${addP}"
}
Подозреваю что в PDK забыли положить патчей
по остальным пунктам что не хватает чего типа с++ всего хватает.
и там этой опции нет
Это в старом спеке нет, который для 3.2 с патчами от МЦСТ (закрытыми под NDA).
Подозреваю что в PDK забыли положить патчей
Не положили потому что у них патчи закрытые, надо требовать и долго ждать пока выложат и если выложат когда-то. Я пытаюсь делать опенсорсные, но секретных знаний иногда не хватает. Если бы я знал что там вызывается через FFI, было бы понятнее как исправить.
Можете через gdb попробовать понять в каком месте падает.
А вот с gdb большой вопрос я не понимаю как туда пропихнуть gdb чтобы выяснить что за падение происходит подробнее а corefile который генерится получается кривой
[New LWP 1578156]
[New LWP 1578201]
.reg section in corefile is damaged
.reg section in corefile is damaged
в результате не понятно как вытащит хороший трейс
А можете выложить libffi.so* собранные на альте 3.3 версии Хочу проверить с этими либами запустится ли
Я заметил, что ffi_call вызывают используя для результата тип ffi_arg, равный по размеру 8 байт. И я написал код, что сохраняет в него ровно столько, сколько возвращается, например 1 байт для char. Но код для x86_64 расширяет числа до 8 байт. И если код для вызова FFI написан так, что вызываемая функция возвращает менее 8 байт, а использует все 8, то будет работать не правильно. Но тесты такого не проверяют.
Код из теста, для примера:
ffi_arg result;
ffi_call(&cif, FFI_FN(doit), &result, values);
printf ("The result is %d\n", (int)result);
Где исходники вашего pyanaconda? У них код слишком меняется в isys, я нашел две версии со значительными различиями.
git: https://abf.io/import/anaconda бранч rosa2021.1
rpms: http://abf-downloads.rosalinux.ru/rosa2021.1/container/4105557/e2kv4/main/release/
файл /usr/lib64/python3.8/site-packages/pyanaconda/_isys.so внутри пакета anaconda-core
мне тут говорят что в альте актуальная версия для e2k libffi6-3.2.1-alt3.E2K.1.e2kv5.rpm то есть все та же 3.2.1 с major 6
мне тут говорят что в альте актуальная версия для e2k libffi6-3.2.1-alt3.E2K.1.e2kv5.rpm то есть все та же 3.2.1 с major 6
Для Эльбруса (и для большинства архитектур) не существует такого пакета, только для riscv64 и mipsel:
https://packages.altlinux.org/ru/sisyphus_mipsel/srpms/libffi6/specfiles/
И я не знаю зачем он вообще создан, для этих архитектур это старая версия, а не актуальная.
Лучше дайте мне свой libffi собранный с патчем, я дизассемблирую и посмотрю это место:
/usr/lib64/libffi.so.7(ffi_call+0x708)[0x4623bee9e370]
Я обновил патч на основе моих предположений что это могло быть.
Одно из предположений неверное, второе с расширением целых чисел - вряд ли влияет, так что наверное будет падать так же. Мне надо стектрейс падения и библиотеку от одной и той же компиляции библиотеки.
Обновленный патч сейчас наложу и попробую запустить.
Попробовал, не помогло
Anaconda received signal 04!.
/usr/lib64/python3.8/site-packages/pyanaconda/_isys.so(+0x1a50)[0x4618a6617a50]
<signal handler called>
/usr/lib64/libffi.so.7(ffi_call+0x718)[0x4618a4f807c0]
/usr/lib64/python3.8/site-packages/gi/_gi.cpython-38.so(+0x8e898)[0x4618a4a0b898]
/usr/lib64/python3.8/site-packages/gi/_gi.cpython-38.so(+0x55f38)[0x4618a49d2f38]
/usr/lib64/libpython3.8.so.1.0(_PyObject_MakeTpCall+0x480)[0x461895ef77f8]
/usr/lib64/libpython3.8.so.1.0(+0x443938)[0x461896240938]
На всякий случай вот еще работающей libffi.so.7 от м ц с т https://file-store.rosalinux.ru/download/3ba89c8dd1e48ed8a36b57e0ee8e13149082482e от него если либу подложить то все ок
Место падения выглядит странно, это сохранение в стек возвращаемого значения после вызова функции.
Указатель неправильным быть не может, значит возвращаемое значение было спекулятивным с тегом указывающим ошибку. Что может случиться когда вызывают функцию что не возвращает аргументов, и от неё приходит какой-то мусор.
Да, с кодом МЦСТ это будет работать, потому что они сохраняют возврат инструкцией что не кидает ошибку на тегах указывающих ошибку.
Я сейчас переписал кусок ffi_call на ассемблер и тестирую такую версию. В такой ситуации это должно работать так же как в коде МЦСТ. Вот только тут может баг в anaconda.
Можно мне патч? Я быстро протестирую.
Вот предварительный патч https://pastebin.com/FSPBatTw Тесты libffi проходит, тоже проверяйте сначала на них.
А помогло!
Please make a selection from the above ['c' to continue, 'q' to quit, 'r' to
refresh]: 2
================================================================================
================================================================================
Installation
1) [x] Language settings 2) [x] Time settings
(English (United States)) (Europe/Moscow timezone)
3) [!] Installation Destination 4) [ ] Network configuration
(Processing...) (No network devices available)
5) [x] Root password 6) [!] User creation
(Root account is disabled.) (No user will be created)
Please make a selection from the above ['b' to begin installation, 'h' to help,
'q' to quit, 'r' to refresh]:
An unknown error has occured, look at the /tmp/anaconda-tb* file(s) for more details
Пару макросов переименовал и закоммитил этот патч.
А можешь дать свой тг? У меня есть кое-что, что тут выложить не могу.
Почта в патче написана, если "тг" означает Телеграм, то там меня нет и не будет.
2 момента: