C native android app crashes on Oreo and above due to signal(SIGALARM) call


I have created a C library using Android NDK and created an apk using this prebuild library. This apk calls the foo() function of the library. In this library I have two functions foo() and add(), foo() will call add() using signal(SIGALARM). In C library, there is a memory allocation on the stack (simple declaring an array), if I allocate memory more than 9MB it will crash with sigsegv. You can also suggest an alternative of a signal in C on Unix platform as I want to call this add() function in the background only.

This apk runs fine till nougat. On Oreo and above the background process killed after a certain amount of memory allocation and I have found a workaround on java but I want to do the same on C what should I do please help. I have tried heap memory allocation which runs fine. But I want memory allocation on the stack only, when I allocate stack memory on foreground it runs fine. And how do I push notification using C?

Library code:

int foo(int a)
{

signal(SIGALRM, add);
alarm(5);
return ++a;
}

void add(int signo)
{


char arr[100000];

//char *bytes = alloca(100000);

sleep(2);

alarm(2);
//sleep(5);
return;
}


apk code:

JNIEXPORT jstring JNICALL
Java_com_example_sample_MainActivity_stringFromJNI(JNIEnv *env, jobject instance)
{


int calls = foo(5);

while(1){

break;
}

//pause();

return (*env)->NewStringUTF(env, "success");
}
Last edited on
TBH, several MB on the stack is a bad design, regardless of whether it happens to work for you in some cases.

If you're worried about memory leaks, then perhaps a worker function
1
2
3
4
5
6
7
8
void add_worker(char *buffer) {
}
void add(int signum) {
    char *buffer = malloc(1000000);  //!! Except it's not sig-safe !!
    if ( buffer ) add_worker(buffer);
    free( buffer );
    // sleep, alarm or whatever
}


Or just allocate it once as a static.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
static char *buffer = NULL;

// Native code....

JNIEXPORT jstring JNICALL
Java_com_example_sample_MainActivity_stringFromJNI(JNIEnv *env, jobject instance)
{
  buffer = malloc(1000000);
  int calls = foo(5);
  while(1){
    break;
  }
  return (*env)->NewStringUTF(env, "success");
}

JNIEXPORT jstring JNICALL
Java_com_example_sample_CloseActivity_stringFromJNI(JNIEnv *env, jobject instance)
{
  free(buffer);
  buffer = NULL;
  return (*env)->NewStringUTF(env, "bye!");
}


Similarly, using sigalarm as a "poor man's thread" seems equally problematic.
Why not just use a thread?

This is a list of the only functions you can call safely from a signal handler.
What else were you doing in 'add' that required megabytes of memory?
http://man7.org/linux/man-pages/man7/signal-safety.7.html
why stack only? Heap, used as shown above in the static example, is just as fast if this is a performance question. The heap is only noticeably slow if you are constantly getting and freeing it, over and over. If its threaded, the static idea is dangerous and you must take care (but a pool of static buffers can do the trick, or mutex locks). What is your real goal here (don't just say "I want it on the stack because I want it on the stack").
Last edited on
Topic archived. No new replies allowed.