0

I currently start an executable on my mobile using adb shell (binary needs the "shell" user permissions). I want to keep the process running in the background for as long as possible, but the process dies every time I disconnect the USB cord.

The testing device's OS is an unofficial Version of LineageOS / Android 8.1.

I have tried:

  • starting the executable with all combinations of "nohup" and "> /dev/null 2> /dev/null < /dev/null &"
  • to catch and handle every possible signal in the executable itself
  • to fork off the process as a daemon
  • all of the above combined

My current code is the following, compiled in a standard NDK-project with the CMake configuration "add_executable(libDaemonize.so Daemonize.c)" and executed in adb shell with "nohup /data/app/org.app.name/lib/arm/libDaemonize.so > /dev/null 2> /dev/null < /dev/null &". The "lib***.so" name is necessary to automatically pack the binary into the apk and install it on the device with executable permissions.

/*Based on https://stackoverflow.com/a/17955149/11250128*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <syslog.h>

void INThandler(int);

static void skeleton_daemon()
{
    pid_t pid;

    /* Fork off the parent process */
    pid = fork();

    /* An error occurred */
    if (pid < 0)
        exit(EXIT_FAILURE);

    /* Success: Let the parent terminate */
    if (pid > 0) {
        syslog (LOG_NOTICE, "From starter: PID: %d, PPID: %d\n", getpid(), getppid());
        exit(EXIT_SUCCESS);
    }
    /* On success: The child process becomes session leader */
    if (setsid() < 0)
        exit(EXIT_FAILURE);

    /* Catch, ignore and handle ALL signals */
    int i;
    for(i=1; i<32; i++) {
        signal(i, INThandler);
    }

    /* Fork off for the second time*/
    pid = fork();

    /* An error occurred */
    if (pid < 0)
        exit(EXIT_FAILURE);

    /* Success: Let the parent terminate */
    if (pid > 0)
        exit(EXIT_SUCCESS);

    /* Set new file permissions */
    umask(0);

    /* Change the working directory to the root directory */
    /* or another appropriated directory */
    chdir("/");

    /* Close all open file descriptors */
    int x;
    for (x = sysconf(_SC_OPEN_MAX); x>=0; x--)
    {
        close (x);
    }

    /* Open the log file */
    openlog ("testdaemon", LOG_PID, LOG_DAEMON);
}


int main()
{
    skeleton_daemon();

    while (1)
    {
        syslog (LOG_NOTICE, "Daemon running. PID: %d, PPID: %d\n", getpid(), getppid());
        sleep (1);
    }

    syslog (LOG_NOTICE, "Daemon terminated.");
    closelog();

    return EXIT_SUCCESS;
}

/*Define signal handlers to find out what signal kills us */
void INThandler(int sig)
{
    syslog(LOG_CRIT, "Daemon received Signal %d", sig);
}

The calls all succeed and work as expected (e.G. the daemon taking init/pid 1 as a parent), but as soon as the USB cord is disconnected, the application stops printing to syslog.

My best guess is that the Android system actively kills the process, but neither the Adbd logs (activated via "setprop persist.adb.trace_mask") nor after my search in the Adb source I found any evidence for this.

I feel like I miss something obvious. Thanks for your ideas.

Dan Albert
  • 8,619
  • 1
  • 30
  • 72
Ogm
  • 1
  • 2
  • are you sure you do not mix different versions of adb? usually, the server gets killed/respawned when you try to use a different version of adb command. – OznOg Mar 24 '19 at 17:03
  • There is no problem with adb itself. It is the binary I started via adb shell that dies/gets killed on a cable reconnect. The version of adb before and after the reconnect are identical. – Ogm Mar 24 '19 at 17:13
  • not all signals can be caught. The application does not see the same signals as the 'adb' sees – user3629249 Mar 24 '19 at 18:28
  • Thanks for the reply. I am aware that not all signals can be caught, but then again I was not able to find any reason for the process being killed (or receiving any other signals but SIGHUP) in the adbd logs or source code. – Ogm Mar 24 '19 at 20:57

0 Answers0