Использование дезинфицирующего средства адресов Clang в библиотеке NDK на Android

У NDK есть возможность включить дезинфицирующее средство адресов для всего, что вы создаете с его помощью, добавив флаг -fsanitize=address как к LOCAL_CFLAGS, так и к LOCAL_LDFLAGS, что приятно. Ну, было бы неплохо, если бы это действительно работало. Если вы добавите этот флаг и попытаетесь создать свою библиотеку, вы получите кучу ошибок «неопределенный символ». Вы можете игнорировать эти ошибки, передав компоновщику -Wl,--unresolved-symbols=ignore, и сборка завершится успешно, но, конечно же, приключения на этом не заканчиваются.

Затем в руководстве Google говорится, что вам нужно устройство с root-правами, на котором вы запускаете скрипт, изменяет исполняемый файл среды выполнения в системном разделе, чтобы он загружал библиотеку ASan, а затем связывал вышеупомянутые отсутствующие символы во время выполнения. Я попробовал это, и основная проблема с этим подходом заключается в том, что он также профилирует что-то в самой JVM, тем самым замедляя ее настолько, что приложение вообще не запускается или падает где-то внутри JVM.

Я также пробовал новую отладку malloc на эмуляторе, но он также отлаживает всю JVM, что делает ее непригодной для использования. Все эти инструменты кажутся совершенно не предназначенными для разработчиков приложений, а для тех, кто работает на самом Android.

Мне отчаянно нужен способ исправить сбой с повреждением памяти в моем приложении без профилирования всей виртуальной машины в процессе. Будет ли работать ASan, если я просто вставлю его библиотеку в свой apk и загружу ее перед моей библиотекой JNI? Есть ли другие способы отладить это? Как люди вообще исправляют подобные ошибки на Android?

Создание «минимального исполняемого файла-оболочки» и запуск его в какой-либо другой операционной системе с надлежащими инструментами отладки на самом деле не вариант, потому что способ использования библиотеки JNI существенно зависит от части Java, и даже если я создам ее, я нельзя быть полностью уверенным, что эта ошибка будет воспроизводиться.

Обновление: я попробовал скрипт asan_device_setup на эмуляторе Oreo, потому что в этот раз он не работал на Nexus 9 с Nougat. Журнал был заполнен ошибками компоновщика 32-битных процессов, пытающихся загрузить 64-битные библиотеки, а затем он завис, и единственным способом сделать его снова пригодным для использования была прошивка заводского образа. Просто чтобы убедиться, что я ничего не напутал, я несколько раз пытался перепрошить заводской образ, затем TWRP, затем SuperSU, а затем с помощью приложения «adbd insecure» перезапустить демон adb от имени пользователя root. Итак, я запустил эмулятор с -writable-system и запустил на нем скрипт, он успешно завершился. Затем я создал свое приложение с помощью ASAN и установил его, но оно вылетает с ошибкой java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "__asan_init_v3" referenced by "/data/...full path to the shared library при запуске. Пробовал и с setprop wrap.com.app.package "asanwrapper" и без, результат тот же.


person Grishka    schedule 29.11.2017    source источник
comment
Вы, вероятно, имеете в виду Davlik/ART, где вы говорите JVM.   -  person Lapshin Dmitry    schedule 29.11.2017
comment
Ну, было бы неплохо, если бы это действительно работало. Если вы добавите этот флаг и попытаетесь создать свою библиотеку, вы получите кучу ошибок с неопределенными символами. Этого не должно быть. Это нормально для сборки ASAN, отличной от Android, но Android использует версию среды выполнения ASAN с общей библиотекой, которая позволяет этого избежать. Взгляните на android.googlesource.com/platform. /ndk/+/master/tests/device/ для примера использования ASAN с NDK.   -  person Dan Albert    schedule 30.11.2017
comment
Список неопределенных символов также должен был помочь.   -  person Glider    schedule 30.11.2017
comment
@DanAlbert, как и любой другой пример, который я когда-либо видел, тот, который вы связали, создает исполняемый файл вместо общей библиотеки.   -  person Grishka    schedule 01.12.2017
comment
Поэтому измените его на BUILD_SHARED_LIBRARY.   -  person Dan Albert    schedule 01.12.2017
comment
@DanAlbert, как уже выглядит мой make-файл, а затем он либо жалуется на то, что -lasan не найден, если я также передаю -fsanitize=address компоновщику, либо на отсутствующие символы __asan_..., если я этого не делаю. Я уже исправил этот сбой, поэтому сейчас мне больше не нужен ASAN, но все же было бы неплохо узнать, как запустить его в приложении для Android, потому что нигде нет исчерпывающего руководства.   -  person Grishka    schedule 01.12.2017
comment
-lasan нет. Откуда этот флаг?   -  person Dan Albert    schedule 03.12.2017
comment
Я предполагаю, что компоновщик добавляет его автоматически, когда я указываю -fsanitize=address, потому что он не показывает эту ошибку, когда я этого не делаю.   -  person Grishka    schedule 03.12.2017


Ответы (1)


Возможно, вам следует сообщить об ошибках (http://b.android.com), если вы видите проблемы с производительностью серьезный. Мы ежедневно запускаем устройства, полностью оснащенные ASAN, и они работают лучше, чем вы ожидаете. ASAN замедляет работу примерно в 2 раза, но запуск вашего приложения с ASAN должен работать нормально.

То же самое касается отладки malloc (я не помню последствий отладки malloc для производительности, но я думал, что они менее серьезны, чем ASAN).

person Dan Albert    schedule 30.11.2017
comment
Я попробовал ASAN на Moto X под управлением 5.1, если это имеет значение, и отладку malloc на эмуляторе, потому что у меня нет устройства Oreo с разблокированным загрузчиком. Пока я писал это, я понял, что у меня также есть Nexus 9, на котором я в какой-то момент разблокировал загрузчик, поэтому теперь я попытаюсь рутировать его и запустить на нем ASAN. - person Grishka; 30.11.2017
comment
KitKat/Lollipop — это когда материалы ASAN для Android только собирались вместе. Это может быть гораздо лучший опыт на чем-то новом. - person Dan Albert; 30.11.2017
comment
Я обновил свой вопрос результатами моих дальнейших неудачных экспериментов. - person Grishka; 01.12.2017