In my application I create a process to record a log file extracted from logcat into an Android device. To do this I use a Process that just executes logcat -f log
with su
permissions and I keep the reference to this process to let the user cancel the log.
The problem is: in my Android version (4.1) I get this exception when I try to call process.destroy()
I/System ( 2948): Failed to destroy process 3134
D/dalvikvm( 2221): GC_CONCURRENT freed 499K, 12% free 6962K/7879K, paused 12ms+10ms, total 84ms
I/System ( 2948): libcore.io.ErrnoException: kill failed: EPERM (Operation not permitted)
I/System ( 2948): at libcore.io.Posix.kill(Native Method)
I/System ( 2948): at libcore.io.ForwardingOs.kill(ForwardingOs.java:77)
I/System ( 2948): at java.lang.ProcessManager$ProcessImpl.destroy(ProcessManager.java:260)
I/System ( 2948): at com.blablabla.android.core.device.debug.DebugDevice.destroyProcess(DebugDevice.java:127)
I/System ( 2948): at com.blablabla.android.core.device.debug.DebugDevice.cancelLogcatToFile(DebugDevice.java:98)
After checking this, I've modified my cancelLogcatToFile with the suggested solution, so my code is like this:
private void exportLogcatToFile(String fileName) {
String command = new StringBuffer("logcat -f ").append(fileName)
.append("\n").toString();
try {
logcatToFileProcess = Runtime.getRuntime().exec("su");
final DataOutputStream os = new DataOutputStream(
logcatToFileProcess.getOutputStream());
os.writeBytes(command);
} catch (IOException e) {
Log.e(TAG, Log.getStackTraceString(e));
}
}
And to kill the process:
private void cancelLogcatToFile() {
if (logcatToFileProcess != null) {
// logcatToFileProcess.destroy();
destroyProcess(logcatToFileProcess);
logcatToFileProcess = null;
}
}
private static void destroyProcess(Process process) {
try {
if (process != null) {
// use exitValue() to determine if process is still running.
process.exitValue();
}
} catch (IllegalThreadStateException e) {
// process is still running, kill it.
process.destroy();
}
}
Thank you!
EDIT: This code is going to be executed in a rooted device, so su
will not be a problem.
Also, I know I could do something like killall logcat
but I want to keep another logcat processes alive
I suspect that if you use your hacked su
shim to launch the process as root, then to literally kill it you will also have to use su
to launch the kill
command in order to kill it, as a regular user (such as your application process) cannot kill a process owned by root.
The other possibility would be to see if there is something that would make the process exit on its own.