[[["易于理解","easyToUnderstand","thumb-up"],["解决了我的问题","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["没有我需要的信息","missingTheInformationINeed","thumb-down"],["太复杂/步骤太多","tooComplicatedTooManySteps","thumb-down"],["内容需要更新","outOfDate","thumb-down"],["翻译问题","translationIssue","thumb-down"],["示例/代码问题","samplesCodeIssue","thumb-down"],["其他","otherDown","thumb-down"]],["最后更新时间 (UTC):2024-08-22。"],[],[],null,["# Wrap shell script\n\nWhen debugging and profiling apps with native code, it's often useful to use\ndebugging tools that need to be enabled at process startup. This requires that\nyou run your app in a fresh process rather than cloning from the zygote.\nExamples include:\n\n- Tracing system calls with [strace](https://strace.io/).\n- Finding memory bugs with [malloc debug](https://android.googlesource.com/platform/bionic/+/master/libc/malloc_debug/README.md) or [Address Sanitizer (ASan)](https://github.com/google/sanitizers/wiki/AddressSanitizerOnAndroid).\n- Profiling with [Simpleperf](https://developer.android.com/ndk/guides/simpleperf.html).\n\nUse the wrap shell script\n-------------------------\n\n| **Note:** `wrap.sh` is only available for API level 27 and above.\n\nUsing `wrap.sh` is easy:\n\n1. Compile a custom debuggable APK that packages the following:\n - A shell script named `wrap.sh`. See [Create the wrap shell script](#creating_the_wrap_shell_script) and [Package wrap.sh](#packaging_wrapsh) for more details.\n - Any extra tools your shell script needs (such as your own `strace` binary).\n2. Install the debuggable APK on a device.\n3. Launch the app.\n\nCreate the wrap shell script\n----------------------------\n\nWhen you launch a debuggable APK that contains `wrap.sh`, the system executes\nthe script and passes the command to start the app as arguments. The script is\nresponsible for starting the app, but can make any environment or argument\nchanges. The script should follow\n[MirBSD Korn shell](https://www.mirbsd.org/mksh.htm) (mksh) syntax.\n\nThe following snippet shows how to write a simple `wrap.sh` file that just\nstarts the app: \n\n```\n#!/system/bin/sh\nexec \"$@\"\n```\n\n### Malloc debug\n\nTo use\n[malloc debug](https://android.googlesource.com/platform/bionic/+/master/libc/malloc_debug/README.md)\nvia `wrap.sh`, you would include the following line: \n\n```\n#!/system/bin/sh\nLIBC_DEBUG_MALLOC_OPTIONS=backtrace logwrapper \"$@\"\n```\n\n### ASan\n\nThere's an example of how to do this for ASan in the\n[ASan documentation](/ndk/guides/asan).\n\nPackage wrap.sh\n---------------\n\nTo take advantage of `wrap.sh`, your APK must be debuggable. Make sure that the\n`android:debuggable=\"true\"`setting is configured in the\n[`\u003capplication\u003e`](https://developer.android.com/guide/topics/manifest/application-element.html)\nelement in your Android manifest, or if you are using Android Studio that\nyou've configured a debug build in the\n[`build.gradle`](/studio/build/build-variants#build-types) file.\n\nIt's also necessary to set [`useLegacyPackaging`](/reference/tools/gradle-api/7.1/com/android/build/api/dsl/JniLibsPackagingOptions#uselegacypackaging)\nto `true` in your app's `build.gradle` file. In most cases, this option is set\nto `false` by default, so you might want to set this explicitly to `true` to\navoid any surprises.\n\nYou must package the `wrap.sh` script with the native libraries of the app. If\nyour app does not contain native libraries, add the lib directory manually to\nyour project directory. For each architecture that your app supports, you must\nprovide a copy of the wrap shell script under that native library directory.\n\nThe following example shows the file layout to support both the ARMv8 and x86-64\narchitectures: \n\n```\n# App Directory\n|- AndroidManifest.xml\n|- …\n|- lib\n |- arm64-v8a\n |- ...\n |- wrap.sh\n |- x86_64\n |- ...\n |- wrap.sh\n```\n\nAndroid Studio only packages `.so` files from the `lib/` directories, so if\nyou're an Android Studio user, you'll need to place your `wrap.sh` files in the\n`src/main/resources/lib/*` directories instead, so that they'll be packaged\ncorrectly.\n\nNote that `resources/lib/x86` will be displayed in the UI as\n`lib.x86`, but it should actually be a subdirectory:\n\nDebug when using wrap.sh\n------------------------\n\nIf you want to attach a debugger when using `wrap.sh`, your shell script will\nneed to manually enable debugging. How to do this has varied between releases,\nso this example shows how to add the appropriate options for all releases that\nsupport `wrap.sh`: \n\n #!/system/bin/sh\n\n cmd=$1\n shift\n\n os_version=$(getprop ro.build.version.sdk)\n\n if [ \"$os_version\" -eq \"27\" ]; then\n cmd=\"$cmd -Xrunjdwp:transport=dt_android_adb,suspend=n,server=y -Xcompiler-option --debuggable $@\"\n elif [ \"$os_version\" -eq \"28\" ]; then\n cmd=\"$cmd -XjdwpProvider:adbconnection -XjdwpOptions:suspend=n,server=y -Xcompiler-option --debuggable $@\"\n else\n cmd=\"$cmd -XjdwpProvider:adbconnection -XjdwpOptions:suspend=n,server=y $@\"\n fi\n\n exec $cmd"]]