Wrap Shell Script

When debugging and profiling apps with native code, it’s often useful to be able to bundle command-line developer tools in your APK and run them automatically on the device when the app launches.

Beginning in Android 8.0, you can opt to create and package a user-defined shell script that the system automatically runs in a fresh process when you launch a debuggable app. This feature lets you write a script to invoke native developer tools to perform such operations as:

Using the wrap shell script

To run native developer tools on the device using the wrap shell script, follow these steps:

  1. Compile a custom debuggable APK that packages the following:
  2. Install the debuggable APK on a device. Depending on the Android platform version on the device, you may need to modify access control over processes for the wrap shell script to run.
    • Android 8.1 (API level 27) or higher: No such modification is needed.
    • Android 8.0 (API level 26): The device must have SELinux enforcement disabled. You can disable SELinux enforcement via adb on userdebug or eng builds. Supported devices with these permission levels are:
      • An Android emulator with a userdebug system image, or
      • A Google device flashed with an AOSP eng build or root image.
  3. Launch the app normally on your device, either via the app launcher or from the command line.
  4. It is strongly recommended to re-enable SELinux enforcement on your device when done.

Creating the wrap shell script

You can create a shell script named wrap.sh to customize your runtime environment. In your script, you can set environment variables and modify runtime arguments. The script should follow MirBSD Korn shell (mksh) syntax.

When you launch a debuggable APK that contains wrap.sh, the system executes the script and grants it control over the app process. The system passes the command to start the requested app as an argument to the wrap.sh invocation. Note that your script is responsible for starting the app.

The following snippet shows how to write a simple wrap.sh file that just starts the app:


To start the malloc debug tool using wrap.sh, you would include the following line:

LIBC_DEBUG_MALLOC_OPTIONS=backtrace logwrapper $@

Packaging wrap.sh

To take advantage of wrap.sh, you must build a debuggable APK. Make sure that the android:debuggable=”true”setting is configured in the <application> element in your Android manifest.

You must package the wrap.sh script with the native libraries of the app. If your app does not contain native libraries, add the lib directory manually to your project directory. For all architectures that your app supports, you must provide a copy of the wrap shell script under their respective native-library architecture directories.

The following project directory example shows the file layout to support both the x86 and ARMv8 architectures:

# App Directory
|- AndroidManifest.xml
|- …
|- lib
   |- x86
      |- ...
      |- wrap.sh
   |- arm64-v8a
      |- ...
      |- wrap.sh

Make sure that your wrap.sh script is executable (that is, its executable bit is set). For example:

$ ls -l lib/x86/wrap.sh
-rwxr-x--x 1 user user 0 Jan 01  1980 lib/x86/wrap.sh