Commit 0dd3d61
committed
Work around an Android 9 dlopen bug on x86
Fixes: #4893
This commit fixes an issue in Android 9 (API 28) 32-bit (ONLY) dynamic
loader issue where if the same library is loaded more than once, instead
of returning a handle to the already loaded copy, `dlopen` will
reinitialize the library thus resetting its state (BSS section is
cleared, global instances of C++ classes are re-instantiated etc).
When the library is reinitalized, however, our runtime is not - since
the Java `Runtime.initialize`, which ends up in our native code,
is *not* called because the library load is not part of the process
startup, when `Runtime.initialize` is invoked. This in turn leads to
situation when certain class members initialized in `Runtime.initialize`
and assumed to be correct throughout the application life are, in fact,
invalid and lead to crashes. In the instance of issue #4893, the
problem was that the `MonodroidRuntime::Class_getName` field was not
initialized to point to the `Java.Lang.Class.getName` Java method and
that, in turn, led to Xamarin.Android not being able to look up Java
types during application execution time.
`libmonodroid.so` is reloaded whenever Mono tries to resolve an
`__Internal` p/invoke (via a call to Xamarin.Android's
`monodroid_dlopen` fallback handler) - these p/invokes are assumed to
live in `libmonodroid` so we need to return a handle to it, so that Mono
can subsequently use `dlsym` to look up the required symbol. Given the
situation described in the previous paragraph, we need a way to not
reload `libmonodroid` or do something else to avoid it being
reinitialized.
Since there's no portable way to check whether a DSO is already
loaded we need to resort to "something else", implemented in this
commit. We move all the functions used in `__Internal` p/invokes to a
separate DSO which can be reloaded & reinitialized over and over again
without shredding our global state. This is done by way of introducing
a C++ interface class, `MonoAndroidExternalAPI` which is passed to the
new DSO on load time, thus giving it a way to invoke all the necessary
internal Xamarin.Android functions the `__Internal` p/invokes need in
order to work as expected.1 parent 5d0ff03 commit 0dd3d61
File tree
18 files changed
+645
-167
lines changed- build-tools/installers
- samples/HelloWorld/Properties
- src
- Xamarin.Android.Build.Tasks
- monodroid
- jni
18 files changed
+645
-167
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
159 | 159 | | |
160 | 160 | | |
161 | 161 | | |
| 162 | + | |
162 | 163 | | |
163 | 164 | | |
164 | 165 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
| 4 | + | |
5 | 5 | | |
6 | 6 | | |
Lines changed: 1 addition & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1958 | 1958 | | |
1959 | 1959 | | |
1960 | 1960 | | |
| 1961 | + | |
1961 | 1962 | | |
1962 | 1963 | | |
1963 | 1964 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
220 | 220 | | |
221 | 221 | | |
222 | 222 | | |
| 223 | + | |
| 224 | + | |
223 | 225 | | |
224 | 226 | | |
225 | 227 | | |
| |||
277 | 279 | | |
278 | 280 | | |
279 | 281 | | |
280 | | - | |
281 | 282 | | |
282 | | - | |
283 | 283 | | |
284 | 284 | | |
| 285 | + | |
285 | 286 | | |
286 | 287 | | |
287 | 288 | | |
| |||
291 | 292 | | |
292 | 293 | | |
293 | 294 | | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
294 | 301 | | |
295 | 302 | | |
296 | 303 | | |
| |||
306 | 313 | | |
307 | 314 | | |
308 | 315 | | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
309 | 325 | | |
310 | 326 | | |
311 | 327 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
225 | 225 | | |
226 | 226 | | |
227 | 227 | | |
228 | | - | |
| 228 | + | |
229 | 229 | | |
230 | 230 | | |
231 | 231 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
597 | 597 | | |
598 | 598 | | |
599 | 599 | | |
600 | | - | |
| 600 | + | |
601 | 601 | | |
602 | 602 | | |
603 | 603 | | |
| |||
0 commit comments