-
Notifications
You must be signed in to change notification settings - Fork 3.8k
[runtime] Don't try (slow) dlopen on android if it doesn't exist #12074
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
looks good. did you test this change on a device? |
|
@lewurm I haven't, I was hoping to see our CI test it on sim. I don't have any of the XA caches on my machine currently. |
|
@alexanderkyte CI will not give you any result because of #12094 |
|
@lewurm @luhenry That indicates that this works on android (or passes those tests). |
The one outstanding failure seen on CI: ^ |
|
@monojenkins backport 2018-08 As requested by @jonpryor |
) [2018-12] [runtime] Don\u0027t try (slow) dlopen on android if it doesn\u0027t exist On android, the dlopen call will take around 1ms per AOT module we try to load. By not using dlopen with the existence check, we rely on a much slower dlopen check that happens later. I think they support dlopen of non-resolved names. This might break a few things if we don't use the full path to dlopen. If it does, we should probably add existence checks at the caller, but this will be an optimization that works everywhere. @jonpryor @grendello Backport of #12074. /cc @alexanderkyte
|
Going to need to revert this one. It's been identified as the cause of dotnet/android#3388 |
The intention of calling `g_file_test (file, G_FILE_TEST_EXISTS)` where file is the name of a shared library we want to open is to speed up probing for non-existent libraries. See mono#12074 The problem is that if file is just a simple "libdl.so" then `dlopen (file)` doesn't just look for it in the current working directory, it will probe some other paths too. (For example on desktop linux you'd also look in all the directories in LD_LIBRARY_PATH). So the g_file_test() call is not a robust way to avoid calling dlopen if the filename is relative. But it actually broke more things: dotnet/android#3388 When probing for "libdl.so" on Android mono_lookup_pinvoke_call will first try prepending some paths that it knows about and we end up calling `dlopen ("/system/lib/libdl.so")` which will fail because Bionic has security restrictions on what code can dlopen something from /system/lib with an absolute path. Eventually mono_lookup_pinvoke_call will go back to trying the bare "libdl.so" which hits `g_file_test` and returns NULL. The new code only does the file test if we pass it an absolute path, which gives Bionic's dlopen a chance to deal with relative paths however it needs to.
The intention of calling `g_file_test (file, G_FILE_TEST_EXISTS)` where file is the name of a shared library we want to open is to speed up probing for non-existent libraries. See mono#12074 The problem is that if file is just a simple "libdl.so" then `dlopen (file)` doesn't just look for it in the current working directory, it will probe some other paths too. (For example on desktop linux you'd also look in all the directories in LD_LIBRARY_PATH). So the g_file_test() call is not a robust way to avoid calling dlopen if the filename is relative. But it actually broke more things: dotnet/android#3388 When probing for "libdl.so" on Android mono_lookup_pinvoke_call will first try prepending some paths that it knows about and we end up calling `dlopen ("/system/lib/libdl.so")` which will fail because Bionic has security restrictions on what code can dlopen something from /system/lib with an absolute path. Eventually mono_lookup_pinvoke_call will go back to trying the bare "libdl.so" which hits `g_file_test` and returns NULL. The new code only does the file test if we pass it an absolute path, which gives Bionic's dlopen a chance to deal with relative paths however it needs to.
The intention of calling `g_file_test (file, G_FILE_TEST_EXISTS)` where file is the name of a shared library we want to open is to speed up probing for non-existent libraries. See mono#12074 The problem is that if file is just a simple "libdl.so" then `dlopen (file)` doesn't just look for it in the current working directory, it will probe some other paths too. (For example on desktop linux you'd also look in all the directories in LD_LIBRARY_PATH). So the g_file_test() call is not a robust way to avoid calling dlopen if the filename is relative. But it actually broke more things: dotnet/android#3388 When probing for "libdl.so" on Android mono_lookup_pinvoke_call will first try prepending some paths that it knows about and we end up calling `dlopen ("/system/lib/libdl.so")` which will fail because Bionic has security restrictions on what code can dlopen something from /system/lib with an absolute path. Eventually mono_lookup_pinvoke_call will go back to trying the bare "libdl.so" which hits `g_file_test` and returns NULL. The new code only does the file test if we pass it an absolute path, which gives Bionic's dlopen a chance to deal with relative paths however it needs to.
…16387) The intention of calling `g_file_test (file, G_FILE_TEST_EXISTS)` where file is the name of a shared library we want to open is to speed up probing for non-existent libraries. See #12074 The problem is that if file is just a simple "libdl.so" then `dlopen (file)` doesn't just look for it in the current working directory, it will probe some other paths too. (For example on desktop linux you'd also look in all the directories in LD_LIBRARY_PATH). So the g_file_test() call is not a robust way to avoid calling dlopen if the filename is relative. But it actually broke more things: dotnet/android#3388 When probing for "libdl.so" on Android mono_lookup_pinvoke_call will first try prepending some paths that it knows about and we end up calling `dlopen ("/system/lib/libdl.so")` which will fail because Bionic has security restrictions on what code can dlopen something from /system/lib with an absolute path. Eventually mono_lookup_pinvoke_call will go back to trying the bare "libdl.so" which hits `g_file_test` and returns NULL. The new code only does the file test if we pass it an absolute path, which gives Bionic's dlopen a chance to deal with relative paths however it needs to.
…16392) The intention of calling `g_file_test (file, G_FILE_TEST_EXISTS)` where file is the name of a shared library we want to open is to speed up probing for non-existent libraries. See #12074 The problem is that if file is just a simple "libdl.so" then `dlopen (file)` doesn't just look for it in the current working directory, it will probe some other paths too. (For example on desktop linux you'd also look in all the directories in LD_LIBRARY_PATH). So the g_file_test() call is not a robust way to avoid calling dlopen if the filename is relative. But it actually broke more things: dotnet/android#3388 When probing for "libdl.so" on Android mono_lookup_pinvoke_call will first try prepending some paths that it knows about and we end up calling `dlopen ("/system/lib/libdl.so")` which will fail because Bionic has security restrictions on what code can dlopen something from /system/lib with an absolute path. Eventually mono_lookup_pinvoke_call will go back to trying the bare "libdl.so" which hits `g_file_test` and returns NULL. The new code only does the file test if we pass it an absolute path, which gives Bionic's dlopen a chance to deal with relative paths however it needs to.
…16393) The intention of calling `g_file_test (file, G_FILE_TEST_EXISTS)` where file is the name of a shared library we want to open is to speed up probing for non-existent libraries. See #12074 The problem is that if file is just a simple "libdl.so" then `dlopen (file)` doesn't just look for it in the current working directory, it will probe some other paths too. (For example on desktop linux you'd also look in all the directories in LD_LIBRARY_PATH). So the g_file_test() call is not a robust way to avoid calling dlopen if the filename is relative. But it actually broke more things: dotnet/android#3388 When probing for "libdl.so" on Android mono_lookup_pinvoke_call will first try prepending some paths that it knows about and we end up calling `dlopen ("/system/lib/libdl.so")` which will fail because Bionic has security restrictions on what code can dlopen something from /system/lib with an absolute path. Eventually mono_lookup_pinvoke_call will go back to trying the bare "libdl.so" which hits `g_file_test` and returns NULL. The new code only does the file test if we pass it an absolute path, which gives Bionic's dlopen a chance to deal with relative paths however it needs to.
…ono/mono#16387) The intention of calling `g_file_test (file, G_FILE_TEST_EXISTS)` where file is the name of a shared library we want to open is to speed up probing for non-existent libraries. See mono/mono#12074 The problem is that if file is just a simple "libdl.so" then `dlopen (file)` doesn't just look for it in the current working directory, it will probe some other paths too. (For example on desktop linux you'd also look in all the directories in LD_LIBRARY_PATH). So the g_file_test() call is not a robust way to avoid calling dlopen if the filename is relative. But it actually broke more things: dotnet/android#3388 When probing for "libdl.so" on Android mono_lookup_pinvoke_call will first try prepending some paths that it knows about and we end up calling `dlopen ("/system/lib/libdl.so")` which will fail because Bionic has security restrictions on what code can dlopen something from /system/lib with an absolute path. Eventually mono_lookup_pinvoke_call will go back to trying the bare "libdl.so" which hits `g_file_test` and returns NULL. The new code only does the file test if we pass it an absolute path, which gives Bionic's dlopen a chance to deal with relative paths however it needs to. Commit migrated from mono/mono@e74736a
On android, the dlopen call will take around 1ms per AOT module we try to load. By not using dlopen with the existence check, we rely on a much slower dlopen check that happens later. I think they support dlopen of non-resolved names.
This might break a few things if we don't use the full path to dlopen. If it does, we should probably add existence checks at the caller, but this will be an optimization that works everywhere.
@jonpryor @grendello