参考:
https://www.jianshu.com/p/47d0121484fc
https://blog.csdn.net/xichangbao/article/details/53104810
https://blog.csdn.net/qq_33023933/article/details/112917326
https://blog.csdn.net/sinat_22657459/article/details/78946921
https://www.dandelioncloud.cn/article/details/1532342564976095234
前文:
http://www.gaohaiyan.com/4062.html
前面梳理到“service zygote /system/bin/app_process64”对应的源码在 frameworks/base/cmds/app_process,Android.bp 中又指向了同目录下的 app_main.cpp 文件。
1. app_main.cpp
frameworks/base/cmds/app_process/app_main.cpp 约165行。
检测是否符合启动zygote的条件,并设置参数。最终通过AndroidRuntime去启动。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 |
#define LOG_TAG "appproc" #include <stdio.h> #include <stdlib.h> #include <sys/prctl.h> #include <sys/stat.h> #include <unistd.h> #include <android-base/macros.h> #include <binder/IPCThreadState.h> #include <hwbinder/IPCThreadState.h> #include <utils/Log.h> #include <cutils/memory.h> #include <cutils/properties.h> #include <cutils/trace.h> #include <android_runtime/AndroidRuntime.h> // frameworks/base/core/jni/include/android_runtime/AndroidRuntime.h #include <private/android_filesystem_config.h> // for AID_SYSTEM namespace android { static void app_usage(){ fprintf(stderr, "Usage: app_process [java-options] cmd-dir start-class-name [options]\n"); } class AppRuntime : public AndroidRuntime{ public: AppRuntime(char* argBlockStart, const size_t argBlockLength) : AndroidRuntime(argBlockStart, argBlockLength) , mClass(NULL){ } void setClassNameAndArgs(const String8& className, int argc, char * const *argv) { mClassName = className; for (int i = 0; i < argc; ++i) { mArgs.add(String8(argv[i])); } } virtual void onVmCreated(JNIEnv* env) { ALOGE("aosp-acer, app_main.cpp 约47行 AppRuntime.onVmCreated,虚拟机开始创建启动 \n"); if (mClassName.isEmpty()) { return; // Zygote. Nothing to do here. } // ...... } virtual void onStarted(){ // ...... } virtual void onZygoteInit(){ // ...... } virtual void onExit(int code){ // ...... } String8 mClassName; Vector<String8> mArgs; jclass mClass; }; // end class AppRuntime } // end namespace android using namespace android; static size_t computeArgBlockSize(int argc, char* const argv[]) { //将原始参数留个备份 // ...... } static void maybeCreateDalvikCache() { // 创建虚拟机所须的 /data/dalvik-cache // ...... } #if defined(__LP64__) static const char ABI_LIST_PROPERTY[] = "ro.product.cpu.abilist64"; static const char ZYGOTE_NICE_NAME[] = "zygote64"; #else static const char ABI_LIST_PROPERTY[] = "ro.product.cpu.abilist32"; static const char ZYGOTE_NICE_NAME[] = "zygote"; #endif // 入口 int main(int argc, char* const argv[]) // 参数 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote { if (!LOG_NDEBUG) { // 调试模式时打印一下参数 String8 argv_String; for (int i = 0; i < argc; ++i) { argv_String.append("\""); argv_String.append(argv[i]); argv_String.append("\" "); } ALOGV("app_process main with argv: %s", argv_String.string()); } ALOGE("aosp-acer, 启动zygote参数个数:'%s'\n", argc); ALOGE("aosp-acer, 启动zygote到第一个参数:'%s'\n", argv[0]); // 约34行 class AppRuntime : public AndroidRuntime AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv)); //将原始参数留个备份 // Process command line arguments // ignore argv[0] argc--; argv++; // Everything up to '--' or first non '-' arg goes to the vm. // 所有以 -- 开头或没有 - 开头到参数都是为了启动VM。 // The first argument after the VM args is the "parent dir", which is currently unused. // VM参数后的第一个参数是“父目录”,它当前未使用。 // After the parent dir, we expect one or more the following internal arguments : // 父目录参数之后到,须要一个或多个以下参数: // --zygote : Start in zygote mode --启动zygote进程 // --start-system-server : Start the system server. --启动system服务 // --application : Start in application (stand alone, non zygote) mode. --启动(独立的,非zygote的)普通的应用进程 // --nice-name : The nice name for this process. --设置这个进程的名字 // [参考https://www.jianshu.com/p/47d0121484fc] // For non zygote starts, these arguments will be followed by the main class name. // All remaining arguments are passed to the main method of this class. // 非zygote程序的启动,这些参数后跟主类名称。所有剩余的参数都传递到该类的main方法。 // For zygote starts, all remaining arguments are passed to the zygote. // main function. // zygote的启动,所有剩余的参数都传递给zygote的主函数。 // Note that we must copy argument string values since we will rewrite the // entire argument block when we apply the nice name to argv0. // 注意,必须在设定这些参数到新名称以前进行拷贝,即尽早 AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv)); // As an exception to the above rule, anything in "spaced commands" goes to the vm even though it has a space in it. // 有个例外,“间隔”中的任何内容都直接进入vm,尽管就是个空格。 const char* spaced_commands[] = { "-cp", "-classpath" }; // Allow "spaced commands" to be succeeded by exactly 1 argument (regardless of -s). bool known_command = false; // 下面到for是过滤无效参数 int i; for (i = 0; i < argc; i++) { if (known_command == true) { runtime.addOption(strdup(argv[i])); // The static analyzer gets upset that we don't ever free the above string. // Since the allocation is from main, leaking it doesn't seem problematic. // NOLINTNEXTLINE ALOGV("app_process main add known option '%s'", argv[i]); known_command = false; continue; } for (int j = 0; j < static_cast<int>(sizeof(spaced_commands) / sizeof(spaced_commands[0])); ++j) { if (strcmp(argv[i], spaced_commands[j]) == 0) { known_command = true; ALOGV("app_process main found known command '%s'", argv[i]); } } if (argv[i][0] != '-') { break; } if (argv[i][1] == '-' && argv[i][2] == 0) { ++i; // Skip --. break; } runtime.addOption(strdup(argv[i])); // The static analyzer gets upset that we don't ever free the above string. // Since the allocation is from main, leaking it doesn't seem problematic. // NOLINTNEXTLINE ALOGV("app_process main add option '%s'", argv[i]); } // Parse runtime arguments. Stop at first unrecognized option. 解析运行时参数。遇到不能识别的就停止。 bool zygote = false; // 是否是启动zygote bool startSystemServer = false; // 是否是启动system-service bool application = false; // 是否是启动普通的应用进程 String8 niceName; // 进程名称 String8 className; // 程序的类名 ++i; // Skip unused "parent dir" argument. while (i < argc) { const char* arg = argv[i++]; if (strcmp(arg, "--zygote") == 0) { // 参数中有“--zygote”,则启动zygote进程 zygote = true; // 标记设为true niceName = ZYGOTE_NICE_NAME; // 将进程名设为zygote64或zygote } else if (strcmp(arg, "--start-system-server") == 0) { // 是否启动system-service startSystemServer = true; } else if (strcmp(arg, "--application") == 0) { // 是否启动普通的应用进程。这个和zygote是并列的,二选一? application = true; } else if (strncmp(arg, "--nice-name=", 12) == 0) { // 手动设置的进程名 niceName.setTo(arg + 12); } else if (strncmp(arg, "--", 2) != 0) { className.setTo(arg); break; } else { --i; break; } } Vector<String8> args; if (!className.isEmpty()) { // 如果已经存在要启动的程序到类名。 // We're not in zygote mode, the only argument we need to pass to RuntimeInit is the application argument. // 那么就不是启动zygote,我们需要传递给RuntimeInit的唯一参数是这个应用程序的名称。 // The Remainder of args get passed to startup class main(). 其它的参数都是传给这个程序的main函数。 // Make copies of them before we overwrite them with the process name. 在我们用进程名称覆盖它们之前,先复制它们。 args.add(application ? String8("application") : String8("tool")); runtime.setClassNameAndArgs(className, argc - i, argv + i); if (!LOG_NDEBUG) { // 开启调试时打印一下 String8 restOfArgs; char* const* argv_new = argv + i; int argc_new = argc - i; for (int k = 0; k < argc_new; ++k) { restOfArgs.append("\""); restOfArgs.append(argv_new[k]); restOfArgs.append("\" "); } ALOGV("Class name = %s, args = %s", className.string(), restOfArgs.string()); } } else { // 如果不存在要启动的程序到类名。 // We're in zygote mode. // 我们进入zygote maybeCreateDalvikCache(); // 创建虚拟机所须的 /data/dalvik-cache if (startSystemServer) { // 是否是启动system-service args.add(String8("start-system-server")); } char prop[PROP_VALUE_MAX]; if (property_get(ABI_LIST_PROPERTY, prop, NULL) == 0) { // cpu参数 LOG_ALWAYS_FATAL("app_process: Unable to determine ABI list from property %s.", ABI_LIST_PROPERTY); return 11; } String8 abiFlag("--abi-list="); abiFlag.append(prop); args.add(abiFlag); // In zygote mode, pass all remaining arguments to the zygote main() method. // zygote模式,全部参数都是传给zygote的main函数。 for (; i < argc; ++i) { args.add(String8(argv[i])); } } if (!niceName.isEmpty()) { // niceName非空,即zygote模式,传给runtime。 runtime.setArgv0(niceName.string(), true); /* setProcName */ } String8 s_String; for(int i=0;i<args.size();i++) { s_String.append(" %s", args[i]); } ALOGE("aosp-acer, zygote参数:%s", s_String.string()); if (zygote) { // zygote进程,调用AppRuntime的start方法并把 com.android.internal.os.ZygoteIni 这个java全类名传进去 runtime.start("com.android.internal.os.ZygoteInit", args, zygote); //【--- 2 -->】 frameworks/base/core/jni/AndroidRuntime.cpp 约1136行 void AndroidRuntime::start(className, options, zygote) } else if (className) { // 普通应用程序进程 runtime.start("com.android.internal.os.RuntimeInit", args, zygote); } else { fprintf(stderr, "Error: no class name or --zygote supplied.\n"); app_usage(); LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied."); } } // end main |
2. AndroidRuntime.cpp
frameworks/base/core/jni/AndroidRuntime.cpp 约1136行
解析参数,启动DVM,通过JNI构造java类,启动ZygoteInit类。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
/* Start the Android runtime. 开始安卓运行时状态。 * This involves starting the virtual machine and calling the "static void main(String[] args)" method in the class named by "className". * 这涉及到启动虚拟机 并在由“className”命名的类中 调用“static void main(String[]args)”方法。 * Passes the main function two arguments, the class name and the specified options string. * 向主函数传递两个参数,即类名和指定的选项字符串。*/ void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote) { // className为 com.android.internal.os.ZygoteInit, // options为 start-system-server,--abi-list=arm64-v8a,--socket-name=zygote, // zygote为 true ALOGD(">>>>>> START %s uid %d <<<<<<\n", className != NULL ? className : "(unknown)", getuid()); static const String8 startSystemServer("start-system-server"); // Whether this is the primary zygote, meaning the zygote which will fork system server. bool primary_zygote = false; // true,启动系统服务 /* 'startSystemServer == true' means runtime is obsolete and not run from init.rc anymore, so we print out the boot start event here. */ // “startSystemServer==true”表示运行时已过时,而不是从init.rc启动的。不再是rc,所以我们在这里打印启动启动事件。 for (size_t i = 0; i < options.size(); ++i) { if (options[i] == startSystemServer) { primary_zygote = true; /* track our progress through the boot sequence */ const int LOG_BOOT_PROGRESS_START = 3000; LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START, ns2ms(systemTime(SYSTEM_TIME_MONOTONIC))); } } const char* rootDir = getenv("ANDROID_ROOT"); // /system if (rootDir == NULL) { rootDir = "/system"; if (!hasDir("/system")) { LOG_FATAL("No root directory specified, and /system does not exist."); return; } setenv("ANDROID_ROOT", rootDir, 1); } const char* artRootDir = getenv("ANDROID_ART_ROOT"); if (artRootDir == NULL) { LOG_FATAL("No ART directory specified with ANDROID_ART_ROOT environment variable."); return; } const char* i18nRootDir = getenv("ANDROID_I18N_ROOT"); if (i18nRootDir == NULL) { LOG_FATAL("No runtime directory specified with ANDROID_I18N_ROOT environment variable."); return; } const char* tzdataRootDir = getenv("ANDROID_TZDATA_ROOT"); if (tzdataRootDir == NULL) { LOG_FATAL("No tz data directory specified with ANDROID_TZDATA_ROOT environment variable."); return; } //const char* kernelHack = getenv("LD_ASSUME_KERNEL"); //ALOGD("Found LD_ASSUME_KERNEL='%s'\n", kernelHack); /* start the virtual machine */ JniInvocation jni_invocation; jni_invocation.Init(NULL); // 初始化jni接口 JNIEnv* env; // startVm(&mJavaVM, &env, zygote, primary_zygote) 约609行。启动虚拟机 【 ----- 2.1 ------ 】 if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) { return; } onVmCreated(env); // 约1272行。空方法。当虚拟机创建了。 /* Register android functions. */ // int AndroidRuntime::startReg(JNIEnv* env) 约1590行。使用JNI注册android的native函数 // 【 ----- 2.2 ------ 】startReg注册jni函数 if (startReg(env) < 0) { ALOGE("aosp-acer, Unable to register all android natives\n"); return; } /* We want to call main() with a String array with arguments in it. At present we have two arguments, the class name and an option string. * Create an array to hold them. * 我们要用 字符串数组参数 调用main()。现在有两个:类名、选项。创建一个数组来保存它们。 */ jclass stringClass; jobjectArray strArray; jstring classNameStr; stringClass = env->FindClass("java/lang/String"); // 使用jni获取java的String类型 assert(stringClass != NULL); strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL); assert(strArray != NULL); classNameStr = env->NewStringUTF(className); assert(classNameStr != NULL); env->SetObjectArrayElement(strArray, 0, classNameStr); for (size_t i = 0; i < options.size(); ++i) { jstring optionsStr = env->NewStringUTF(options.itemAt(i).string()); assert(optionsStr != NULL); env->SetObjectArrayElement(strArray, i + 1, optionsStr); } /* Start VM. This thread becomes the main thread of the VM, and will not return until the VM exits. */ // 虚拟机启动后,这个线程就是主线程。直到虚拟机停止才返回。 char* slashClassName = toSlashClassName(className != NULL ? className : ""); // 约1103行。将"com.android.internal.os.ZygoteInit"转换为"com/android/internal/os/ZygoteInit" jclass startClass = env->FindClass(slashClassName); // jni找到这个类 if (startClass == NULL) { ALOGE("aosp-acer, JavaVM无法定位class '%s'\n", slashClassName); /* keep going */ } else { jmethodID startMeth = env->GetStaticMethodID(startClass, "main", "([Ljava/lang/String;)V"); // 获取main函数 if (startMeth == NULL) { ALOGE("aosp-acer, JavaVM unable to find main() in '%s'\n", className); /* keep going */ } else { // startClass :com/android/internal/os/ZygoteInit // startMeth :main // strArray :String["start-system-server", "--abi-list=arm64-v8a", "--socket-name=zygote"] // 【--- 3 ---】【--- 重点,下一篇 ---】 启动函数,进入Java世界。 env->CallStaticVoidMethod(startClass, startMeth, strArray); // frameworks/base/core/java/com/android/internal/os/ZygoteInit.java ALOGE("aosp-acer, Zygote开始孵化"); #if 0 if (env->ExceptionCheck()) threadExitUncaughtException(env); #endif } } free(slashClassName); // 释放内存 ALOGD("Shutting down VM\n"); if (mJavaVM->DetachCurrentThread() != JNI_OK) // 取消当前线程与jvm关联 ALOGW("Warning: unable to detach main thread\n"); if (mJavaVM->DestroyJavaVM() != 0) // 销毁Java虚拟机并回收资源 ALOGW("Warning: VM did not shut down cleanly\n"); } // end start() |
2.1. startVm
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 |
/* Start the Dalvik Virtual Machine. 启动DVM * Various arguments, most determined by system properties, are passed in. * The "mOptions" vector is updated. * * CAUTION: when adding options in here, be careful not to put the char buffer inside a nested scope. * 注意:在此函数内,当添加配置时,必须小心不要将char缓冲区放在嵌套范围内。 * Adding the buffer to the options using mOptions.add() does not copy the buffer, so if the buffer goes out of scope the option may be overwritten. * 使用mOptions.add()并不会发生复制,因此,如果缓冲区超出范围,该选项可能会被覆盖。 * It's best to put the buffer at the top of the function so that it is more unlikely that someone will surround it in a scope at a later time and thus introduce a bug. * 最好将缓冲区放在函数的顶部,这样就不太可能以后有人会把它围在一个范围内,从而引入了一个bug。 * 成功执行后返回 0。 */ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote, bool primary_zygote) { // 下面声明一堆虚拟机参数 JavaVMInitArgs initArgs; char propBuf[PROPERTY_VALUE_MAX]; char jniOptsBuf[sizeof("-Xjniopts:")-1 + PROPERTY_VALUE_MAX]; char heapstartsizeOptsBuf[sizeof("-Xms")-1 + PROPERTY_VALUE_MAX]; char heapsizeOptsBuf[sizeof("-Xmx")-1 + PROPERTY_VALUE_MAX]; char heapgrowthlimitOptsBuf[sizeof("-XX:HeapGrowthLimit=")-1 + PROPERTY_VALUE_MAX]; char heapminfreeOptsBuf[sizeof("-XX:HeapMinFree=")-1 + PROPERTY_VALUE_MAX]; char heapmaxfreeOptsBuf[sizeof("-XX:HeapMaxFree=")-1 + PROPERTY_VALUE_MAX]; char usejitOptsBuf[sizeof("-Xusejit:")-1 + PROPERTY_VALUE_MAX]; char jitpthreadpriorityOptsBuf[sizeof("-Xjitpthreadpriority:")-1 + PROPERTY_VALUE_MAX]; char jitmaxsizeOptsBuf[sizeof("-Xjitmaxsize:")-1 + PROPERTY_VALUE_MAX]; char jitinitialsizeOptsBuf[sizeof("-Xjitinitialsize:")-1 + PROPERTY_VALUE_MAX]; char jitthresholdOptsBuf[sizeof("-Xjitthreshold:")-1 + PROPERTY_VALUE_MAX]; char useJitProfilesOptsBuf[sizeof("-Xjitsaveprofilinginfo:")-1 + PROPERTY_VALUE_MAX]; char jitprithreadweightOptBuf[sizeof("-Xjitprithreadweight:")-1 + PROPERTY_VALUE_MAX]; char jittransitionweightOptBuf[sizeof("-Xjittransitionweight:")-1 + PROPERTY_VALUE_MAX]; char hotstartupsamplesOptsBuf[sizeof("-Xps-hot-startup-method-samples:")-1 + PROPERTY_VALUE_MAX]; char saveResolvedClassesDelayMsOptsBuf[sizeof("-Xps-save-resolved-classes-delay-ms:")-1 + PROPERTY_VALUE_MAX]; char madviseRandomOptsBuf[sizeof("-XX:MadviseRandomAccess:")-1 + PROPERTY_VALUE_MAX]; char gctypeOptsBuf[sizeof("-Xgc:")-1 + PROPERTY_VALUE_MAX]; char backgroundgcOptsBuf[sizeof("-XX:BackgroundGC=")-1 + PROPERTY_VALUE_MAX]; char heaptargetutilizationOptsBuf[sizeof("-XX:HeapTargetUtilization=")-1 + PROPERTY_VALUE_MAX]; char foregroundHeapGrowthMultiplierOptsBuf[sizeof("-XX:ForegroundHeapGrowthMultiplier=")-1 + PROPERTY_VALUE_MAX]; char finalizerTimeoutMsOptsBuf[sizeof("-XX:FinalizerTimeoutMs=")-1 + PROPERTY_VALUE_MAX]; char threadSuspendTimeoutOptsBuf[sizeof("-XX:ThreadSuspendTimeout=")-1 + PROPERTY_VALUE_MAX]; char cachePruneBuf[sizeof("-Xzygote-max-boot-retry=")-1 + PROPERTY_VALUE_MAX]; char dex2oatXmsImageFlagsBuf[sizeof("-Xms")-1 + PROPERTY_VALUE_MAX]; char dex2oatXmxImageFlagsBuf[sizeof("-Xmx")-1 + PROPERTY_VALUE_MAX]; char dex2oatCompilerFilterBuf[sizeof("--compiler-filter=")-1 + PROPERTY_VALUE_MAX]; char dex2oatImageCompilerFilterBuf[sizeof("--compiler-filter=")-1 + PROPERTY_VALUE_MAX]; char dex2oatThreadsBuf[sizeof("-j")-1 + PROPERTY_VALUE_MAX]; char dex2oatThreadsImageBuf[sizeof("-j")-1 + PROPERTY_VALUE_MAX]; char dex2oatCpuSetBuf[sizeof("--cpu-set=")-1 + PROPERTY_VALUE_MAX]; char dex2oatCpuSetImageBuf[sizeof("--cpu-set=")-1 + PROPERTY_VALUE_MAX]; char dex2oat_isa_variant_key[PROPERTY_KEY_MAX]; char dex2oat_isa_variant[sizeof("--instruction-set-variant=") -1 + PROPERTY_VALUE_MAX]; char dex2oat_isa_features_key[PROPERTY_KEY_MAX]; char dex2oat_isa_features[sizeof("--instruction-set-features=") -1 + PROPERTY_VALUE_MAX]; char dex2oatFlagsBuf[PROPERTY_VALUE_MAX]; char dex2oatImageFlagsBuf[PROPERTY_VALUE_MAX]; char extraOptsBuf[PROPERTY_VALUE_MAX]; char voldDecryptBuf[PROPERTY_VALUE_MAX]; char perfettoHprofOptBuf[sizeof("-XX:PerfettoHprof=") + PROPERTY_VALUE_MAX]; enum { kEMDefault, kEMIntPortable, kEMIntFast, kEMJitCompiler, } executionMode = kEMDefault; char localeOption[sizeof("-Duser.locale=") + PROPERTY_VALUE_MAX]; char lockProfThresholdBuf[sizeof("-Xlockprofthreshold:")-1 + PROPERTY_VALUE_MAX]; char nativeBridgeLibrary[sizeof("-XX:NativeBridge=") + PROPERTY_VALUE_MAX]; char cpuAbiListBuf[sizeof("--cpu-abilist=") + PROPERTY_VALUE_MAX]; char corePlatformApiPolicyBuf[sizeof("-Xcore-platform-api-policy:") + PROPERTY_VALUE_MAX]; char methodTraceFileBuf[sizeof("-Xmethod-trace-file:") + PROPERTY_VALUE_MAX]; char methodTraceFileSizeBuf[sizeof("-Xmethod-trace-file-size:") + PROPERTY_VALUE_MAX]; std::string fingerprintBuf; char jdwpProviderBuf[sizeof("-XjdwpProvider:") - 1 + PROPERTY_VALUE_MAX]; char opaqueJniIds[sizeof("-Xopaque-jni-ids:") - 1 + PROPERTY_VALUE_MAX]; char bootImageBuf[sizeof("-Ximage:") - 1 + PROPERTY_VALUE_MAX]; // 下面定义一堆虚拟机参数 // Read if we are using the profile configuration, do this at the start since the last ART args take precedence. // 如果使用的是配置文件配置,就在最后一个ART参数设置后,立刻开始读取。 property_get("dalvik.vm.profilebootclasspath", propBuf, ""); // build/make/target/product/profile_boot_common.mk:28: dalvik.vm.profilebootclasspath=true std::string profile_boot_class_path_flag = propBuf; // Empty means the property is unset and we should default to the phenotype property. // The possible values are {"true", "false", ""} if (profile_boot_class_path_flag.empty()) { profile_boot_class_path_flag = server_configurable_flags::GetServerConfigurableFlag( RUNTIME_NATIVE_BOOT_NAMESPACE, PROFILE_BOOT_CLASS_PATH, /*default_value=*/ ""); } const bool profile_boot_class_path = (profile_boot_class_path_flag == "true"); if (profile_boot_class_path) { addOption("-Xcompiler-option"); addOption("--count-hotness-in-compiled-code"); addOption("-Xps-profile-boot-class-path"); addOption("-Xps-profile-aot-code"); addOption("-Xjitsaveprofilinginfo"); } std::string use_jitzygote_image_flag = server_configurable_flags::GetServerConfigurableFlag(RUNTIME_NATIVE_BOOT_NAMESPACE, ENABLE_JITZYGOTE_IMAGE, /*default_value=*/""); // Use the APEX boot image for boot class path profiling to get JIT samples on BCP methods. 使用APEX引导映像进行引导类路径分析,以获取BCP方法的JIT示例。 // Also use the APEX boot image if it's explicitly enabled via configuration flag. 如果通过配置标志显式启用了APEX引导映像,也可以使用它。 const bool use_apex_image = profile_boot_class_path || (use_jitzygote_image_flag == "true"); if (use_apex_image) { ALOGI("Using JIT Zygote image: '%s'\n", kJitZygoteImageOption); addOption(kJitZygoteImageOption); } else if (parseRuntimeOption("dalvik.vm.boot-image", bootImageBuf, "-Ximage:")) { ALOGI("Using dalvik.vm.boot-image: '%s'\n", bootImageBuf); } else { ALOGI("Using default boot image"); } std::string disable_lock_profiling = server_configurable_flags::GetServerConfigurableFlag(RUNTIME_NATIVE_BOOT_NAMESPACE, DISABLE_LOCK_PROFILING, /*default_value=*/ ""); if (disable_lock_profiling == "true") { addOption(kLockProfThresholdRuntimeOption); ALOGI("Disabling lock profiling: '%s'\n", kLockProfThresholdRuntimeOption); } else { ALOGI("Leaving lock profiling enabled"); } bool checkJni = false; property_get("dalvik.vm.checkjni", propBuf, ""); // JNI检测功能,用于native层调用jni函数时进行常规检测 if (strcmp(propBuf, "true") == 0) { checkJni = true; } else if (strcmp(propBuf, "false") != 0) { /* property is neither true nor false; fall back on kernel parameter */ // 属性无论真假,都依赖内核参数 property_get("ro.kernel.android.checkjni", propBuf, ""); if (propBuf[0] == '1') { checkJni = true; } } ALOGV("CheckJNI is %s\n", checkJni ? "ON" : "OFF"); if (checkJni) { /* extended JNI checking 开启检测*/ addOption("-Xcheck:jni"); /* with -Xcheck:jni, this provides a JNI function call trace */ //addOption("-verbose:jni"); } property_get("dalvik.vm.execution-mode", propBuf, ""); if (strcmp(propBuf, "int:portable") == 0) { executionMode = kEMIntPortable; } else if (strcmp(propBuf, "int:fast") == 0) { executionMode = kEMIntFast; } else if (strcmp(propBuf, "int:jit") == 0) { executionMode = kEMJitCompiler; } strcpy(jniOptsBuf, "-Xjniopts:"); if (parseRuntimeOption("dalvik.vm.jniopts", jniOptsBuf, "-Xjniopts:")) { // JNI检测选项 ALOGI("JNI options: '%s'\n", jniOptsBuf); } /* route exit() to our handler */ addOption("exit", (void*) runtime_exit); // 添加Java虚拟机选项,当Java虚拟机退出时执行runtime_exit方法 /* route fprintf() to our handler */ addOption("vfprintf", (void*) runtime_vfprintf); // 当Java虚拟机调用vfprintf时,调用runtime_vfprintf方法 /* register the framework-specific "is sensitive thread" hook */ addOption("sensitiveThread", (void*) runtime_isSensitiveThread); /* enable verbose; standard options are { jni, gc, class } */ //addOption("-verbose:jni"); addOption("-verbose:gc"); //addOption("-verbose:class"); // On Android, we always want to allow loading the PerfettoHprof plugin. // Even with this option set, we will still only actually load the plugin if we are on a userdebug build or the app is debuggable or profileable. // This is enforced in art/runtime/runtime.cc. // We want to be able to disable this, because this does not work on host, and we do not want to enable it in tests. parseRuntimeOption("dalvik.vm.perfetto_hprof", perfettoHprofOptBuf, "-XX:PerfettoHprof=", "true"); if (primary_zygote) { addOption("-Xprimaryzygote"); } /* The default starting and maximum size of the heap. Larger values should be specified in a product property override. */ parseRuntimeOption("dalvik.vm.heapstartsize", heapstartsizeOptsBuf, "-Xms", "4m"); parseRuntimeOption("dalvik.vm.heapsize", heapsizeOptsBuf, "-Xmx", "16m"); // 设置虚拟机的heapsize,默认为16M parseRuntimeOption("dalvik.vm.heapgrowthlimit", heapgrowthlimitOptsBuf, "-XX:HeapGrowthLimit="); parseRuntimeOption("dalvik.vm.heapminfree", heapminfreeOptsBuf, "-XX:HeapMinFree="); parseRuntimeOption("dalvik.vm.heapmaxfree", heapmaxfreeOptsBuf, "-XX:HeapMaxFree="); parseRuntimeOption("dalvik.vm.heaptargetutilization", heaptargetutilizationOptsBuf, "-XX:HeapTargetUtilization="); /* Foreground heap growth multiplier option */ parseRuntimeOption("dalvik.vm.foreground-heap-growth-multiplier", foregroundHeapGrowthMultiplierOptsBuf, "-XX:ForegroundHeapGrowthMultiplier="); /* Finalizer and thread suspend timeouts. */ parseRuntimeOption("dalvik.vm.finalizer-timeout-ms", finalizerTimeoutMsOptsBuf, "-XX:FinalizerTimeoutMs="); parseRuntimeOption("dalvik.vm.thread-suspend-timeout-ms", threadSuspendTimeoutOptsBuf, "-XX:ThreadSuspendTimeout="); /* JIT related options. */ parseRuntimeOption("dalvik.vm.usejit", usejitOptsBuf, "-Xusejit:"); parseRuntimeOption("dalvik.vm.jitmaxsize", jitmaxsizeOptsBuf, "-Xjitmaxsize:"); parseRuntimeOption("dalvik.vm.jitinitialsize", jitinitialsizeOptsBuf, "-Xjitinitialsize:"); parseRuntimeOption("dalvik.vm.jitthreshold", jitthresholdOptsBuf, "-Xjitthreshold:"); parseRuntimeOption("dalvik.vm.jitpthreadpriority", jitpthreadpriorityOptsBuf, "-Xjitpthreadpriority:"); property_get("dalvik.vm.usejitprofiles", useJitProfilesOptsBuf, ""); if (strcmp(useJitProfilesOptsBuf, "true") == 0) { addOption("-Xjitsaveprofilinginfo"); } parseRuntimeOption("dalvik.vm.jitprithreadweight", jitprithreadweightOptBuf, "-Xjitprithreadweight:"); parseRuntimeOption("dalvik.vm.jittransitionweight", jittransitionweightOptBuf, "-Xjittransitionweight:"); /* Madvise related options. */ parseRuntimeOption("dalvik.vm.madvise-random", madviseRandomOptsBuf, "-XX:MadviseRandomAccess:"); /* Profile related options. */ parseRuntimeOption("dalvik.vm.hot-startup-method-samples", hotstartupsamplesOptsBuf, "-Xps-hot-startup-method-samples:"); parseRuntimeOption("dalvik.vm.ps-resolved-classes-delay-ms", saveResolvedClassesDelayMsOptsBuf, "-Xps-save-resolved-classes-delay-ms:"); property_get("ro.config.low_ram", propBuf, ""); if (strcmp(propBuf, "true") == 0) { addOption("-XX:LowMemoryMode"); } /* Garbage-collection related options. */ parseRuntimeOption("dalvik.vm.gctype", gctypeOptsBuf, "-Xgc:"); // If it set, honor the "enable_generational_cc" device configuration; // otherwise, let the runtime use its default behavior. std::string enable_generational_cc = server_configurable_flags::GetServerConfigurableFlag(RUNTIME_NATIVE_BOOT_NAMESPACE, ENABLE_GENERATIONAL_CC, /*default_value=*/ ""); if (enable_generational_cc == "true") { addOption(kGenerationalCCRuntimeOption); } else if (enable_generational_cc == "false") { addOption(kNoGenerationalCCRuntimeOption); } parseRuntimeOption("dalvik.vm.backgroundgctype", backgroundgcOptsBuf, "-XX:BackgroundGC="); /* Enable debugging only for apps forked from zygote. */ if (zygote) { // Set the JDWP provider and required arguments. By default let the runtime choose how JDWP is // implemented. When this is not set the runtime defaults to not allowing JDWP. addOption("-XjdwpOptions:suspend=n,server=y"); parseRuntimeOption("dalvik.vm.jdwp-provider", jdwpProviderBuf, "-XjdwpProvider:", "default"); } // Only pass an explicit opaque-jni-ids to apps forked from zygote if (zygote) { parseRuntimeOption("dalvik.vm.opaque-jni-ids", opaqueJniIds, "-Xopaque-jni-ids:", "swapable"); } parseRuntimeOption("dalvik.vm.lockprof.threshold", lockProfThresholdBuf, "-Xlockprofthreshold:"); if (executionMode == kEMIntPortable) { addOption("-Xint:portable"); } else if (executionMode == kEMIntFast) { addOption("-Xint:fast"); } else if (executionMode == kEMJitCompiler) { addOption("-Xint:jit"); } // If we are booting without the real /data, don't spend time compiling. property_get("vold.decrypt", voldDecryptBuf, ""); bool skip_compilation = ((strcmp(voldDecryptBuf, "trigger_restart_min_framework") == 0) || (strcmp(voldDecryptBuf, "1") == 0)); // Extra options for JIT. if (skip_compilation) { addOption("-Xcompiler-option"); addOption("--compiler-filter=assume-verified"); } else { parseCompilerOption("dalvik.vm.dex2oat-filter", dex2oatCompilerFilterBuf, "--compiler-filter=", "-Xcompiler-option"); } parseCompilerOption("dalvik.vm.dex2oat-threads", dex2oatThreadsBuf, "-j", "-Xcompiler-option"); parseCompilerOption("dalvik.vm.dex2oat-cpu-set", dex2oatCpuSetBuf, "--cpu-set=", "-Xcompiler-option"); // Copy the variant. sprintf(dex2oat_isa_variant_key, "dalvik.vm.isa.%s.variant", ABI_STRING); parseCompilerOption(dex2oat_isa_variant_key, dex2oat_isa_variant, "--instruction-set-variant=", "-Xcompiler-option"); // Copy the features. sprintf(dex2oat_isa_features_key, "dalvik.vm.isa.%s.features", ABI_STRING); parseCompilerOption(dex2oat_isa_features_key, dex2oat_isa_features, "--instruction-set-features=", "-Xcompiler-option"); /* When running with debug.generate-debug-info, add --generate-debug-info to the compiler options so that both JITted code and the boot image extension, * if it is compiled on device, will include native debugging information. */ property_get("debug.generate-debug-info", propBuf, ""); bool generate_debug_info = (strcmp(propBuf, "true") == 0); if (generate_debug_info) { addOption("-Xcompiler-option"); addOption("--generate-debug-info"); } // The mini-debug-info makes it possible to backtrace through compiled code. bool generate_mini_debug_info = property_get_bool("dalvik.vm.minidebuginfo", 0); if (generate_mini_debug_info) { addOption("-Xcompiler-option"); addOption("--generate-mini-debug-info"); } property_get("dalvik.vm.dex2oat-flags", dex2oatFlagsBuf, ""); parseExtraOpts(dex2oatFlagsBuf, "-Xcompiler-option"); /* extra options; parse this late so it overrides others */ property_get("dalvik.vm.extra-opts", extraOptsBuf, ""); parseExtraOpts(extraOptsBuf, NULL); // Extra options for boot image extension generation. if (skip_compilation) { addOption("-Xnoimage-dex2oat"); } else { parseCompilerRuntimeOption("dalvik.vm.image-dex2oat-Xms", dex2oatXmsImageFlagsBuf, "-Xms", "-Ximage-compiler-option"); parseCompilerRuntimeOption("dalvik.vm.image-dex2oat-Xmx", dex2oatXmxImageFlagsBuf, "-Xmx", "-Ximage-compiler-option"); parseCompilerOption("dalvik.vm.image-dex2oat-filter", dex2oatImageCompilerFilterBuf, "--compiler-filter=", "-Ximage-compiler-option"); // If there is a dirty-image-objects file, push it. if (hasFile("/system/etc/dirty-image-objects")) { addOption("-Ximage-compiler-option"); addOption("--dirty-image-objects=/system/etc/dirty-image-objects"); } parseCompilerOption("dalvik.vm.image-dex2oat-threads", dex2oatThreadsImageBuf, "-j", "-Ximage-compiler-option"); parseCompilerOption("dalvik.vm.image-dex2oat-cpu-set", dex2oatCpuSetImageBuf, "--cpu-set=", "-Ximage-compiler-option"); // The runtime may compile a boot image extension, when necessary, not using installd. // Thus, we need to pass the instruction-set-features/variant as an image-compiler-option. // Note: it is OK to reuse the buffer, as the values are exactly the same between // * compiler-option, used for runtime compilation (DexClassLoader) // * image-compiler-option, used for boot-image compilation on device parseCompilerOption(dex2oat_isa_variant_key, dex2oat_isa_variant, "--instruction-set-variant=", "-Ximage-compiler-option"); parseCompilerOption(dex2oat_isa_features_key, dex2oat_isa_features, "--instruction-set-features=", "-Ximage-compiler-option"); if (generate_debug_info) { addOption("-Ximage-compiler-option"); addOption("--generate-debug-info"); } if (generate_mini_debug_info) { addOption("-Ximage-compiler-option"); addOption("--generate-mini-debug-info"); } property_get("dalvik.vm.image-dex2oat-flags", dex2oatImageFlagsBuf, ""); parseExtraOpts(dex2oatImageFlagsBuf, "-Ximage-compiler-option"); } /* Set the properties for locale */ { strcpy(localeOption, "-Duser.locale="); const std::string locale = readLocale(); strncat(localeOption, locale.c_str(), PROPERTY_VALUE_MAX); addOption(localeOption); } // Trace files are stored in /data/misc/trace which is writable only in debug mode. // 跟踪文件存储在/data/misc/Trace中,该文件只能在调试模式下写入。 property_get("ro.debuggable", propBuf, "0"); if (strcmp(propBuf, "1") == 0) { property_get("dalvik.vm.method-trace", propBuf, "false"); if (strcmp(propBuf, "true") == 0) { addOption("-Xmethod-trace"); parseRuntimeOption("dalvik.vm.method-trace-file", methodTraceFileBuf, "-Xmethod-trace-file:"); parseRuntimeOption("dalvik.vm.method-trace-file-siz", methodTraceFileSizeBuf, "-Xmethod-trace-file-size:"); property_get("dalvik.vm.method-trace-stream", propBuf, "false"); if (strcmp(propBuf, "true") == 0) { addOption("-Xmethod-trace-stream"); } } } // Native bridge library. "0" means that native bridge is disabled. // 本机网桥库。“0”表示本机网桥已禁用。 // Note: bridging is only enabled for the zygote. Other runs of app_process may not have the permissions to mount etc. // 桥接仅对合子启用。app\u进程的其他运行可能没有装载等的权限。 property_get("ro.dalvik.vm.native.bridge", propBuf, ""); if (propBuf[0] == '\0') { ALOGW("ro.dalvik.vm.native.bridge is not expected to be empty"); } else if (zygote && strcmp(propBuf, "0") != 0) { snprintf(nativeBridgeLibrary, sizeof("-XX:NativeBridge=") + PROPERTY_VALUE_MAX, "-XX:NativeBridge=%s", propBuf); addOption(nativeBridgeLibrary); } #if defined(__LP64__) const char* cpu_abilist_property_name = "ro.product.cpu.abilist64"; #else const char* cpu_abilist_property_name = "ro.product.cpu.abilist32"; #endif // defined(__LP64__) property_get(cpu_abilist_property_name, propBuf, ""); if (propBuf[0] == '\0') { ALOGE("aosp-acer, %s is not expected to be empty", cpu_abilist_property_name); return -1; } snprintf(cpuAbiListBuf, sizeof(cpuAbiListBuf), "--cpu-abilist=%s", propBuf); addOption(cpuAbiListBuf); // Dalvik-cache pruning counter. parseRuntimeOption("dalvik.vm.zygote.max-boot-retry", cachePruneBuf, "-Xzygote-max-boot-retry="); // If set, the property below can be used to enable core platform API violation reporting. // property_get("persist.debug.dalvik.vm.core_platform_api_policy", propBuf, ""); if (propBuf[0] != '\0') { snprintf(corePlatformApiPolicyBuf, sizeof(corePlatformApiPolicyBuf), "-Xcore-platform-api-policy:%s", propBuf); addOption(corePlatformApiPolicyBuf); } /* Retrieve the build fingerprint and provide it to the runtime. That way, ANR dumps will contain the fingerprint and can be parsed. * 检索构建指纹并将其提供给运行时。这样,ANR转储将包含指纹并可以进行解析。 * Fingerprints are potentially longer than PROPERTY_VALUE_MAX, so parseRuntimeOption() cannot be used here. * 指纹可能比 PROPERTY_VALUE_MAX 长,因此此处不能使用 arseRuntimeOption() 。 * Do not ever re-assign fingerprintBuf as its c_str() value is stored in mOptions. * 当指纹的c_str()值存储在mOptions中,永远不要再重新分配。*/ std::string fingerprint = GetProperty("ro.build.fingerprint", ""); if (!fingerprint.empty()) { fingerprintBuf = "-Xfingerprint:" + fingerprint; addOption(fingerprintBuf.c_str()); } // 以上代码主要是在读取 dalvik.vm.* 属性,然后设置Java虚拟机参数。以下参考 // build/make/target/product/profile_boot_common.mk:27: dalvik.vm.profilesystemserver=true \ // 28: dalvik.vm.profilebootclasspath=true // build/make/target/product/runtime_libart.mk:44: dalvik.vm.image-dex2oat-Xms=64m \ // 45: dalvik.vm.image-dex2oat-Xmx=64m \ // 46: dalvik.vm.dex2oat-Xms=64m \ // 47: dalvik.vm.dex2oat-Xmx=512m \ // 48: dalvik.vm.usejit=true \ // 49: dalvik.vm.usejitprofiles=true \ // 50: dalvik.vm.dexopt.secondary=true \ // 51: dalvik.vm.appimageformat=lz4 // 54: ro.dalvik.vm.native.bridge=0 // 80: dalvik.vm.dex2oat-updatable-bcp-packages-file=/system/etc/updatable-bcp-packages.txt // 84: dalvik.vm.dex2oat-resolve-startup-strings=true // 88: dalvik.vm.dex2oat-max-image-block-size=524288 // 92: dalvik.vm.minidebuginfo=true \ // 93: dalvik.vm.dex2oat-minidebuginfo=true initArgs.version = JNI_VERSION_1_4; initArgs.options = mOptions.editArray(); initArgs.nOptions = mOptions.size(); initArgs.ignoreUnrecognized = JNI_FALSE; /* Initialize the VM. * * The JavaVM* is essentially per-process, and the JNIEnv* is per-thread. * If this call succeeds, the VM is ready, and we can start issuing JNI calls. */ // 创建Java虚拟机。art/runtime/jni/java_vm_ext.cc 约1195行 extern "C" jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) { //【 --- 2.3 --- 】 ALOGE("aosp-acer, JNI_CreateJavaVM failed\n"); return -1; } ALOGE("aosp-acer, JNI_CreateJavaVM执行,DVM创建啦 \n"); return 0; } // end startVm |
2.2. startReg
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
// 约1377行 static const RegJNIRec gRegJNI[] = { // ...... REG_JNI(register_com_android_internal_os_ClassLoaderFactory), // 【--- 2.2.1 -----】frameworks/base/core/jni/com_android_internal_os_ClassLoaderFactory.cpp 约32行 // ...... } // 约1590行 /*static*/ int AndroidRuntime::startReg(JNIEnv* env) { // ...... if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) { env->PopLocalFrame(NULL); return -1; } // ...... } // 约1561行 extern "C" jint registerFrameworkNatives(JNIEnv* env) { return register_jni_procs(gRegJNI, NELEM(gRegJNI), env); } |
2.2.1. register_com_android_internal_os_ClassLoaderFactory
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
static jstring createClassloaderNamespace_native(JNIEnv* env, // 1) 定义函数 jobject clazz, jobject classLoader, jint targetSdkVersion, jstring librarySearchPath, jstring libraryPermittedPath, jboolean isShared, jstring dexPath) { // 约32行 return android::CreateClassLoaderNamespace(env, targetSdkVersion, // 【------ 2.3.1 ------】art/libnativeloader/native_loader.cpp 约90行 jstring CreateClassLoaderNamespace classLoader, isShared == JNI_TRUE, dexPath, librarySearchPath, libraryPermittedPath); } static const JNINativeMethod g_methods[] = { { "createClassloaderNamespace", "(Ljava/lang/ClassLoader;ILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;)Ljava/lang/String;", reinterpret_cast<void*>(createClassloaderNamespace_native) }, // 2) 封装为jni函数 }; static const char* const kClassLoaderFactoryPathName = "com/android/internal/os/ClassLoaderFactory"; namespace android { int register_com_android_internal_os_ClassLoaderFactory(JNIEnv* env) { // 这个函数在 frameworks/base/core/jni/AndroidRuntime.cpp 约1452行 被JNI注册 return RegisterMethodsOrDie(env, kClassLoaderFactoryPathName, g_methods, NELEM(g_methods)); // 3) 注册为JNI函数 } } |
2.3. JNI_CreateJavaVM
art/runtime/jni/java_vm_ext.cc 约1195行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
// JNI Invocation interface. // 创建Java虚拟机 extern "C" jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) { ScopedTrace trace(__FUNCTION__); const JavaVMInitArgs* args = static_cast<JavaVMInitArgs*>(vm_args); if (JavaVMExt::IsBadJniVersion(args->version)) { LOG(ERROR) << "Bad JNI version passed to CreateJavaVM: " << args->version; return JNI_EVERSION; } RuntimeOptions options; for (int i = 0; i < args->nOptions; ++i) { // 解析虚拟机参数存到JavaVMOption中。 JavaVMOption* option = &args->options[i]; options.push_back(std::make_pair(std::string(option->optionString), option->extraInfo)); } bool ignore_unrecognized = args->ignoreUnrecognized; if (!Runtime::Create(options, ignore_unrecognized)) { // 调用Create函数,创建Runtime实例。art/runtime/runtime.cc return JNI_ERR; } // Initialize native loader. This step makes sure we have everything set up before we start using JNI. // 初始化native加载程序。这一步确保我们在开始使用JNI之前已经设置好了一切。 android::InitializeNativeLoader(); // 【--- 2.3.1 ---】art/libnativeloader/native_loader.cpp 约76行 void InitializeNativeLoader() Runtime* runtime = Runtime::Current(); bool started = runtime->Start(); // art/runtime/runtime.cc 约845行 bool Runtime::Start() if (!started) { delete Thread::Current()->GetJniEnv(); delete runtime->GetJavaVM(); // 【--- 2.4 ---】art/runtime/jni/jni_internal.cc 约2615行 static jint GetJavaVM(JNIEnv* env, JavaVM** vm) LOG(WARNING) << "CreateJavaVM failed"; return JNI_ERR; } |
2.3.1. CreateClassLoaderNamespace和InitializeNativeLoader
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
#include "library_namespaces.h" // 约50行 std::mutex g_namespaces_mutex; LibraryNamespaces* g_namespaces = new LibraryNamespaces; // art/libnativeloader/library_namespaces.h约42行 // 约76行 void InitializeNativeLoader() { #if defined(__ANDROID__) std::lock_guard<std::mutex> guard(g_namespaces_mutex); g_namespaces->Initialize(); // 【--- 2.3.2 ---】 #endif } // 约90行 jstring CreateClassLoaderNamespace(JNIEnv* env, int32_t target_sdk_version, jobject class_loader, bool is_shared, jstring dex_path, jstring library_path, jstring permitted_path) { #if defined(__ANDROID__) std::lock_guard<std::mutex> guard(g_namespaces_mutex); auto ns = g_namespaces->Create(env, target_sdk_version, class_loader, is_shared, dex_path, library_path, permitted_path); // 【--- 2.3.3 ---】 if (!ns.ok()) { return env->NewStringUTF(ns.error().message().c_str()); } #else UNUSED(env, target_sdk_version, class_loader, is_shared, dex_path, library_path, permitted_path); #endif return nullptr; } |
2.3.2. LibraryNamespaces.Initialize
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// 约119行 void LibraryNamespaces::Initialize() { // Once public namespace is initialized there is no // point in running this code - it will have no effect // on the current list of public libraries. if (initialized_) { return; } // 【----2.3.2.1 -------】 art/libnativeloader/public_libraries.cpp 约318行 preloadable_public_libraries for (const auto& soname : android::base::Split(preloadable_public_libraries(), ":")) { LOG_ALWAYS_FATAL_IF(dlopen(soname.c_str(), RTLD_NOW | RTLD_NODELETE) == nullptr, "Error preloading public library %s: %s", soname.c_str(), dlerror()); } } |
2.3.2.1. preloadable_public_libraries
1 2 3 4 5 |
// 约318行 const std::string& preloadable_public_libraries() { static std::string list = InitDefaultPublicLibraries(/*for_preload*/ true); // 【---2.3.4---】167行static std::string InitDefaultPublicLibraries(bool for_preload) return list; } |
2.3.3. LibraryNamespaces.Create
1 2 3 4 5 6 7 8 9 10 |
// 约141行 Result<NativeLoaderNamespace*> LibraryNamespaces::Create(JNIEnv* env, uint32_t target_sdk_version, jobject class_loader, bool is_shared, jstring dex_path, jstring java_library_path, jstring java_permitted_path) { // ...... std::string system_exposed_libraries = default_public_libraries(); // 【---2.3.4---】 art/libnativeloader/public_libraries.cpp 约323行 const std::string& default_public_libraries() // ...... } |
2.3.4. InitDefaultPublicLibraries和default_public_libraries
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
// 约49行 constexpr const char* kDefaultPublicLibrariesFile = "/etc/public.libraries.txt"; // 连接手机用adb shell查看 constexpr const char* kExtendedPublicLibrariesFilePrefix = "public.libraries-"; constexpr const char* kExtendedPublicLibrariesFileSuffix = ".txt"; constexpr const char* kVendorPublicLibrariesFile = "/vendor/etc/public.libraries.txt"; constexpr const char* kLlndkLibrariesFile = "/apex/com.android.vndk.v{}/etc/llndk.libraries.{}.txt"; constexpr const char* kVndkLibrariesFile = "/apex/com.android.vndk.v{}/etc/vndksp.libraries.{}.txt"; // 约167行 static std::string InitDefaultPublicLibraries(bool for_preload) { std::string config_file = root_dir() + kDefaultPublicLibrariesFile; // ...... } // 约323行 const std::string& default_public_libraries() { static std::string list = InitDefaultPublicLibraries(/*for_preload*/ false); // 167行static std::string InitDefaultPublicLibraries(bool for_preload) return list; } |
public.libraries.txt常用于添加自己的so库,与之有关的“UnsatisfiedLinkError”问题,参考:
https://blog.csdn.net/qq_38907791/article/details/91039130
https://blog.csdn.net/k663514387/article/details/106357975
2.4. GetJavaVM
art/runtime/jni/jni_internal.cc 约2615行
1 2 3 4 5 6 7 8 9 10 11 |
static jint GetJavaVM(JNIEnv* env, JavaVM** vm) { LOG(ERROR) << "获取JVM,art/runtime/jni/jni_internal.cc 约2615行,GetJavaVM"; CHECK_NON_NULL_ARGUMENT_RETURN(vm, JNI_ERR); Runtime* runtime = Runtime::Current(); // art/runtime/runtime.h 约245行 static Runtime* Current() if (runtime != nullptr) { *vm = runtime->GetJavaVM(); // art/runtime/runtime.h 约316行 JavaVMExt* GetJavaVM() } else { *vm = nullptr; } return (*vm != nullptr) ? JNI_OK : JNI_ERR; } |
3. ZygoteInit
见下一篇。
- end
本文由崔维友 威格灵 cuiweiyou vigiles cuiweiyou 原创,转载请注明出处:http://www.gaohaiyan.com/4073.html
承接App定制、企业web站点、办公系统软件 设计开发,外包项目,毕设