У 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"
и без, результат тот же.
BUILD_SHARED_LIBRARY
. - person Dan Albert   schedule 01.12.2017-lasan
не найден, если я также передаю-fsanitize=address
компоновщику, либо на отсутствующие символы__asan_...
, если я этого не делаю. Я уже исправил этот сбой, поэтому сейчас мне больше не нужен ASAN, но все же было бы неплохо узнать, как запустить его в приложении для Android, потому что нигде нет исчерпывающего руководства. - person Grishka   schedule 01.12.2017-lasan
нет. Откуда этот флаг? - person Dan Albert   schedule 03.12.2017-fsanitize=address
, потому что он не показывает эту ошибку, когда я этого не делаю. - person Grishka   schedule 03.12.2017