I am trying to start a native app from within an android app (Android Jelly bean (4.1.2)). I am able to start the native app manually from adb, however it does not start from android. The native app is inside AsyncTask and it is started by the doInBackground function. The command I use to start the app inside android is:
process = Runtime.getRuntime().exec("/data/data/MyAppDir/CAL_Android > /data/data/MyAppDir/out.txt 2>&1 &");
I simplified the command as below, but still did not start:
process = Runtime.getRuntime().exec("/data/data/MyAppDir/CAL_Android");
My various attempts at debugging the issue:
Start a simple command, like "touch file.txt" from android. Works
Moved the native app to /data/local/tmp. Did not work.
Changed the execute permission to 777 (rwxrwxrwx). Did not work.
Changed the owner to root apart from that of the app. Did not work.
Tried using a thread (implements Runnable instead of extends AsyncTask). Did not work.
Execute command using "su -c" ("su -c /data/data/MyAppDir/CAL_Android"). Did not work.
Place the command to execute inside a shell script and invoke shell script from Android. Did not work.
I checked the dmesg output and the error I get is:
<7>[14156.022980] CAL_Android: unhandled page fault (11) at 0x0000000c, code 0x017
<1>[14156.023010] pgd = e6204000
<1>[14156.026306] [0000000c] *pgd=b0728831, *pte=00000000, *ppte=00000000
<4>[14156.032777]
<4>[14156.034242] Pid: 9408, comm: CAL_Android
<4>[14156.051821] CPU: 0 Tainted: G W (3.4.0-ge11b2fc-dirty #1)
<4>[14156.061557] PC is at 0x4012aa22
Can someone please tell me what the problem is?
EDIT:
The dmesg output is not correct. After checking a few more times, I am not getting the error message in dmesg. The crash seems to have happened due to a different unknown reason. But I have added an answer to the reason for not being able to start the native app from android. Hopefully this helps someone who faces a similar issue.
I found out why the android app was not able to start the native app, by using the below 2 lines and printing them in the log.
BufferedReader std_input = new BufferedReader(new InputStreamReader(process.getInputStream()));
BufferedReader std_error = new BufferedReader(new InputStreamReader(process.getErrorStream()));
String line;
while ((line = std_error.readLine()) != null) {
Log.i(TAG, line);
}
When I used "su -c" before my command, I got this error message:
su: uid <xyz> not allowed to su
and when I did not use "su -c" I got this one instead:
"Cannot open socket: Operation not permitted"
The reason is that, the android app does not have root permission to start the native app and the native app needs root permission to open a socket for sending and receiving data.
Related
I have built a custom ROM that I'm testing on Android Cuttlefish, but when I go to boot the device on the command line using the launch_cvd command, I get the following errors:
[assemble_cvd ... fetcher_config.cpp:212] Could not find file ending in kernel
[assemble_cvd ... fetcher_config.cpp 212] Could not find file ending in initramfs.img
run_cvd returned 23
Subprocess 39641 exited with error code: 23
The main issue seems to lie in the 'error 23' that is returned by run_cvd.
I have tried Google searching and browsing popular forums where Android is built and debugged (XDA Forums, Reddit, StackOverflow, the Android Building Google Group, YouTube, and the web in general). I have also posted on Reddit and will post on the Android Building Google Group. Additionally, I have looked through the source code for Cuttlefish on Google's Git repo to find why the program is outputting the error to no avail.
Lastly, I read through the logfiles of Cuttlefish to see the errors outputted by Cuttlefish. The kernel.log file seems to show the kernel booted successfully (despite the command line saying that it couldn't find the kernel file), I would imagine the same is true of initramfs.img, but I have no way of confirming that initramfs.img was successfully found by launch_cvd. The logcat file is empty (likely because the Cuttlefish failed to boot) and launcher.log simply reproduces the output on the command line (which contain the four errors I listed above).
Could anyone help me troubleshoot this issue? Your help would be greatly appreciated!
Do ps -A | grep crosvm to see if crosvm is running already.
If it is do stop_cvd || true or kill crosvm process with process PID.
I have a C binary that I run using root user (su -c binary_path) in Android.
Everything works fine until the binary tries to exec*() another binary. It actually works on most devices, however on some I get EACCES error.
The C binary is actually started using this:
execlp("su","su","-c",binary_path,NULL);
At some point, the binary will try to make those calls (simplified):
fork();
...
// child here
execlp("sh","sh","-c",script,NULL);
Actually tested on different Android 6.0 devices, a Nexus 9 and a S7. Nexus 9 ok, S7 fails.
So I checked all permissions and security context of the following, found no difference:
/system/bin
/system/bin/sh
/system/bin/ls
<library_path>
/su/bin/su
Also checked the binary was running with UID/GID = 0, true on both devices.
In logcat, I don't see any audit for a missing permission or secure policy violation.
EDIT: Just verified the security context the binary is running under:
$ps -Z
u:r:init:s0 root ...
Same for both devices whether exec() works or not.
EDIT2: On the device it fails, /proc/kmsg contains this when trying to exec():
Restricted making process. PID = 8868(<binary>) PPID = 8340(<binary>)
No avc from selinux, and this text cannot be found in AOSP source code.
After searching for "Restricted making process" on Google, I stumbled across Samsung kernels for the S5 and S6 (not the S7).
if(CHECK_ROOT_UID(current))
if(sec_restrict_fork())
{
PRINT_LOG("Restricted making process. PID = %d(%s) "
"PPID = %d(%s)\n",
current->pid, current->comm,
current->parent->pid, current->parent->comm);
return -EACCES;
}
And the sec_restrict_fork() contains this:
if (sec_check_execpath(current->mm, "/data/")) {
ret = 1;
goto out;
}
Hence the failure on Samsung devices and no others.
I want to start a custom program in the init process. I compiled this program statically that run fine from my booted up android stock ROM.
From the android init.rc docs I read that the exec command is what I need.
BTW all I can see in dmesg is that my program exit with code -1 (I can't return that).
init.rc snippet:
on post-fs-data
write /dev/kmsg "launching test"
exec /data/test
All I see in dmesg is this:
<4>[ 6.336816] launching test
<6>[ 6.336902] init: command 'write' r=0
<6>[ 6.337115] init: command 'exec' r=-1
Here you are the executable source code: http://pastebin.com/Hym1APWx
UPDATE
I tried to statically compile and run this program:
int main(){return 0; }
But the result is always command 'exec' r=-1. Maybe user uselen are right, maybe I cannot run executables from /data in the early-boot phase.
As christian said, it looks like exec isn't even implemented. I'm beginning to think that a lot of features documented for init.rc aren't implemented. Here's a way you can get your program to launch however.
Instead of running this as an "exec" command, set this up as a service instead.
In your init.rc, or another file included by it:
service my_service /data/test
class main
oneshot
If it's in class main, and not disabled, it should run after /data is mounted.
I had the same issue today. In my case the solution was simple: The exec function wasn't implemented yet and contained just a return -1. You should take a look at builtin.c and search for do_exec(). This code is executed when init.rc contains an exec statement.
I'm getting below error with systrace tool provided by android Jelly bean SDK on windows 2003 PC with python 2.7
executing below command in cygwin editor
python systrace.py --time=10 -o mynewtrace.html
▒GS{▒&▒izAr ▒▒9▒Zww▒▒▒Hj▒▒K▒[X▒▒▒4▒i▒▒D▒▒#▒"▒▒▒]▒lJ▒!▒▒)K▒dKY▒▒:\▒?▒ ▒?w%{D▒g▒?Q&▒wQ▒▒p%'T▒▒oE▒(▒:▒▒k▒▒◄▒▒)▒2▒?▒%▒▒4▒w^▒ ▒~▒▒/▒g▒7?M?▒c▒r#/▒oDE▒tg▒▒N▒▒S'\▒▒▒▒↓▒▒GY▒x▒↓▒2D'↓CN▒{▒f2?pu▒▒?▒▒▒▒(g▒▒9▒f▒<A▒Hz▒+P/▒▒sTU▒b▒?{▒/▒▒▒▒4u_▒▒?▒!0▒▒▒▒1▒▒▒▒#1 ▒▒▒s ▒↓
Y▒;♥♥▒▒3G▒H ▒▒&v▒▒:♦▒{▒▒*▒?7▒▒=▒"▒♥▒▒▒▒▒♥▒▒▒<▒:n?♥<i▒▒► ▒v/▒▒↓▒/♣c▒.▒)#Ou/▒▒O▒▒?▒▒▒%▒A,4+▒x▒▒▒#▒*gfσ▒7▒♣▒▒EtV▒3▒▒▒▒▒r♦▒kQ▒a♦↓▒▒|/:Iy▒{▒◄x8y▒▒▒h▒M▒▒▒G|▒▒"#⌂▒▒gK-▒▒▒'▒▒(▒▒FfN▒▒▒▒▒↑▒▒~4▒⌂▒T?r▒▒▒▒▒▒!▒?▒?▒▒▒▒~CaO▒
ho▒▒L▒H▒9▒▒▒Lh▒▒▒iY▒$4▒d▒▒.C▒▒►#!↓↑▒▒▒▒RQ▒;c▒▒▒?#3▒g▒▒▒▒?G▒y▒▒?Fb▒B=▒▒W|▒%Zc▒▒Q▒UY?♣▒c▒▒$v▒▒▒?▒8▒4v▒h▒▒▒I↑▒`▒Kb▒,▒▒Y▒▒#▒+▒▒▒▒=▒▒▒▒▒▒▒▒
e▒*▒e⌂▒▒"▒P▒!↑▒}▒n♦▒IW ▒▒▒
▒⌂▒)♠K▒?ln▒D♠:z▒:♥▒xA>▒▒LGX↑▒O▒▒W9Z▒▒p▒8▒xG$?▒▒;▒,▒M▒▒▒▒`▒kH▒▒▒kd9▒4t6▒xQH%o▒▒▒▒▒▒O▒▒▒#▒▒▒x▒3▒▒0◄~▒♦▒▒*#W▒▒▒_▒▒_y▒▒▒04▒▒▒▒P-R2K▒▒▒(?B▒e9▒g▒8M37A4▒▒n▒▒#▒▒m▒I▒.▒=▒3▒c▒▒?▒▒s▒▒▒j▒4e▒▒*E▒Q1N▒▒▒▒▒▒▒qy▒▒▒▒▒▒▒▒▒▒▒▒aN?▒_▒▒▒▒▒28_~▒]e♦▒▒▒▒&g♥v3►p▒p▒`▒J▒/▒X⌂▒{▒▒▒-▒▒▒rI▒%Q▒⌂▒▒q▒▒▒▒?▒▒▒▒/hE▒▒▒?▒▒▒▒▒▒▒7▒6▒W▒j▒▒▒w▒▒O▒▒>▒▒▒▒?▒xy▒▒v▒▒▒⌂?4▒T▒a▒◄▒c▒▒▒O7▒⌂v⌂|▒▒rL▒*▒♠▒▒▒#▒▒▒▒~}▒▒
▒K▒H2▒▒▒^l▒RI▒c^$9S$▒=▒▒BI:▒6cj+▒▒▒#
>▒▒▒&f ▒▒▒$▒▒◄▒?▒r▒C▒Ze♥↓▒%▒▒&▒#6▒CE▒▒◄+G♣-▒▒]▒ ▒▒[c▒b\▒MBhu▒O▒▒2▒!+y▒▒▒▒lDt▒U▒▒e▒I5▒\▒▒=▒▒▒▒▒▒T▒T▒▒▒♦^▒▒v▒k▒?▒-▒▒*▒)▒9▒t?▒▒cq▒,$▒▒▒
▒▒+▒▒OM▒#▒▒▒=?▒,?d;k▒♥p▒▒sd▒w▒▒▒▒▒I▒▒p▒nk▒▒D▒▒J▒Gh▒AJ▒B
▒t▒?%D▒q▒yUfyb▒?▒▒▒o▒/q*▒▒▒%i▒▒▒▒▒?>▒v▒/▒>_-▒▒~▒▒▒▒cu▒▒▒▒▒/▒▒|▒~▒▒v3▒▒▒_▒v▒~y"▒▒?▒▒▒▒▒▒_?▒▒▒/Oj▒>▒▒▒▒~▒\▒▒▒▒▒▒▒#▒▒t▒▒2Z▒K▒8_▒▒▒J▒*▒▒▒▒^a▒▒▒4W-▒▒▒TAn error occured while capturing the trace. Output file was not written.
Any environment variable should be added for python?? if yes which variable has to be added?
Can anyone help me in resolving this issue?
Thanks & regards
The reason it's not working on Cygwin is because the stream coming from the device actually
has two carriage returns before every line feed. You can see this by putting in a call to 'print repr(out) after reading from adb.stdout.
You just need to update systrace.py as follows to work around this:
if sys.platform == 'cygwin':
out = out.replace('\r\r\n', '\n')
else:
out = out.replace('\r\n', '\n')
I posted a patch at https://android-review.googlesource.com/55170 to fix this.
I try to access to my folder in sdcard and install myapp.apk, i use this code:
Runtime.getRuntime().exec("cd sdcard/.yasmin");
Runtime.getRuntime().exec("adb install tefli.apk");
But unfortunatelly i have this error:
05-11 11:09:57.925: WARN/System.err(1399): java.io.IOException:
Error running exec(). Commands: [cd, sdcard/.yasmin] Working Directory: null Environment: null
Anybody please have an idea.
thanks in advance.
I am not sure that this will fix your problem, but AFAIK, each call to exec() creates a new shell. A possible solution is to do the following:
Get the process of the exec() using: Process p = Runtime.getRuntime().exec(...).
Grab the process inputStream using p.getInputStream();.
Run the second command.
also note that you are trying to access the sdcard as you were in root folder and in a hardcoded path, consider the following:
Process p = Runtime.getRuntime().exec("cd /sdcard/.yasmin");
Or even better:
Process p = Runtime.getRuntime().exec("cd " + Environment.getExternalStorageDirectory() + "/.yasmin");
Hope it'll help!
you should use
Runtime.getRuntime().exec("sh -c cd /sdcard/.yasmin");
You can get the file generated with log as follows:
command - "your command"
Environment - null
Directory - null
Runtime.getRuntime().exec("your command",null,null);
Get the process of the exec() using: Process p = Runtime.getRuntime().exec(...).
Grab the process inputStream using p.getInputStream();.
Run the second command.
I would have posted it as a comment to MByD's answer but I don't have 50 reputation yet so StackOverflow won't let me.
For the second step you are supposed to use DataOutputStream instead of DataInputStream to write commands to the shell. InsputDataStream is for the opposite purpose in fact that is to read output.
If it sounds confusing then think of it this way:
You are outputting the commands through the Android Debug Bridge (ADB) to the shell hence using DataOutputStream. On the other hand you are getting result through the ADB from the shell hence using DataInputStream.