Appið virkaði á Android 9 og deyr á sama síma eftir uppfærsluna í Android 10. Prófíllinn þinn er ósnortinn, skírteinin eru þau sömu og hrunið kemur fyrir alla auðkenningarumferð. Logcat sýnir fyrst núllbenda, og nokkrar línur fyrir ofan stendur Cannot run program ...: error=13, Permission denied. Þessi skilaboð snúast um að keyra skrá, ekki um að lesa stillingarnar þínar.

Hverju hafnar villa 13 í raun

Android 10, API-stig 29, stöðvaði að app keyrðu skrár sem þau skrifuðu í eigin gagnamöppu. Reglan beinist að geymslu sem fyrst er skrifanleg og síðan keyranleg, og það er einmitt það sem ræsir sem afritar úr assets býr til. Eldri útgáfur af ics-openvpn-kjarnanum pakka út keyranlegri skrá openvpn úr APK-inu við fyrstu keyrslu og ræsa hana með ProcessBuilder. Útpökkunin tekst ennþá; það er keyrslunni sem er hafnað. App sem miðar á API 29 erfir regluna jafnvel þegar það keyrir á tæki sem kom með eldri útgáfu, og þess vegna getur uppfærsla brotið uppbyggingu sem enginn snerti.

Ekkert við höfnunina er sértækt fyrir eitt möppuheiti. Skrá sem appið bjó til undir gagnamöppu sinni er meðhöndluð sem ókeyranleg sama hver slóðin er, svo getFilesDir(), getCacheDir() og sérsniðin undirmappa mistakast öll á sama hátt.

Aðskildu hrun hjálparforritsins frá prófílvandamáli

Lestu loggið í kringum ræsingu ferlisins í stað þess að skruna frá toppnum. Það merki sem á að leita að er línan error=13, og staflarakningin fyrir ofan nefnir yfirleitt ræsuaðferðina sem kallaði á ProcessBuilder:

adb logcat -d | grep -n -i -E "cannot run program|permission denied|startOpenVPN"

Ef hjálparforritið ræstist aldrei sérðu enga OpenVPN-loggúttak yfirleitt: enga dulritunarviðræður, engar ýttar slóðir, enga DNS-stillingu. Ef þessar línur birtast þó og bilunin kemur seinna, þá rann tvíundaskráin og vandamálið er í prófílnum, netþjóninum eða leiðslulaginu. Þessi eina greinarmunur sparar mikinn tíma sem færi annars í að breyta skrám .ovpn sem voru aldrei sekar. Hann segir þér líka hvor af tveimur lagfæringunum hér fyrir neðan þú þarft í raun.

Athugaðu líka API-stigið á tækinu sem þú prófar, ekki það í uppbyggingarstillingunum þínum. Hermibúnaðarmynd á API 28 endurgerir ekkert, því takmörkunin bítur aðeins frá 29 og upp. Athugaðu á sama tíma mark-SDK í uppbyggingarskránni þinni: það er hækkun þess sem dregur regluna inn.

adb shell getprop ro.build.version.sdk

Hvers vegna afritun tvíundaskrárinnar annað hjálpar ekki

Augljósa leiðin, að skrifa hjálparforritið í aðra skrifanlega möppu, mistekst af sömu ástæðu og upprunalega gerði. Android leyfir enn að keyra samnýtt bókasöfn sem sett voru í innfædda bókasafnsmöppu appsins, því uppsetningarforritið pakkar þeim í stað þess að þau séu skrifuð við keyrslu. Sú mappa er eini staðurinn sem ræsirinn ætti að benda á. Allt sem þú pakkar sjálfur út við keyrslu, hvað sem þú kallar það, verður áfram í höfnuðum flokki.

Ytri geymsla er verri: hún er tengd með noexec, og hjálparforrit sem sett er þar getur ekkert app ræst. Að hreinsa appgögn endurheimtir ekki heldur gamla hegðun, því næsta keyrsla býr einfaldlega til sama ókeyranlega afritið aftur.

Beindu ræsinum að pökkuðu bókasafni

Endurnefndu hjálparforritið í nafn samnýtts bókasafns og sendu það undir jniLibs fyrir hvert ABI sem þú styður, og láttu ræsirinn svo skila slóð uppsetta bókasafnsins frá API 28 og áfram:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
    return new File(context.getApplicationInfo().nativeLibraryDir,
                    "libovpnexec.so").getPath();
}

Bókasafnið verður að vera pakkað út við uppsetningu svo sú slóð innihaldi raunverulega skrá, svo stilltu android:extractNativeLibs="true" á elementinu <application>. Ef manifest-sameining leggur til annað gildi skaltu bæta tools:replace="android:extractNativeLibs" við hliðina. tilvísun application-elementsins skjalfestir hvað eigindin stýrir.

Gættu að tvítekinni staðbundinni breytu þegar þú plástrar ræsinn fyrir höndina. Eldri heimildir lýsa nativeAPI seinna í sömu aðferð, og önnur lýsing er þýðingarvilla en ekki keyrsluvilla, svo uppbyggingin mistekst hratt og auðvelt er að sjá mistökin. Haltu ABI-listnum í Gradle-blokkinni í takt við möppurnar sem þú bætir við.

Láttu útgáfuvöruna passa við prófunaruppbygginguna

Kembiforrit getur reist göngin á meðan útgáfubundle hrynur enn, því bundle pakkar innfæddum bókasöfnum í annarri mynd og getur boðið þau þjöppuð úr skjalasafninu. Ef aðeins uppbyggingar sem koma úr bundle mistekst skaltu bæta þessu við gradle.properties og byggja aftur:

android.bundle.enableUncompressedNativeLibs=false

Staðfestu svo að uppsetti pakkinn greini frá því ABI sem þú býst við, og endurtaktu athugunina á 32-bita og 64-bita tæki ef þú sendir bæði. Pakkastjórinn nefnir það ABI sem hann valdi, svo tæki sem féll aftur í 32 bita birtist hér í stað þess að birtast í hrunskýrslu:

adb shell dumpsys package com.example.openvpn | grep -i primaryCpuAbi

Bókasafn sem vantar fyrir eitt ABI endurgerir upprunalegu heimildarvilluna aðeins á því tæki, og þess vegna er einn heppinn prófunarsími ekki sönnun. Sendu manifest-flögguna, bókasafnsheitið og bundle-stillinguna saman; að breyta einni og gleyma hinum setur þig aftur í sama hrun. Varanlega lausnin er að fara yfir í viðhaldið kjarnútgáfu í stað þess að bera plástrann að eilífu.

Tengdir greinar