0

Consider this scenario:

There is an Android app that does stuff, which could be in different threads. Some of these may cause segmentation violations (SIGSEGV's). I want to be able to catch all of the violations, irrespective of the thread that caused it, from a signal handler written in C using NDK.

Actually, I have written such handler by using sigaction. And it works but only for the thread that will run the NDK code. This is because SIGSEGVs are delivered to the thread that caused the violation, in contrary with let's say SIGKILL which is delivered to the process. As a result, my handler does not receive SIGSEGVs caused by other threads, and the program gets killed.

Is there a way to cause all SIGSEGVs to be redirected to my handler? Or, alternatively, a way to override the default handler for ALL the threads?

And yes, there is a reason I want this particular thing in the way I have describe it! ;)

Paschalis
  • 11,929
  • 9
  • 52
  • 82
  • 1
    Some info here: http://stackoverflow.com/questions/1083154/how-can-i-catch-sigsegv-segmentation-fault-and-get-a-stack-trace-under-jni-on/ . Make a JNI call from each of your threads to set the handlers for that thread. Make sure you identify your specific crashes and chain to the previous handler. – fadden Oct 14 '15 at 23:07
  • @fadden sorry, my question wasn't very clear! Let's assume that I won't have access to the threads. I don't know what an application might be doing, I just want to handle all the SIGSEGV's caused by it. – Paschalis Oct 14 '15 at 23:17
  • What you want is called uncaught exception handler. It exists in Java, not sure what it is called in c/c++. – 18446744073709551615 Oct 15 '15 at 12:37
  • 1
    I don't know a way to set a signal handler for a running thread other than the current one. The way you set up a global signal handler is by establishing it on the main thread and letting every newly-created thread inherit it, but that's not an option here. FWIW, all threads do have SIGSEGV handlers, as part of the debuggerd crash reporting mechanism. Signals are always delivered to a specific thread (note behavior of `kill` vs. `tgkill` though); SIGKILL is unusual in that it cannot be caught. – fadden Oct 16 '15 at 01:46

1 Answers1

0

You may catch a SIGSEGV, but you cannot free resources that would be free if that SIGSEGV did not happen. Java has a garbage collector (and in some cases even gc does not save from memory leaks), but c/c++ code must either free() or delete or delete[] what it has allocated (but not alloca()-ed).

I would place the stuff that does the risky native things into a separate process. (Android apps may consist of multiple processes.) When a process dies, its garbage dies as well. And the main process would have to detect that the worker process has died.

18446744073709551615
  • 16,368
  • 4
  • 94
  • 127
  • I am not doing this for `free`s or `malloc`s! I am removing permissions from virtual pages, using `mprotect`. A these pages are presumably being used by other threads. A `sigsegv` occurs in that thread, and what I want is to be able to handle it. So I need to redirect it, or something else. **Is this possible?** – Paschalis Oct 15 '15 at 12:57
  • 1
    In other words, you remove permissions on virtual pages and when an exception happens in a thread, you want to give the permission back and resume execution of that thread. In theory, this should be possible. This is very similar to what the debuggers do. But the debuggers usually start a child process. Probably a kernel module could help you. Write up a description of _your memory management task_ in more detail than just "catch SIGSEGV", and ask another SO question tagging it POSIX (or search using the words from your description and probably "debugger" and "kernel module"). – 18446744073709551615 Oct 16 '15 at 08:51