1 /*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "java_vm_ext-inl.h"
18
19 #include <dlfcn.h>
20 #include <string_view>
21
22 #include "android-base/stringprintf.h"
23
24 #include "art_method-inl.h"
25 #include "base/dumpable.h"
26 #include "base/mutex-inl.h"
27 #include "base/sdk_version.h"
28 #include "base/stl_util.h"
29 #include "base/systrace.h"
30 #include "check_jni.h"
31 #include "dex/dex_file-inl.h"
32 #include "entrypoints/entrypoint_utils-inl.h"
33 #include "fault_handler.h"
34 #include "gc/allocation_record.h"
35 #include "gc/heap.h"
36 #include "gc_root-inl.h"
37 #include "indirect_reference_table-inl.h"
38 #include "jni_internal.h"
39 #include "mirror/class-inl.h"
40 #include "mirror/class_loader.h"
41 #include "mirror/dex_cache-inl.h"
42 #include "nativebridge/native_bridge.h"
43 #include "nativehelper/scoped_local_ref.h"
44 #include "nativehelper/scoped_utf_chars.h"
45 #include "nativeloader/native_loader.h"
46 #include "parsed_options.h"
47 #include "runtime-inl.h"
48 #include "runtime_options.h"
49 #include "scoped_thread_state_change-inl.h"
50 #include "sigchain.h"
51 #include "thread-inl.h"
52 #include "thread_list.h"
53 #include "ti/agent.h"
54 #include "well_known_classes-inl.h"
55
56 namespace art HIDDEN {
57
58 using android::base::StringAppendF;
59 using android::base::StringAppendV;
60
61 // Maximum number of global references (must fit in 16 bits).
62 static constexpr size_t kGlobalsMax = 51200;
63
64 // Maximum number of weak global references (must fit in 16 bits).
65 static constexpr size_t kWeakGlobalsMax = 51200;
66
IsBadJniVersion(int version)67 bool JavaVMExt::IsBadJniVersion(int version) {
68 // We don't support JNI_VERSION_1_1. These are the only other valid versions.
69 return version != JNI_VERSION_1_2 && version != JNI_VERSION_1_4 && version != JNI_VERSION_1_6;
70 }
71
72 class SharedLibrary {
73 public:
SharedLibrary(JNIEnv * env,Thread * self,const std::string & path,void * handle,bool needs_native_bridge,jobject class_loader,void * class_loader_allocator)74 SharedLibrary(JNIEnv* env, Thread* self, const std::string& path, void* handle,
75 bool needs_native_bridge, jobject class_loader, void* class_loader_allocator)
76 : path_(path),
77 handle_(handle),
78 needs_native_bridge_(needs_native_bridge),
79 class_loader_(env->NewWeakGlobalRef(class_loader)),
80 class_loader_allocator_(class_loader_allocator),
81 jni_on_load_lock_("JNI_OnLoad lock"),
82 jni_on_load_cond_("JNI_OnLoad condition variable", jni_on_load_lock_),
83 jni_on_load_thread_id_(self->GetThreadId()),
84 jni_on_load_result_(kPending) {
85 CHECK(class_loader_allocator_ != nullptr);
86 }
87
~SharedLibrary()88 ~SharedLibrary() {
89 Thread* self = Thread::Current();
90 if (self != nullptr) {
91 self->GetJniEnv()->DeleteWeakGlobalRef(class_loader_);
92 }
93
94 char* error_msg = nullptr;
95 if (!android::CloseNativeLibrary(handle_, needs_native_bridge_, &error_msg)) {
96 LOG(WARNING) << "Error while unloading native library \"" << path_ << "\": " << error_msg;
97 android::NativeLoaderFreeErrorMessage(error_msg);
98 }
99 }
100
GetClassLoader() const101 jweak GetClassLoader() const {
102 return class_loader_;
103 }
104
GetClassLoaderAllocator() const105 const void* GetClassLoaderAllocator() const {
106 return class_loader_allocator_;
107 }
108
GetPath() const109 const std::string& GetPath() const {
110 return path_;
111 }
112
113 /*
114 * Check the result of an earlier call to JNI_OnLoad on this library.
115 * If the call has not yet finished in another thread, wait for it.
116 */
CheckOnLoadResult()117 bool CheckOnLoadResult()
118 REQUIRES(!jni_on_load_lock_) {
119 Thread* self = Thread::Current();
120 bool okay;
121 {
122 MutexLock mu(self, jni_on_load_lock_);
123
124 if (jni_on_load_thread_id_ == self->GetThreadId()) {
125 // Check this so we don't end up waiting for ourselves. We need to return "true" so the
126 // caller can continue.
127 LOG(INFO) << *self << " recursive attempt to load library " << "\"" << path_ << "\"";
128 okay = true;
129 } else {
130 while (jni_on_load_result_ == kPending) {
131 VLOG(jni) << "[" << *self << " waiting for \"" << path_ << "\" " << "JNI_OnLoad...]";
132 jni_on_load_cond_.Wait(self);
133 }
134
135 okay = (jni_on_load_result_ == kOkay);
136 VLOG(jni) << "[Earlier JNI_OnLoad for \"" << path_ << "\" "
137 << (okay ? "succeeded" : "failed") << "]";
138 }
139 }
140 return okay;
141 }
142
SetResult(bool result)143 void SetResult(bool result) REQUIRES(!jni_on_load_lock_) {
144 Thread* self = Thread::Current();
145 MutexLock mu(self, jni_on_load_lock_);
146
147 jni_on_load_result_ = result ? kOkay : kFailed;
148 jni_on_load_thread_id_ = 0;
149
150 // Broadcast a wakeup to anybody sleeping on the condition variable.
151 jni_on_load_cond_.Broadcast(self);
152 }
153
SetNeedsNativeBridge(bool needs)154 void SetNeedsNativeBridge(bool needs) {
155 needs_native_bridge_ = needs;
156 }
157
NeedsNativeBridge() const158 bool NeedsNativeBridge() const {
159 return needs_native_bridge_;
160 }
161
162 // No mutator lock since dlsym may block for a while if another thread is doing dlopen.
FindSymbol(const std::string & symbol_name,const char * shorty,android::JNICallType jni_call_type)163 void* FindSymbol(const std::string& symbol_name,
164 const char* shorty,
165 android::JNICallType jni_call_type) REQUIRES(!Locks::mutator_lock_) {
166 return NeedsNativeBridge() ? FindSymbolWithNativeBridge(symbol_name, shorty, jni_call_type) :
167 FindSymbolWithoutNativeBridge(symbol_name);
168 }
169
170 // No mutator lock since dlsym may block for a while if another thread is doing dlopen.
FindSymbolWithoutNativeBridge(const std::string & symbol_name)171 void* FindSymbolWithoutNativeBridge(const std::string& symbol_name)
172 REQUIRES(!Locks::mutator_lock_) {
173 CHECK(!NeedsNativeBridge());
174
175 return dlsym(handle_, symbol_name.c_str());
176 }
177
FindSymbolWithNativeBridge(const std::string & symbol_name,const char * shorty,android::JNICallType jni_call_type)178 void* FindSymbolWithNativeBridge(const std::string& symbol_name,
179 const char* shorty,
180 android::JNICallType jni_call_type)
181 REQUIRES(!Locks::mutator_lock_) {
182 CHECK(NeedsNativeBridge());
183
184 uint32_t len = 0;
185 return android::NativeBridgeGetTrampoline2(
186 handle_, symbol_name.c_str(), shorty, len, jni_call_type);
187 }
188
189 private:
190 enum JNI_OnLoadState {
191 kPending,
192 kFailed,
193 kOkay,
194 };
195
196 // Path to library "/system/lib/libjni.so".
197 const std::string path_;
198
199 // The void* returned by dlopen(3).
200 void* const handle_;
201
202 // True if a native bridge is required.
203 bool needs_native_bridge_;
204
205 // The ClassLoader this library is associated with, a weak global JNI reference that is
206 // created/deleted with the scope of the library.
207 const jweak class_loader_;
208 // Used to do equality check on class loaders so we can avoid decoding the weak root and read
209 // barriers that mess with class unloading.
210 const void* class_loader_allocator_;
211
212 // Guards remaining items.
213 Mutex jni_on_load_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
214 // Wait for JNI_OnLoad in other thread.
215 ConditionVariable jni_on_load_cond_ GUARDED_BY(jni_on_load_lock_);
216 // Recursive invocation guard.
217 uint32_t jni_on_load_thread_id_ GUARDED_BY(jni_on_load_lock_);
218 // Result of earlier JNI_OnLoad call.
219 JNI_OnLoadState jni_on_load_result_ GUARDED_BY(jni_on_load_lock_);
220 };
221
222 // This exists mainly to keep implementation details out of the header file.
223 class Libraries {
224 public:
Libraries()225 Libraries() {
226 }
227
~Libraries()228 ~Libraries() {
229 STLDeleteValues(&libraries_);
230 }
231
232 // NO_THREAD_SAFETY_ANALYSIS as this is during runtime shutdown, and we have
233 // no thread to lock this with.
UnloadBootNativeLibraries(JavaVM * vm) const234 void UnloadBootNativeLibraries(JavaVM* vm) const NO_THREAD_SAFETY_ANALYSIS {
235 CHECK(Thread::Current() == nullptr);
236 std::vector<SharedLibrary*> unload_libraries;
237 for (auto it = libraries_.begin(); it != libraries_.end(); ++it) {
238 SharedLibrary* const library = it->second;
239 if (library->GetClassLoader() == nullptr) {
240 unload_libraries.push_back(library);
241 }
242 }
243 UnloadLibraries(vm, unload_libraries);
244 }
245
246 // NO_THREAD_SAFETY_ANALYSIS since this may be called from Dumpable. Dumpable can't be annotated
247 // properly due to the template. The caller should be holding the jni_libraries_lock_.
Dump(std::ostream & os) const248 void Dump(std::ostream& os) const NO_THREAD_SAFETY_ANALYSIS {
249 Locks::jni_libraries_lock_->AssertHeld(Thread::Current());
250 bool first = true;
251 for (const auto& library : libraries_) {
252 if (!first) {
253 os << ' ';
254 }
255 first = false;
256 os << library.first;
257 }
258 }
259
size() const260 size_t size() const REQUIRES(Locks::jni_libraries_lock_) {
261 return libraries_.size();
262 }
263
Get(const std::string & path)264 SharedLibrary* Get(const std::string& path) REQUIRES(Locks::jni_libraries_lock_) {
265 auto it = libraries_.find(path);
266 return (it == libraries_.end()) ? nullptr : it->second;
267 }
268
Put(const std::string & path,SharedLibrary * library)269 void Put(const std::string& path, SharedLibrary* library)
270 REQUIRES(Locks::jni_libraries_lock_) {
271 libraries_.Put(path, library);
272 }
273
274 // See section 11.3 "Linking Native Methods" of the JNI spec.
FindNativeMethod(Thread * self,ArtMethod * m,std::string * detail,bool can_suspend)275 void* FindNativeMethod(Thread* self, ArtMethod* m, std::string* detail, bool can_suspend)
276 REQUIRES(!Locks::jni_libraries_lock_)
277 REQUIRES_SHARED(Locks::mutator_lock_) {
278 std::string jni_short_name(m->JniShortName());
279 std::string jni_long_name(m->JniLongName());
280 const ObjPtr<mirror::ClassLoader> declaring_class_loader =
281 m->GetDeclaringClass()->GetClassLoader();
282 void* const declaring_class_loader_allocator =
283 Runtime::Current()->GetClassLinker()->GetAllocatorForClassLoader(declaring_class_loader);
284 CHECK(declaring_class_loader_allocator != nullptr);
285 // TODO: Avoid calling GetShorty here to prevent dirtying dex pages?
286 const char* shorty = m->GetShorty();
287 void* native_code = nullptr;
288 android::JNICallType jni_call_type =
289 m->IsCriticalNative() ? android::kJNICallTypeCriticalNative : android::kJNICallTypeRegular;
290 if (can_suspend) {
291 // Go to suspended since dlsym may block for a long time if other threads are using dlopen.
292 ScopedThreadSuspension sts(self, ThreadState::kNative);
293 native_code = FindNativeMethodInternal(self,
294 declaring_class_loader_allocator,
295 shorty,
296 jni_short_name,
297 jni_long_name,
298 jni_call_type);
299 } else {
300 native_code = FindNativeMethodInternal(self,
301 declaring_class_loader_allocator,
302 shorty,
303 jni_short_name,
304 jni_long_name,
305 jni_call_type);
306 }
307 if (native_code != nullptr) {
308 return native_code;
309 }
310 if (detail != nullptr) {
311 *detail += "No implementation found for ";
312 *detail += m->PrettyMethod();
313 *detail += " (tried " + jni_short_name + " and " + jni_long_name + ")";
314 *detail += " - is the library loaded, e.g. System.loadLibrary?";
315 }
316 return nullptr;
317 }
318
FindNativeMethodInternal(Thread * self,void * declaring_class_loader_allocator,const char * shorty,const std::string & jni_short_name,const std::string & jni_long_name,android::JNICallType jni_call_type)319 void* FindNativeMethodInternal(Thread* self,
320 void* declaring_class_loader_allocator,
321 const char* shorty,
322 const std::string& jni_short_name,
323 const std::string& jni_long_name,
324 android::JNICallType jni_call_type)
325 REQUIRES(!Locks::jni_libraries_lock_) {
326 MutexLock mu(self, *Locks::jni_libraries_lock_);
327 for (const auto& lib : libraries_) {
328 SharedLibrary* const library = lib.second;
329 // Use the allocator address for class loader equality to avoid unnecessary weak root decode.
330 if (library->GetClassLoaderAllocator() != declaring_class_loader_allocator) {
331 // We only search libraries loaded by the appropriate ClassLoader.
332 continue;
333 }
334 // Try the short name then the long name...
335 const char* arg_shorty = library->NeedsNativeBridge() ? shorty : nullptr;
336 void* fn = library->FindSymbol(jni_short_name, arg_shorty, jni_call_type);
337 if (fn == nullptr) {
338 fn = library->FindSymbol(jni_long_name, arg_shorty, jni_call_type);
339 }
340 if (fn != nullptr) {
341 VLOG(jni) << "[Found native code for " << jni_long_name
342 << " in \"" << library->GetPath() << "\"]";
343 return fn;
344 }
345 }
346 return nullptr;
347 }
348
349 // Unload native libraries with cleared class loaders.
UnloadNativeLibraries()350 void UnloadNativeLibraries()
351 REQUIRES(!Locks::jni_libraries_lock_)
352 REQUIRES_SHARED(Locks::mutator_lock_) {
353 Thread* const self = Thread::Current();
354 std::vector<SharedLibrary*> unload_libraries;
355 {
356 // jni_libraries_lock_ appears to be held long enough that we just retry once, rather than
357 // spinning.
358 int retries = 0;
359 static constexpr int MAX_RETRIES = 5;
360 while (!Locks::jni_libraries_lock_->ExclusiveTryLock(self)) {
361 if (Runtime::Current()->IsZygote()) {
362 // Do not risk deferring to the child processes.
363 Locks::jni_libraries_lock_->ExclusiveLock(self);
364 break;
365 }
366 if (++retries > MAX_RETRIES) {
367 // We do not want to block indefinitely here, for fear of timeouts. See b/374209523.
368 LOG(WARNING) << "Deferring native library unloading due to contention";
369 return;
370 }
371 ScopedTrace("sleep 1 msec for jni_libraries_lock_");
372 usleep(1000);
373 }
374 for (auto it = libraries_.begin(); it != libraries_.end(); ) {
375 SharedLibrary* const library = it->second;
376 // If class loader is null then it was unloaded, call JNI_OnUnload.
377 const jweak class_loader = library->GetClassLoader();
378 // If class_loader is a null jobject then it is the boot class loader. We should not unload
379 // the native libraries of the boot class loader.
380 if (class_loader != nullptr && self->IsJWeakCleared(class_loader)) {
381 unload_libraries.push_back(library);
382 it = libraries_.erase(it);
383 } else {
384 ++it;
385 }
386 }
387 Locks::jni_libraries_lock_->ExclusiveUnlock(self);
388 }
389 ScopedThreadSuspension sts(self, ThreadState::kNative);
390 // Do this without holding the jni libraries lock to prevent possible deadlocks.
391 UnloadLibraries(self->GetJniEnv()->GetVm(), unload_libraries);
392 for (auto library : unload_libraries) {
393 delete library;
394 }
395 }
396
UnloadLibraries(JavaVM * vm,const std::vector<SharedLibrary * > & libraries)397 static void UnloadLibraries(JavaVM* vm, const std::vector<SharedLibrary*>& libraries) {
398 using JNI_OnUnloadFn = void(*)(JavaVM*, void*);
399 for (SharedLibrary* library : libraries) {
400 void* const sym = library->FindSymbol("JNI_OnUnload", nullptr, android::kJNICallTypeRegular);
401 if (sym == nullptr) {
402 VLOG(jni) << "[No JNI_OnUnload found in \"" << library->GetPath() << "\"]";
403 } else {
404 VLOG(jni) << "[JNI_OnUnload found for \"" << library->GetPath() << "\"]: Calling...";
405 JNI_OnUnloadFn jni_on_unload = reinterpret_cast<JNI_OnUnloadFn>(sym);
406 jni_on_unload(vm, nullptr);
407 }
408 }
409 }
410
411 private:
412 AllocationTrackingSafeMap<std::string, SharedLibrary*, kAllocatorTagJNILibraries> libraries_
413 GUARDED_BY(Locks::jni_libraries_lock_);
414 };
415
416 class JII {
417 public:
DestroyJavaVM(JavaVM * vm)418 static jint DestroyJavaVM(JavaVM* vm) {
419 if (vm == nullptr) {
420 return JNI_ERR;
421 }
422 JavaVMExt* raw_vm = reinterpret_cast<JavaVMExt*>(vm);
423
424 // Wait for all non-dameon threads to terminate before we start destroying
425 // bits of the runtime. Thread list deletion will repeat this in case more
426 // threads are created by daemons in the meantime.
427 raw_vm->GetRuntime()->GetThreadList()
428 ->WaitForOtherNonDaemonThreadsToExit(/*check_no_birth=*/ false);
429
430 delete raw_vm->GetRuntime();
431 android::ResetNativeLoader();
432 return JNI_OK;
433 }
434
AttachCurrentThread(JavaVM * vm,JNIEnv ** p_env,void * thr_args)435 static jint AttachCurrentThread(JavaVM* vm, JNIEnv** p_env, void* thr_args) {
436 return AttachCurrentThreadInternal(vm, p_env, thr_args, false);
437 }
438
AttachCurrentThreadAsDaemon(JavaVM * vm,JNIEnv ** p_env,void * thr_args)439 static jint AttachCurrentThreadAsDaemon(JavaVM* vm, JNIEnv** p_env, void* thr_args) {
440 return AttachCurrentThreadInternal(vm, p_env, thr_args, true);
441 }
442
DetachCurrentThread(JavaVM * vm)443 static jint DetachCurrentThread(JavaVM* vm) {
444 if (vm == nullptr || Thread::Current() == nullptr) {
445 return JNI_ERR;
446 }
447 JavaVMExt* raw_vm = reinterpret_cast<JavaVMExt*>(vm);
448 Runtime* runtime = raw_vm->GetRuntime();
449 runtime->DetachCurrentThread();
450 return JNI_OK;
451 }
452
GetEnv(JavaVM * vm,void ** env,jint version)453 static jint GetEnv(JavaVM* vm, void** env, jint version) {
454 if (vm == nullptr || env == nullptr) {
455 return JNI_ERR;
456 }
457 Thread* thread = Thread::Current();
458 if (thread == nullptr) {
459 *env = nullptr;
460 return JNI_EDETACHED;
461 }
462 JavaVMExt* raw_vm = reinterpret_cast<JavaVMExt*>(vm);
463 return raw_vm->HandleGetEnv(env, version);
464 }
465
466 private:
AttachCurrentThreadInternal(JavaVM * vm,JNIEnv ** p_env,void * raw_args,bool as_daemon)467 static jint AttachCurrentThreadInternal(JavaVM* vm, JNIEnv** p_env, void* raw_args, bool as_daemon) {
468 if (vm == nullptr || p_env == nullptr) {
469 return JNI_ERR;
470 }
471
472 // Return immediately if we're already attached.
473 Thread* self = Thread::Current();
474 if (self != nullptr) {
475 *p_env = self->GetJniEnv();
476 return JNI_OK;
477 }
478
479 Runtime* runtime = reinterpret_cast<JavaVMExt*>(vm)->GetRuntime();
480
481 // No threads allowed in zygote mode.
482 if (runtime->IsZygote()) {
483 LOG(ERROR) << "Attempt to attach a thread in the zygote";
484 return JNI_ERR;
485 }
486
487 JavaVMAttachArgs* args = static_cast<JavaVMAttachArgs*>(raw_args);
488 const char* thread_name = nullptr;
489 jobject thread_group = nullptr;
490 if (args != nullptr) {
491 if (JavaVMExt::IsBadJniVersion(args->version)) {
492 LOG(ERROR) << "Bad JNI version passed to "
493 << (as_daemon ? "AttachCurrentThreadAsDaemon" : "AttachCurrentThread") << ": "
494 << args->version;
495 return JNI_EVERSION;
496 }
497 thread_name = args->name;
498 thread_group = args->group;
499 }
500
501 if (!runtime->AttachCurrentThread(thread_name, as_daemon, thread_group,
502 !runtime->IsAotCompiler())) {
503 *p_env = nullptr;
504 return JNI_ERR;
505 } else {
506 *p_env = Thread::Current()->GetJniEnv();
507 return JNI_OK;
508 }
509 }
510 };
511
512 const JNIInvokeInterface gJniInvokeInterface = {
513 nullptr, // reserved0
514 nullptr, // reserved1
515 nullptr, // reserved2
516 JII::DestroyJavaVM,
517 JII::AttachCurrentThread,
518 JII::DetachCurrentThread,
519 JII::GetEnv,
520 JII::AttachCurrentThreadAsDaemon
521 };
522
JavaVMExt(Runtime * runtime,const RuntimeArgumentMap & runtime_options)523 JavaVMExt::JavaVMExt(Runtime* runtime, const RuntimeArgumentMap& runtime_options)
524 : runtime_(runtime),
525 check_jni_abort_hook_(nullptr),
526 check_jni_abort_hook_data_(nullptr),
527 check_jni_(false), // Initialized properly in the constructor body below.
528 force_copy_(runtime_options.Exists(RuntimeArgumentMap::JniOptsForceCopy)),
529 tracing_enabled_(runtime_options.Exists(RuntimeArgumentMap::JniTrace)
530 || VLOG_IS_ON(third_party_jni)),
531 trace_(runtime_options.GetOrDefault(RuntimeArgumentMap::JniTrace)),
532 globals_(kGlobal),
533 libraries_(new Libraries),
534 unchecked_functions_(&gJniInvokeInterface),
535 weak_globals_(kWeakGlobal),
536 allow_accessing_weak_globals_(true),
537 weak_globals_add_condition_("weak globals add condition",
538 (CHECK(Locks::jni_weak_globals_lock_ != nullptr),
539 *Locks::jni_weak_globals_lock_)),
540 env_hooks_lock_("environment hooks lock", art::kGenericBottomLock),
541 env_hooks_(),
542 enable_allocation_tracking_delta_(
543 runtime_options.GetOrDefault(RuntimeArgumentMap::GlobalRefAllocStackTraceLimit)),
544 allocation_tracking_enabled_(false),
545 old_allocation_tracking_state_(false) {
546 functions = unchecked_functions_;
547 SetCheckJniEnabled(runtime_options.Exists(RuntimeArgumentMap::CheckJni) || kIsDebugBuild);
548 }
549
Initialize(std::string * error_msg)550 bool JavaVMExt::Initialize(std::string* error_msg) {
551 return globals_.Initialize(kGlobalsMax, error_msg) &&
552 weak_globals_.Initialize(kWeakGlobalsMax, error_msg);
553 }
554
~JavaVMExt()555 JavaVMExt::~JavaVMExt() {
556 UnloadBootNativeLibraries();
557 }
558
Create(Runtime * runtime,const RuntimeArgumentMap & runtime_options,std::string * error_msg)559 std::unique_ptr<JavaVMExt> JavaVMExt::Create(Runtime* runtime,
560 const RuntimeArgumentMap& runtime_options,
561 std::string* error_msg) {
562 std::unique_ptr<JavaVMExt> java_vm(new JavaVMExt(runtime, runtime_options));
563 if (!java_vm->Initialize(error_msg)) {
564 return nullptr;
565 }
566 return java_vm;
567 }
568
HandleGetEnv(void ** env,jint version)569 jint JavaVMExt::HandleGetEnv(/*out*/void** env, jint version) {
570 std::vector<GetEnvHook> env_hooks;
571 {
572 ReaderMutexLock rmu(Thread::Current(), env_hooks_lock_);
573 env_hooks.assign(env_hooks_.begin(), env_hooks_.end());
574 }
575 for (GetEnvHook hook : env_hooks) {
576 jint res = hook(this, env, version);
577 if (res == JNI_OK) {
578 return JNI_OK;
579 } else if (res != JNI_EVERSION) {
580 LOG(ERROR) << "Error returned from a plugin GetEnv handler! " << res;
581 return res;
582 }
583 }
584 LOG(ERROR) << "Bad JNI version passed to GetEnv: " << version;
585 return JNI_EVERSION;
586 }
587
588 // Add a hook to handle getting environments from the GetEnv call.
AddEnvironmentHook(GetEnvHook hook)589 void JavaVMExt::AddEnvironmentHook(GetEnvHook hook) {
590 CHECK(hook != nullptr) << "environment hooks shouldn't be null!";
591 WriterMutexLock wmu(Thread::Current(), env_hooks_lock_);
592 env_hooks_.push_back(hook);
593 }
594
JniAbort(const char * jni_function_name,const char * msg)595 void JavaVMExt::JniAbort(const char* jni_function_name, const char* msg) {
596 Thread* self = Thread::Current();
597 ScopedObjectAccess soa(self);
598 ArtMethod* current_method = self->GetCurrentMethod(nullptr);
599
600 std::ostringstream os;
601 os << "JNI DETECTED ERROR IN APPLICATION: " << msg;
602
603 if (jni_function_name != nullptr) {
604 os << "\n in call to " << jni_function_name;
605 }
606 // TODO: is this useful given that we're about to dump the calling thread's stack?
607 if (current_method != nullptr) {
608 os << "\n from " << current_method->PrettyMethod();
609 }
610
611 if (check_jni_abort_hook_ != nullptr) {
612 check_jni_abort_hook_(check_jni_abort_hook_data_, os.str());
613 } else {
614 // Ensure that we get a native stack trace for this thread.
615 ScopedThreadSuspension sts(self, ThreadState::kNative);
616 LOG(FATAL) << os.str();
617 UNREACHABLE();
618 }
619 }
620
JniAbortV(const char * jni_function_name,const char * fmt,va_list ap)621 void JavaVMExt::JniAbortV(const char* jni_function_name, const char* fmt, va_list ap) {
622 std::string msg;
623 StringAppendV(&msg, fmt, ap);
624 JniAbort(jni_function_name, msg.c_str());
625 }
626
JniAbortF(const char * jni_function_name,const char * fmt,...)627 void JavaVMExt::JniAbortF(const char* jni_function_name, const char* fmt, ...) {
628 va_list args;
629 va_start(args, fmt);
630 JniAbortV(jni_function_name, fmt, args);
631 va_end(args);
632 }
633
ShouldTrace(ArtMethod * method)634 bool JavaVMExt::ShouldTrace(ArtMethod* method) {
635 // Fast where no tracing is enabled.
636 if (trace_.empty() && !VLOG_IS_ON(third_party_jni)) {
637 return false;
638 }
639 // Perform checks based on class name.
640 std::string_view class_name = method->GetDeclaringClassDescriptorView();
641 if (!trace_.empty() && class_name.find(trace_) != std::string_view::npos) {
642 return true;
643 }
644 if (!VLOG_IS_ON(third_party_jni)) {
645 return false;
646 }
647 // Return true if we're trying to log all third-party JNI activity and 'method' doesn't look
648 // like part of Android.
649 static const char* const gBuiltInPrefixes[] = {
650 "Landroid/",
651 "Lcom/android/",
652 "Lcom/google/android/",
653 "Ldalvik/",
654 "Ljava/",
655 "Ljavax/",
656 "Llibcore/",
657 "Lorg/apache/harmony/",
658 };
659 for (size_t i = 0; i < arraysize(gBuiltInPrefixes); ++i) {
660 if (class_name.starts_with(gBuiltInPrefixes[i])) {
661 return false;
662 }
663 }
664 return true;
665 }
666
CheckGlobalRefAllocationTracking()667 void JavaVMExt::CheckGlobalRefAllocationTracking() {
668 if (LIKELY(enable_allocation_tracking_delta_ == 0)) {
669 return;
670 }
671 size_t simple_free_capacity = globals_.FreeCapacity();
672 if (UNLIKELY(simple_free_capacity <= enable_allocation_tracking_delta_)) {
673 if (!allocation_tracking_enabled_) {
674 LOG(WARNING) << "Global reference storage appears close to exhaustion, program termination "
675 << "may be imminent. Enabling allocation tracking to improve abort diagnostics. "
676 << "This will result in program slow-down.";
677
678 old_allocation_tracking_state_ = runtime_->GetHeap()->IsAllocTrackingEnabled();
679 if (!old_allocation_tracking_state_) {
680 // Need to be guaranteed suspended.
681 ScopedObjectAccess soa(Thread::Current());
682 ScopedThreadSuspension sts(soa.Self(), ThreadState::kNative);
683 gc::AllocRecordObjectMap::SetAllocTrackingEnabled(true);
684 }
685 allocation_tracking_enabled_ = true;
686 }
687 } else {
688 if (UNLIKELY(allocation_tracking_enabled_)) {
689 if (!old_allocation_tracking_state_) {
690 // Need to be guaranteed suspended.
691 ScopedObjectAccess soa(Thread::Current());
692 ScopedThreadSuspension sts(soa.Self(), ThreadState::kNative);
693 gc::AllocRecordObjectMap::SetAllocTrackingEnabled(false);
694 }
695 allocation_tracking_enabled_ = false;
696 }
697 }
698 }
699
MaybeTraceGlobals()700 void JavaVMExt::MaybeTraceGlobals() {
701 if (global_ref_report_counter_++ == kGlobalRefReportInterval) {
702 global_ref_report_counter_ = 1;
703 ATraceIntegerValue("JNI Global Refs", globals_.NEntriesForGlobal());
704 }
705 }
706
MaybeTraceWeakGlobals()707 void JavaVMExt::MaybeTraceWeakGlobals() {
708 if (weak_global_ref_report_counter_++ == kGlobalRefReportInterval) {
709 weak_global_ref_report_counter_ = 1;
710 ATraceIntegerValue("JNI Weak Global Refs", weak_globals_.NEntriesForGlobal());
711 }
712 }
713
AddGlobalRef(Thread * self,ObjPtr<mirror::Object> obj)714 jobject JavaVMExt::AddGlobalRef(Thread* self, ObjPtr<mirror::Object> obj) {
715 // Check for null after decoding the object to handle cleared weak globals.
716 if (obj == nullptr) {
717 return nullptr;
718 }
719 IndirectRef ref;
720 std::string error_msg;
721 {
722 WriterMutexLock mu(self, *Locks::jni_globals_lock_);
723 ref = globals_.Add(obj, &error_msg);
724 MaybeTraceGlobals();
725 }
726 if (UNLIKELY(ref == nullptr)) {
727 LOG(FATAL) << error_msg;
728 UNREACHABLE();
729 }
730 CheckGlobalRefAllocationTracking();
731 return reinterpret_cast<jobject>(ref);
732 }
733
WaitForWeakGlobalsAccess(Thread * self)734 void JavaVMExt::WaitForWeakGlobalsAccess(Thread* self) {
735 if (UNLIKELY(!MayAccessWeakGlobals(self))) {
736 ATraceBegin("Blocking on WeakGlobal access");
737 do {
738 // Check and run the empty checkpoint before blocking so the empty checkpoint will work in the
739 // presence of threads blocking for weak ref access.
740 self->CheckEmptyCheckpointFromWeakRefAccess(Locks::jni_weak_globals_lock_);
741 weak_globals_add_condition_.WaitHoldingLocks(self);
742 } while (!MayAccessWeakGlobals(self));
743 ATraceEnd();
744 }
745 }
746
AddWeakGlobalRef(Thread * self,ObjPtr<mirror::Object> obj)747 jweak JavaVMExt::AddWeakGlobalRef(Thread* self, ObjPtr<mirror::Object> obj) {
748 if (obj == nullptr) {
749 return nullptr;
750 }
751 MutexLock mu(self, *Locks::jni_weak_globals_lock_);
752 // CMS needs this to block for concurrent reference processing because an object allocated during
753 // the GC won't be marked and concurrent reference processing would incorrectly clear the JNI weak
754 // ref. But CC (gUseReadBarrier == true) doesn't because of the to-space invariant.
755 if (!gUseReadBarrier) {
756 WaitForWeakGlobalsAccess(self);
757 }
758 std::string error_msg;
759 IndirectRef ref = weak_globals_.Add(obj, &error_msg);
760 MaybeTraceWeakGlobals();
761 if (UNLIKELY(ref == nullptr)) {
762 LOG(FATAL) << error_msg;
763 UNREACHABLE();
764 }
765 return reinterpret_cast<jweak>(ref);
766 }
767
DeleteGlobalRef(Thread * self,jobject obj)768 void JavaVMExt::DeleteGlobalRef(Thread* self, jobject obj) {
769 if (obj == nullptr) {
770 return;
771 }
772 {
773 WriterMutexLock mu(self, *Locks::jni_globals_lock_);
774 if (!globals_.Remove(obj)) {
775 LOG(WARNING) << "JNI WARNING: DeleteGlobalRef(" << obj << ") "
776 << "failed to find entry";
777 }
778 MaybeTraceGlobals();
779 }
780 CheckGlobalRefAllocationTracking();
781 }
782
DeleteWeakGlobalRef(Thread * self,jweak obj)783 void JavaVMExt::DeleteWeakGlobalRef(Thread* self, jweak obj) {
784 if (obj == nullptr) {
785 return;
786 }
787 MutexLock mu(self, *Locks::jni_weak_globals_lock_);
788 if (!weak_globals_.Remove(obj)) {
789 LOG(WARNING) << "JNI WARNING: DeleteWeakGlobalRef(" << obj << ") "
790 << "failed to find entry";
791 }
792 MaybeTraceWeakGlobals();
793 }
794
ThreadEnableCheckJni(Thread * thread,void * arg)795 static void ThreadEnableCheckJni(Thread* thread, void* arg) {
796 bool* check_jni = reinterpret_cast<bool*>(arg);
797 thread->GetJniEnv()->SetCheckJniEnabled(*check_jni);
798 }
799
SetCheckJniEnabled(bool enabled)800 bool JavaVMExt::SetCheckJniEnabled(bool enabled) {
801 bool old_check_jni = check_jni_;
802 check_jni_ = enabled;
803 functions = enabled ? GetCheckJniInvokeInterface() : unchecked_functions_;
804 MutexLock mu(Thread::Current(), *Locks::thread_list_lock_);
805 runtime_->GetThreadList()->ForEach(ThreadEnableCheckJni, &check_jni_);
806 return old_check_jni;
807 }
808
DumpForSigQuit(std::ostream & os)809 void JavaVMExt::DumpForSigQuit(std::ostream& os) {
810 os << "JNI: CheckJNI is " << (check_jni_ ? "on" : "off");
811 if (force_copy_) {
812 os << " (with forcecopy)";
813 }
814 Thread* self = Thread::Current();
815 {
816 ReaderMutexLock mu(self, *Locks::jni_globals_lock_);
817 os << "; globals=" << globals_.Capacity();
818 }
819 {
820 MutexLock mu(self, *Locks::jni_weak_globals_lock_);
821 if (weak_globals_.Capacity() > 0) {
822 os << " (plus " << weak_globals_.Capacity() << " weak)";
823 }
824 }
825 os << '\n';
826
827 {
828 MutexLock mu(self, *Locks::jni_libraries_lock_);
829 os << "Libraries: " << Dumpable<Libraries>(*libraries_) << " (" << libraries_->size() << ")\n";
830 }
831 }
832
DisallowNewWeakGlobals()833 void JavaVMExt::DisallowNewWeakGlobals() {
834 CHECK(!gUseReadBarrier);
835 Thread* const self = Thread::Current();
836 MutexLock mu(self, *Locks::jni_weak_globals_lock_);
837 // DisallowNewWeakGlobals is only called by CMS during the pause. It is required to have the
838 // mutator lock exclusively held so that we don't have any threads in the middle of
839 // DecodeWeakGlobal.
840 Locks::mutator_lock_->AssertExclusiveHeld(self);
841 allow_accessing_weak_globals_.store(false, std::memory_order_seq_cst);
842 }
843
AllowNewWeakGlobals()844 void JavaVMExt::AllowNewWeakGlobals() {
845 CHECK(!gUseReadBarrier);
846 Thread* self = Thread::Current();
847 MutexLock mu(self, *Locks::jni_weak_globals_lock_);
848 allow_accessing_weak_globals_.store(true, std::memory_order_seq_cst);
849 weak_globals_add_condition_.Broadcast(self);
850 }
851
BroadcastForNewWeakGlobals()852 void JavaVMExt::BroadcastForNewWeakGlobals() {
853 Thread* self = Thread::Current();
854 MutexLock mu(self, *Locks::jni_weak_globals_lock_);
855 weak_globals_add_condition_.Broadcast(self);
856 }
857
DecodeGlobal(IndirectRef ref)858 ObjPtr<mirror::Object> JavaVMExt::DecodeGlobal(IndirectRef ref) {
859 return globals_.Get(ref);
860 }
861
UpdateGlobal(Thread * self,IndirectRef ref,ObjPtr<mirror::Object> result)862 void JavaVMExt::UpdateGlobal(Thread* self, IndirectRef ref, ObjPtr<mirror::Object> result) {
863 WriterMutexLock mu(self, *Locks::jni_globals_lock_);
864 globals_.Update(ref, result);
865 }
866
DecodeWeakGlobal(Thread * self,IndirectRef ref)867 ObjPtr<mirror::Object> JavaVMExt::DecodeWeakGlobal(Thread* self, IndirectRef ref) {
868 // It is safe to access GetWeakRefAccessEnabled without the lock since CC uses checkpoints to call
869 // SetWeakRefAccessEnabled, and the other collectors only modify allow_accessing_weak_globals_
870 // when the mutators are paused.
871 // This only applies in the case where MayAccessWeakGlobals goes from false to true. In the other
872 // case, it may be racy, this is benign since DecodeWeakGlobalLocked does the correct behavior
873 // if MayAccessWeakGlobals is false.
874 DCHECK_EQ(IndirectReferenceTable::GetIndirectRefKind(ref), kWeakGlobal);
875 if (LIKELY(MayAccessWeakGlobals(self))) {
876 return weak_globals_.Get(ref);
877 }
878 MutexLock mu(self, *Locks::jni_weak_globals_lock_);
879 return DecodeWeakGlobalLocked(self, ref);
880 }
881
DecodeWeakGlobalLocked(Thread * self,IndirectRef ref)882 ObjPtr<mirror::Object> JavaVMExt::DecodeWeakGlobalLocked(Thread* self, IndirectRef ref) {
883 if (kDebugLocking) {
884 Locks::jni_weak_globals_lock_->AssertHeld(self);
885 }
886 // TODO: Handle the already null case without waiting.
887 // TODO: Otherwise we should just wait for kInitMarkingDone, and track which weak globals were
888 // marked at that point. We would only need one mark bit per entry in the weak_globals_ table,
889 // and a quick pass over that early on during reference processing.
890 WaitForWeakGlobalsAccess(self);
891 return weak_globals_.Get(ref);
892 }
893
DecodeWeakGlobalAsStrong(IndirectRef ref)894 ObjPtr<mirror::Object> JavaVMExt::DecodeWeakGlobalAsStrong(IndirectRef ref) {
895 // The target is known to be alive. Simple `Get()` with read barrier is enough.
896 return weak_globals_.Get(ref);
897 }
898
DecodeWeakGlobalDuringShutdown(Thread * self,IndirectRef ref)899 ObjPtr<mirror::Object> JavaVMExt::DecodeWeakGlobalDuringShutdown(Thread* self, IndirectRef ref) {
900 DCHECK_EQ(IndirectReferenceTable::GetIndirectRefKind(ref), kWeakGlobal);
901 DCHECK(Runtime::Current()->IsShuttingDown(self));
902 if (self != nullptr) {
903 return DecodeWeakGlobal(self, ref);
904 }
905 // self can be null during a runtime shutdown. ~Runtime()->~ClassLinker()->DecodeWeakGlobal().
906 if (!gUseReadBarrier) {
907 DCHECK(allow_accessing_weak_globals_.load(std::memory_order_seq_cst));
908 }
909 return weak_globals_.Get(ref);
910 }
911
IsWeakGlobalCleared(Thread * self,IndirectRef ref)912 bool JavaVMExt::IsWeakGlobalCleared(Thread* self, IndirectRef ref) {
913 DCHECK_EQ(IndirectReferenceTable::GetIndirectRefKind(ref), kWeakGlobal);
914 MutexLock mu(self, *Locks::jni_weak_globals_lock_);
915 WaitForWeakGlobalsAccess(self);
916 // When just checking a weak ref has been cleared, avoid triggering the read barrier in decode
917 // (DecodeWeakGlobal) so that we won't accidentally mark the object alive. Since the cleared
918 // sentinel is a non-moving object, we can compare the ref to it without the read barrier and
919 // decide if it's cleared.
920 return Runtime::Current()->IsClearedJniWeakGlobal(weak_globals_.Get<kWithoutReadBarrier>(ref));
921 }
922
UpdateWeakGlobal(Thread * self,IndirectRef ref,ObjPtr<mirror::Object> result)923 void JavaVMExt::UpdateWeakGlobal(Thread* self, IndirectRef ref, ObjPtr<mirror::Object> result) {
924 MutexLock mu(self, *Locks::jni_weak_globals_lock_);
925 weak_globals_.Update(ref, result);
926 }
927
DumpReferenceTables(std::ostream & os)928 void JavaVMExt::DumpReferenceTables(std::ostream& os) {
929 Thread* self = Thread::Current();
930 {
931 ReaderMutexLock mu(self, *Locks::jni_globals_lock_);
932 globals_.Dump(os);
933 }
934 {
935 MutexLock mu(self, *Locks::jni_weak_globals_lock_);
936 weak_globals_.Dump(os);
937 }
938 }
939
UnloadNativeLibraries()940 void JavaVMExt::UnloadNativeLibraries() {
941 libraries_.get()->UnloadNativeLibraries();
942 }
943
UnloadBootNativeLibraries()944 void JavaVMExt::UnloadBootNativeLibraries() {
945 libraries_.get()->UnloadBootNativeLibraries(this);
946 }
947
LoadNativeLibrary(JNIEnv * env,const std::string & path,jobject class_loader,jclass caller_class,std::string * error_msg)948 bool JavaVMExt::LoadNativeLibrary(JNIEnv* env,
949 const std::string& path,
950 jobject class_loader,
951 jclass caller_class,
952 std::string* error_msg) {
953 error_msg->clear();
954
955 // See if we've already loaded this library. If we have, and the class loader
956 // matches, return successfully without doing anything.
957 // TODO: for better results we should canonicalize the pathname (or even compare
958 // inodes). This implementation is fine if everybody is using System.loadLibrary.
959 SharedLibrary* library;
960 Thread* self = Thread::Current();
961 {
962 // TODO: move the locking (and more of this logic) into Libraries.
963 MutexLock mu(self, *Locks::jni_libraries_lock_);
964 library = libraries_->Get(path);
965 }
966 void* class_loader_allocator = nullptr;
967 std::string caller_location;
968 {
969 ScopedObjectAccess soa(env);
970 // As the incoming class loader is reachable/alive during the call of this function,
971 // it's okay to decode it without worrying about unexpectedly marking it alive.
972 ObjPtr<mirror::ClassLoader> loader = soa.Decode<mirror::ClassLoader>(class_loader);
973
974 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
975 if (class_linker->IsBootClassLoader(loader)) {
976 loader = nullptr;
977 class_loader = nullptr;
978 }
979 if (caller_class != nullptr) {
980 ObjPtr<mirror::Class> caller = soa.Decode<mirror::Class>(caller_class);
981 ObjPtr<mirror::DexCache> dex_cache = caller->GetDexCache();
982 if (dex_cache != nullptr) {
983 caller_location = dex_cache->GetLocation()->ToModifiedUtf8();
984 }
985 }
986
987 class_loader_allocator = class_linker->GetAllocatorForClassLoader(loader);
988 CHECK(class_loader_allocator != nullptr);
989 }
990 if (library != nullptr) {
991 // Use the allocator pointers for class loader equality to avoid unnecessary weak root decode.
992 if (library->GetClassLoaderAllocator() != class_loader_allocator) {
993 // The library will be associated with class_loader. The JNI
994 // spec says we can't load the same library into more than one
995 // class loader.
996 //
997 // This isn't very common. So spend some time to get a readable message.
998 auto call_to_string = [&](jobject obj) -> std::string {
999 if (obj == nullptr) {
1000 return "null";
1001 }
1002 // Handle jweaks. Ignore double local-ref.
1003 ScopedLocalRef<jobject> local_ref(env, env->NewLocalRef(obj));
1004 if (local_ref != nullptr) {
1005 ScopedLocalRef<jclass> local_class(env, env->GetObjectClass(local_ref.get()));
1006 jmethodID to_string = env->GetMethodID(local_class.get(),
1007 "toString",
1008 "()Ljava/lang/String;");
1009 DCHECK(to_string != nullptr);
1010 ScopedLocalRef<jobject> local_string(env,
1011 env->CallObjectMethod(local_ref.get(), to_string));
1012 if (local_string != nullptr) {
1013 ScopedUtfChars utf(env, reinterpret_cast<jstring>(local_string.get()));
1014 if (utf.c_str() != nullptr) {
1015 return utf.c_str();
1016 }
1017 }
1018 if (env->ExceptionCheck()) {
1019 // We can't do much better logging, really. So leave it with a Describe.
1020 env->ExceptionDescribe();
1021 env->ExceptionClear();
1022 }
1023 return "(Error calling toString)";
1024 }
1025 return "null";
1026 };
1027 std::string old_class_loader = call_to_string(library->GetClassLoader());
1028 std::string new_class_loader = call_to_string(class_loader);
1029 StringAppendF(error_msg, "Shared library \"%s\" already opened by "
1030 "ClassLoader %p(%s); can't open in ClassLoader %p(%s)",
1031 path.c_str(),
1032 library->GetClassLoader(),
1033 old_class_loader.c_str(),
1034 class_loader,
1035 new_class_loader.c_str());
1036 LOG(WARNING) << *error_msg;
1037 return false;
1038 }
1039 VLOG(jni) << "[Shared library \"" << path << "\" already loaded in "
1040 << " ClassLoader " << class_loader << "]";
1041 if (!library->CheckOnLoadResult()) {
1042 StringAppendF(error_msg, "JNI_OnLoad failed on a previous attempt "
1043 "to load \"%s\"", path.c_str());
1044 return false;
1045 }
1046 return true;
1047 }
1048
1049 // Open the shared library. Because we're using a full path, the system
1050 // doesn't have to search through LD_LIBRARY_PATH. (It may do so to
1051 // resolve this library's dependencies though.)
1052
1053 // Failures here are expected when java.library.path has several entries
1054 // and we have to hunt for the lib.
1055
1056 // Below we dlopen but there is no paired dlclose, this would be necessary if we supported
1057 // class unloading. Libraries will only be unloaded when the reference count (incremented by
1058 // dlopen) becomes zero from dlclose.
1059
1060 // Retrieve the library path from the classloader, if necessary.
1061 ScopedLocalRef<jstring> library_path(env, GetLibrarySearchPath(env, class_loader));
1062
1063 Locks::mutator_lock_->AssertNotHeld(self);
1064 const char* path_str = path.empty() ? nullptr : path.c_str();
1065 bool needs_native_bridge = false;
1066 char* nativeloader_error_msg = nullptr;
1067 void* handle = android::OpenNativeLibrary(
1068 env,
1069 runtime_->GetTargetSdkVersion(),
1070 path_str,
1071 class_loader,
1072 (caller_location.empty() ? nullptr : caller_location.c_str()),
1073 library_path.get(),
1074 &needs_native_bridge,
1075 &nativeloader_error_msg);
1076 VLOG(jni) << "[Call to dlopen(\"" << path << "\", RTLD_NOW) returned " << handle << "]";
1077
1078 if (handle == nullptr) {
1079 *error_msg = nativeloader_error_msg;
1080 android::NativeLoaderFreeErrorMessage(nativeloader_error_msg);
1081 VLOG(jni) << "dlopen(\"" << path << "\", RTLD_NOW) failed: " << *error_msg;
1082 return false;
1083 }
1084
1085 if (env->ExceptionCheck() == JNI_TRUE) {
1086 LOG(ERROR) << "Unexpected exception:";
1087 env->ExceptionDescribe();
1088 env->ExceptionClear();
1089 }
1090 // Create a new entry.
1091 // TODO: move the locking (and more of this logic) into Libraries.
1092 bool created_library = false;
1093 {
1094 // Create SharedLibrary ahead of taking the libraries lock to maintain lock ordering.
1095 std::unique_ptr<SharedLibrary> new_library(
1096 new SharedLibrary(env,
1097 self,
1098 path,
1099 handle,
1100 needs_native_bridge,
1101 class_loader,
1102 class_loader_allocator));
1103
1104 MutexLock mu(self, *Locks::jni_libraries_lock_);
1105 library = libraries_->Get(path);
1106 if (library == nullptr) { // We won race to get libraries_lock.
1107 library = new_library.release();
1108 libraries_->Put(path, library);
1109 created_library = true;
1110 }
1111 }
1112 if (!created_library) {
1113 LOG(INFO) << "WOW: we lost a race to add shared library: "
1114 << "\"" << path << "\" ClassLoader=" << class_loader;
1115 return library->CheckOnLoadResult();
1116 }
1117 VLOG(jni) << "[Added shared library \"" << path << "\" for ClassLoader " << class_loader << "]";
1118
1119 bool was_successful = false;
1120 void* sym = library->FindSymbol("JNI_OnLoad", nullptr, android::kJNICallTypeRegular);
1121 if (sym == nullptr) {
1122 VLOG(jni) << "[No JNI_OnLoad found in \"" << path << "\"]";
1123 was_successful = true;
1124 } else {
1125 // Call JNI_OnLoad. We have to override the current class
1126 // loader, which will always be "null" since the stuff at the
1127 // top of the stack is around Runtime.loadLibrary(). (See
1128 // the comments in the JNI FindClass function.)
1129 ScopedLocalRef<jobject> old_class_loader(env, env->NewLocalRef(self->GetClassLoaderOverride()));
1130 self->SetClassLoaderOverride(class_loader);
1131
1132 VLOG(jni) << "[Calling JNI_OnLoad in \"" << path << "\"]";
1133 using JNI_OnLoadFn = int(*)(JavaVM*, void*);
1134 JNI_OnLoadFn jni_on_load = reinterpret_cast<JNI_OnLoadFn>(sym);
1135 int version = (*jni_on_load)(this, nullptr);
1136
1137 if (IsSdkVersionSetAndAtMost(runtime_->GetTargetSdkVersion(), SdkVersion::kL)) {
1138 // Make sure that sigchain owns SIGSEGV.
1139 EnsureFrontOfChain(SIGSEGV);
1140 }
1141
1142 self->SetClassLoaderOverride(old_class_loader.get());
1143
1144 if (version == JNI_ERR) {
1145 StringAppendF(error_msg, "JNI_ERR returned from JNI_OnLoad in \"%s\"", path.c_str());
1146 } else if (JavaVMExt::IsBadJniVersion(version)) {
1147 StringAppendF(error_msg, "Bad JNI version returned from JNI_OnLoad in \"%s\": %d",
1148 path.c_str(), version);
1149 // It's unwise to call dlclose() here, but we can mark it
1150 // as bad and ensure that future load attempts will fail.
1151 // We don't know how far JNI_OnLoad got, so there could
1152 // be some partially-initialized stuff accessible through
1153 // newly-registered native method calls. We could try to
1154 // unregister them, but that doesn't seem worthwhile.
1155 } else {
1156 was_successful = true;
1157 }
1158 VLOG(jni) << "[Returned " << (was_successful ? "successfully" : "failure")
1159 << " from JNI_OnLoad in \"" << path << "\"]";
1160 }
1161
1162 library->SetResult(was_successful);
1163 return was_successful;
1164 }
1165
FindCodeForNativeMethodInAgents(ArtMethod * m)1166 static void* FindCodeForNativeMethodInAgents(ArtMethod* m) REQUIRES_SHARED(Locks::mutator_lock_) {
1167 std::string jni_short_name(m->JniShortName());
1168 std::string jni_long_name(m->JniLongName());
1169 for (const std::unique_ptr<ti::Agent>& agent : Runtime::Current()->GetAgents()) {
1170 void* fn = agent->FindSymbol(jni_short_name);
1171 if (fn != nullptr) {
1172 VLOG(jni) << "Found implementation for " << m->PrettyMethod()
1173 << " (symbol: " << jni_short_name << ") in " << *agent;
1174 return fn;
1175 }
1176 fn = agent->FindSymbol(jni_long_name);
1177 if (fn != nullptr) {
1178 VLOG(jni) << "Found implementation for " << m->PrettyMethod()
1179 << " (symbol: " << jni_long_name << ") in " << *agent;
1180 return fn;
1181 }
1182 }
1183 return nullptr;
1184 }
1185
FindCodeForNativeMethod(ArtMethod * m,std::string * error_msg,bool can_suspend)1186 void* JavaVMExt::FindCodeForNativeMethod(ArtMethod* m, std::string* error_msg, bool can_suspend) {
1187 CHECK(m->IsNative());
1188 ObjPtr<mirror::Class> c = m->GetDeclaringClass();
1189 // If this is a static method, it could be called before the class has been initialized.
1190 CHECK(c->IsInitializing() || !m->NeedsClinitCheckBeforeCall())
1191 << c->GetStatus() << " " << m->PrettyMethod();
1192 Thread* const self = Thread::Current();
1193 void* native_method = libraries_->FindNativeMethod(self, m, error_msg, can_suspend);
1194 if (native_method == nullptr && can_suspend) {
1195 // Lookup JNI native methods from native TI Agent libraries. See runtime/ti/agent.h for more
1196 // information. Agent libraries are searched for native methods after all jni libraries.
1197 native_method = FindCodeForNativeMethodInAgents(m);
1198 }
1199 return native_method;
1200 }
1201
TrimGlobals()1202 void JavaVMExt::TrimGlobals() {
1203 WriterMutexLock mu(Thread::Current(), *Locks::jni_globals_lock_);
1204 globals_.Trim();
1205 }
1206
VisitRoots(RootVisitor * visitor)1207 void JavaVMExt::VisitRoots(RootVisitor* visitor) {
1208 Thread* self = Thread::Current();
1209 ReaderMutexLock mu(self, *Locks::jni_globals_lock_);
1210 globals_.VisitRoots(visitor, RootInfo(kRootJNIGlobal));
1211 // The weak_globals table is visited by the GC itself (because it mutates the table).
1212 }
1213
GetLibrarySearchPath(JNIEnv * env,jobject class_loader)1214 jstring JavaVMExt::GetLibrarySearchPath(JNIEnv* env, jobject class_loader) {
1215 if (class_loader == nullptr) {
1216 return nullptr;
1217 }
1218 ScopedObjectAccess soa(env);
1219 ObjPtr<mirror::Object> mirror_class_loader = soa.Decode<mirror::Object>(class_loader);
1220 if (!mirror_class_loader->InstanceOf(WellKnownClasses::dalvik_system_BaseDexClassLoader.Get())) {
1221 return nullptr;
1222 }
1223 return soa.AddLocalReference<jstring>(
1224 WellKnownClasses::dalvik_system_BaseDexClassLoader_getLdLibraryPath->InvokeVirtual<'L'>(
1225 soa.Self(), mirror_class_loader));
1226 }
1227
1228 // JNI Invocation interface.
1229
JNI_CreateJavaVM(JavaVM ** p_vm,JNIEnv ** p_env,void * vm_args)1230 extern "C" EXPORT jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) {
1231 ScopedTrace trace(__FUNCTION__);
1232 const JavaVMInitArgs* args = static_cast<JavaVMInitArgs*>(vm_args);
1233 if (JavaVMExt::IsBadJniVersion(args->version)) {
1234 LOG(ERROR) << "Bad JNI version passed to CreateJavaVM: " << args->version;
1235 return JNI_EVERSION;
1236 }
1237 RuntimeOptions options;
1238 for (int i = 0; i < args->nOptions; ++i) {
1239 JavaVMOption* option = &args->options[i];
1240 options.push_back(std::make_pair(std::string(option->optionString), option->extraInfo));
1241 }
1242 bool ignore_unrecognized = args->ignoreUnrecognized;
1243 if (!Runtime::Create(options, ignore_unrecognized)) {
1244 return JNI_ERR;
1245 }
1246
1247 // When `ART_CRASH_RUNTIME_DELIBERATELY` is defined (which happens only in the
1248 // case of a test APEX), we crash the runtime here on purpose, to test the
1249 // behavior of rollbacks following a failed ART Mainline Module update.
1250 #ifdef ART_CRASH_RUNTIME_DELIBERATELY
1251 LOG(FATAL) << "Runtime crashing deliberately for testing purposes.";
1252 #endif
1253
1254 // Initialize native loader. This step makes sure we have
1255 // everything set up before we start using JNI.
1256 android::InitializeNativeLoader();
1257
1258 Runtime* runtime = Runtime::Current();
1259 bool started = runtime->Start();
1260 if (!started) {
1261 delete Thread::Current()->GetJniEnv();
1262 delete runtime->GetJavaVM();
1263 LOG(WARNING) << "CreateJavaVM failed";
1264 return JNI_ERR;
1265 }
1266
1267 *p_env = Thread::Current()->GetJniEnv();
1268 *p_vm = runtime->GetJavaVM();
1269 return JNI_OK;
1270 }
1271
JNI_GetCreatedJavaVMs(JavaVM ** vms_buf,jsize buf_len,jsize * vm_count)1272 extern "C" EXPORT jint JNI_GetCreatedJavaVMs(JavaVM** vms_buf, jsize buf_len, jsize* vm_count) {
1273 Runtime* runtime = Runtime::Current();
1274 if (runtime == nullptr || buf_len == 0) {
1275 *vm_count = 0;
1276 } else {
1277 *vm_count = 1;
1278 vms_buf[0] = runtime->GetJavaVM();
1279 }
1280 return JNI_OK;
1281 }
1282
1283 // Historically unsupported.
JNI_GetDefaultJavaVMInitArgs(void *)1284 extern "C" EXPORT jint JNI_GetDefaultJavaVMInitArgs(void* /*vm_args*/) {
1285 return JNI_ERR;
1286 }
1287
1288 } // namespace art
1289