wrap.sh를 활용하려면 APK를 디버깅할 수 있어야 합니다. android:debuggable="true" 설정이 Android 매니페스트의 <application> 요소에 구성되어 있거나 build.gradle 파일에 디버그 빌드를 구성하는 Android 스튜디오를 사용하는지 확인하세요.
또한 앱의 build.gradle 파일에서 useLegacyPackaging을 true로 설정해야 합니다. 대부분의 경우 이 옵션은 false로 기본 설정되어 있으므로 명시적으로 true로 설정하여 예기치 않은 상황의 발생을 방지하는 것이 좋습니다.
앱의 네이티브 라이브러리로 wrap.sh 스크립트를 패키징해야 합니다. 앱에 네이티브 라이브러리가 포함되어 있지 않으면 프로젝트 디렉터리에 lib 디렉터리를 직접 추가해야 합니다. 앱에서 지원하는 각 아키텍처의 경우 해당 네이티브 라이브러리 디렉터리에 셸 스크립트 래핑의 사본을 제공해야 합니다.
이 페이지에 나와 있는 콘텐츠와 코드 샘플에는 콘텐츠 라이선스에서 설명하는 라이선스가 적용됩니다. 자바 및 OpenJDK는 Oracle 및 Oracle 계열사의 상표 또는 등록 상표입니다.
최종 업데이트: 2024-08-22(UTC)
[[["이해하기 쉬움","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"]],["최종 업데이트: 2024-08-22(UTC)"],[],[],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"]]