Javascript бесконечная рекурсивная функция аварийно завершает работу Chromium 50 ARM64 lib на Android 10 - PullRequest
0 голосов
/ 29 апреля 2020

В моем Android приложении используется веб-представление, подобное элементу управления на основе Chromium 50 (V8 JavaScript engine 5.0). Использование системного WebView или более новой версии Chromium не допускается по разным причинам.

Я получаю множество Fatal signal 11 (SIGSEGV), code 2 (SEGV_ACCERR) сбоев только на Android 10 и бинарной версии arm64. Тот же двоичный файл с более старыми версиями Android, а также с 32-битной версией двоичного файла с Android 10 не имеет проблем.

Вот пример кода, содержащего бесконечную рекурсивную функцию, которая дает сбой: webView.evaluateJavascript("(function a(i) { a(i++); })()", null);

Трассировка стека от Android Studio Debugger:

art_sigsegv_fault 0x000000753da02e9c
art::FaultManager::HandleFault(int, siginfo*, void*) 0x000000753da033a4
___lldb_unnamed_symbol24$$app_process64 0x0000005ca3207da8
<unknown> 0x00000075c3f888c0
<unknown> 0x00000074784191e8
<unknown> 0x00000074784191e8
<unknown> 0x00000074784191e8
<unknown> 0x00000074784191e8
<unknown> 0x00000074784191e8
............... the same line 15560 times
<unknown> 0x000000747830be94
<unknown> 0x000000747841937c
<unknown> 0x0000007478339a28
<unknown> 0x000000747831fe30

Любые идеи, как избежать этих сбоев, приветствуются.

1 Ответ

1 голос
/ 29 апреля 2020

V8 разработчик здесь. Упомянутая вами ссылка говорит о системных библиотеках. Я не знаю ни одной причины, почему V8 пытался читать системные библиотеки. Вы уверены, что это то, что происходит? Можете ли вы запустить сборку Debug и получить трассировку стека? Без дополнительных данных я бы заподозрил, что происходит что-то еще, что вызывает эти сбои.

FWIW:

--untrusted-code-mitigations заставляет (оптимизирующий) компилятор выдавать последовательности кода, которые (частично) устранить недавно обнаруженные "призрачные" ошибки безопасности процессора. Это совершенно не связано с совместимостью Android 10.

--jitless отключает всю оперативную генерацию кода в достаточно новых версиях V8 (конечно, при значительных затратах на производительность). Это также не относится к памяти только для выполнения для Android системных двоичных файлов.

Обновление после обновленного вопроса и обсуждение в комментариях:

На основе стека При трассировке кажется, что процесс завершается сбоем, когда ему не хватает места в стеке. V8 должен обнаружить эту ситуацию и бросить RangeError до того, как это произойдет; механизм для выполнения sh, который работает, зная оценку того, сколько стекового пространства будет доступно для процесса. Очевидно, для (по крайней мере) указанной комбинации c вашего приложения, работающего на Android 10, остается меньше стекового пространства, чем ожидает V8 v5.0. Обходной путь - запустить с флагом --stack-size=800 или, в качестве альтернативы, отредактировать константу V8_DEFAULT_STACK_SIZE_KB в src/globals.h.

Примечание для других читателей: установка --stack-size в огромное значение не будет магическим образом дать вам более глубокие пределы рекурсии; вместо этого он разрешит вашему процессу cra sh при превышении заданного в операционной системе предела стека вместо того, чтобы выдавать RangeError. Установка слишком низкого значения --stack-size будет означать, что код JavaScript не сможет иметь много глубоких вызовов функций (или, в крайнем случае, вообще не запускаться), прежде чем выдать RangeError. Обычно рекомендуется оставить этот флаг в покое, если только вы не столкнулись с конкретной проблемой c, как здесь, где помогает небольшая настройка.

...