If you run adb shell dumpsys <package_name>, the output contains a section like this:
App Summary
Pss(KB)
------
Java Heap: 65636
Native Heap: 22216
Code: 1444
Stack: 1444
Graphics: 79332
Private Other: 6140
System: 19569
TOTAL: 195781 TOTAL SWAP PSS: 85
What does the Graphics metric correspond to?
please refer to How do I discover memory usage of my application in Android?
the Debug.MemoryInfo class has full documentation for related fields above~
Related
I am analyzing a custom Android device. I tried to enumerate services running in the system (adb shell service list) and I found out that there is a service (let's call it MyService) that I would like to analyze more in depth. It might be a privileged (system) service, if that is a relevant information.
When I run adb shell service list | grep MyService, it returns something like aaa.bbb.ccc.ddd.MyService. I would like to get the code/binary/APK of this service. However, when I run adb shell pm path aaa.bbb.ccc.ddd.MyService, it returns error code 1 and doesn't print any path. The same situation occurs when I execute adb shell pm list packages | grep -i XXX, where XXX is any of aaa,bbb,ccc,ddd or MyService (for the record, aaa and bbb return some packages, but they do not have anything in common with the specific service).
My question is: How can I extract the code/binary/APK/... of the service? How do I find where it is installed?
If root access is needed, that shouldn't be a problem.
I'm new to this problem as well, and had some fun exploring the Android internals. Eventually, I was only able to find the process id that provides the service, and any information associated with that, through /proc and /sys VFS.
Here are my findings:
My first discovery was that, dumpsys <SERVICE_SHORT_NAME> can connect to any service, and ask it to dump its internal state. But this doesn't always include the package name or install directory for that service. I decided to trace system calls from this dumpsys program, using strace. But it turns out that IPC happens through a non-standard /dev/binder device that strace doesn't understand:
$ su
# strace -f -y dumpsys telephony_ims | grep binder | tail
openat(AT_FDCWD, "/dev/binder", O_RDWR|O_CLOEXEC) = 3</dev/binder>
ioctl(3</dev/binder>, BINDER_VERSION, 0x7fd88906b4) = 0
ioctl(3</dev/binder>, BINDER_SET_MAX_THREADS, 0x7fd88906a8) = 0
mmap(NULL, 1040384, PROT_READ, MAP_PRIVATE|MAP_NORESERVE, 3</dev/binder>, 0) = 0x7990b83000
ioctl(3</dev/binder>, BINDER_WRITE_READ, 0x7fd8890460) = 0
ioctl(3</dev/binder>, BINDER_WRITE_READ, 0x7fd8890110) = 0
[pid 15836] ioctl(3</dev/binder>, BINDER_WRITE_READ, 0x7990b7e8a0) = 0
[pid 15836] ioctl(3</dev/binder>, BINDER_WRITE_READ <unfinished ...>
[pid 15836] ioctl(3</dev/binder>, BINDER_THREAD_EXIT, 0) = 0
Luckily, there is still a method to trace what happens inside this binder device. With the help from this other Stack Overflow page, I was able to find the pid running any service.
I will examine the service telephony_ims as an example.
Please run the following commands as root.
First, we need to set up Android Binder Tracing, using commands from the other Stack Overflow page.
cd /sys/kernel/debug/tracing; echo > set_event; echo 1 > events/binder/enable; echo 1 > tracing_on
Then, we must run dumpsys, and immediately afterwards, read the trace logs.
Prerequisite: I used less command, which isn't available on all android devices. If your bash cannot find less, then you could dump the results to a file on SD Card, and open it using a text viewer.
Run (cat /proc/uptime; dumpsys telephony_ims >/dev/null & echo $!; cat /proc/uptime; cat /sys/kernel/debug/trace | tail -n 1000) | less
Look at the resulting output
The first three lines are
16682.46 92635.05
20823
16682.47 92635.12
Search for 20823 from the second line, which is the PID of dumpsys. (The first and third lines are start time timestamp, and end time timestamp, respectively)
Found out that dumpsys is talking with servicemanager:
dumpsys-20823 [006] .... 16682.479173: binder_transaction: transaction=10738057 dest_node=1 dest_proc=563 # more content afterwards, ignored. pid 563 is "servicemanager"
# ... more lines ...
servicemanager-563 [003] .... 16682.479283: binder_transaction: transaction=10738058 dest_node=0 dest_proc=20823 # more content afterwards, ignored.
Then, it turns out that dumpsys-20823 started a child process, 20827:
dumpsys-20823 [004] .... 16682.479808: binder_return: cmd=0x7206 BR_TRANSACTION_COMPLETE
dumpsys-20823 [004] .... 16682.479810: binder_transaction_received: transaction=10738061
dumpsys-20823 [004] .... 16682.479811: binder_return: cmd=0x80407203 BR_REPLY
dumpsys-20823 [004] .... 16682.479812: binder_read_done: ret=0
dumpsys-20823 [004] .... 16682.479813: binder_ioctl_done: ret=0
dumpsys-20827 [006] .... 16682.480058: binder_ioctl: cmd=0xc0306201 arg=0x780a5668a0
dumpsys-20827 [006] .... 16682.480060: binder_command: cmd=0x40406300 BC_TRANSACTION
dumpsys-20827 [006] .... 16682.480077: binder_transaction: transaction=10738063 dest_node=29113 dest_proc=2574 dest_thread=0 reply=0 flags=0x10 code=0x5f444d50
Eventually, it's this child process who gave away the PID of the service ("dest_proc=2574"):
dumpsys-20827 [006] .... 16682.480077: binder_transaction: transaction=10738063 dest_node=29113 dest_proc=2574 dest_thread=0 reply=0 flags=0x10 code=0x5f444d50
Look into this process for its package name / related jars and apks
$ ps -A | grep 2574
radio 2574 875 14414052 120280 SyS_epoll_wait 0 S com.android.phone
$ ls -l /proc/2574/fd | egrep 'apk|jar' | head
lr-x------ 1 root root 64 2020-12-15 13:42 10 -> /apex/com.android.art/javalib/bouncycastle.jar
lr-x------ 1 root root 64 2020-12-15 13:42 102 -> /system/app/Stk/Stk.apk
lr-x------ 1 root root 64 2020-12-15 13:42 11 -> /apex/com.android.art/javalib/apache-xml.jar
lr-x------ 1 root root 64 2020-12-15 13:42 12 -> /system/framework/framework.jar
lr-x------ 1 root root 64 2020-12-15 13:42 13 -> /system/framework/ext.jar
lr-x------ 1 root root 64 2020-12-15 13:42 14 -> /system/framework/telephony-common.jar
lr-x------ 1 root root 64 2020-12-15 13:42 15 -> /system/framework/voip-common.jar
lr-x------ 1 root root 64 2020-12-15 13:42 16 -> /system/framework/ims-common.jar
lr-x------ 1 root root 64 2020-12-15 13:42 18 -> /system/framework/framework-atb-backward-compatibility.jar
lr-x------ 1 root root 64 2020-12-15 13:42 19 -> /apex/com.android.conscrypt/javalib/conscrypt.jar
Need to build android source build with full CPU utilisation.
For that, how to calculate N in " make -jN " ?
Sample CPUinfo:
Your Linux distro should come with the command nprocs, or at least nprocs should be easily installable. If you don't want to require nprocs, this shell command will give you the number of cores in the box (including hyper-threaded ones): ls -d /sys/devices/system/cpu/cpu[0-9]*|wc -l
cores=$(grep -c ^processor /proc/cpuinfo)
make -j${cores}
I send adb shell dumpsys wifi to get current available wifi ap BSSID(MAC address).The result as follows:
Latest scan results:
BSSID Frequency RSSI Age SSID Flags
7c:7d:3d:c3:4c:e0 2422 -40 6.716 HUAWEI-YJDAD5 [WPA2-PSK-CCMP][ESS]
d4:ee:07:26:24:18 2432 -50 6.716 HiWiFi_Refine [WPA-PSK-CCMP][WPA2-PSK-CCMP][ESS]
24:09:95:55:54:20 2442 -52 6.716 HUAWEI-5420 [WPA2-PSK-CCMP][WPS][ESS]
70:72:3c:97:52:b8 2437 -53 6.716 HUAWEI-H6FCXT [WPA-PSK-CCMP+TKIP][WPA2-PSK-CCMP+TKIP][WPS][ESS]
0c:d6:bd:3d:f6:14 2417 -52 6.716 HUAWEI-DUS8FG [WPA-PSK-CCMP+TKIP][WPA2-PSK-CCMP+TKIP][WPS][ESS]
f0:b4:29:20:21:1b 2442 -54 6.716 Xiaomi_211A11 [WPA-PSK-CCMP+TKIP][WPA2-PSK-CCMP+TKIP][WPS][ESS]
80:38:bc:05:ed:a1 2412 -58 6.716 Huawei-Employee [WPA2-EAP-CCMP][ESS]
e0:19:1d:cc:7c:a4 2412 -57 6.715 HUAWEI-B83GL6 [WPA-PSK-CCMP][WPA2-PSK-CCMP][WPS][ESS]
18:c5:8a:17:4b:a1 2412 -60 6.715 Huawei-Employee [WPA2-EAP-CCMP][ESS]
So how to use findstr Regular Expression on Windows to collect BSSID from the result? I tried adb shell dumpsys wifi | findstr /r "[0-9a-f]{2}(:[0-9a-f]{2}){5}" but get nothing
Regular expression support by findstr is limited and does not support all features of regular expression implementation in Perl interpreter, or the regular expression class in Boost library, or what JavaScript RegExp object supports. They all support regular expressions in Perl syntax, but their implementations and features are different. Run in a command prompt window findstr /? to get displayed help of this console application and which regular expressions are supported by findstr.
But findstr is designed to output the line containing the found string and not just the found string. It would not make much sense for a non regular expression search in a file to output just the found string as it would be equal the search string, perhaps with the exception of case in case of using option /I and a search string containing letters.
Therefore I suggest to use command FOR to get just the MAC address written into a text file.
#echo off
rem Delete a perhaps already existing output file.
if exist MacAddress.txt del MacAddress.txt
rem Run command to get WiFi data, skip the first line of output, and
rem write to output file just the first data column with the MAC addresses.
for /F "skip=1" %%I in ('adb.exe shell dumpsys wifi') do echo %%I>>MacAddress.txt
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
del /?
echo /?
for /?
if /?
See also Microsoft article Using command redirection operators for an explanation of >>.
On Android, running valgrind 3.9.0 with --vgdb=yes creates a FIFO pipe that should listen to vgdb commands (along with another pipe for the reverse direction and a piece of shared memory). However, a command such as vgdb instrumentation on just hangs forever.
This is tested on an armv7 emulator with Android 4.0.3 (which is reported to work on README.android) and on a Galaxy Note II with Android 4.3.1 based Cyanogenmod
valgrind is built with export HWKIND=generic and --with-tmpdir=/data/local/Inst; all other options are according to the README.android file
Both devices were rooted and were running insecure adbd's
Two valgrind builds were tested, one built with ndk-r6 and one with ndk-r9d. The result is the same on all configurations
Both devices are able to run valgrind but neither runs listen to vgdb
For reference, the valgrind command and its output are as follows:
# ./valgrind -v -v -v --vgdb=yes sleep 1000
==3640== Memcheck, a memory error detector
==3640== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==3640== Using Valgrind-3.9.0 and LibVEX; rerun with -h for copyright info
==3640== Command: sleep 1000
==3640==
--3640-- Valgrind options:
--3640-- -v
--3640-- -v
--3640-- -v
--3640-- --vgdb=yes
--3640-- Contents of /proc/version:
--3640-- Linux version 2.6.29-g46b05b2 (vchtchetkine#vc-irv.irv.corp.google.com) (gcc version 4.4.3 (GCC) ) #28 Thu Nov 17 06:39:36 PST 2011
--3640-- Arch and hwcaps: ARM, ARMv7-vfp-neon
--3640-- Page sizes: currently 4096, max supported 4096
--3640-- Valgrind library directory: /data/local/Inst/lib/valgrind
--3640-- TT/TC: VG_(init_tt_tc) (startup of code management)
--3640-- TT/TC: cache: 6 sectors of 27597024 bytes each = 165582144 total
--3640-- TT/TC: table: 6 tables of 11531696 bytes each = 69190176 total
--3640-- TT/TC: table: 65521 entries each = 393126 total entries max occupancy 255528 (65%)
--3640-- Reading syms from /system/xbin/busybox
--3640-- svma 0x0000008120, avma 0x0000008120
--3640-- object doesn't have a symbol table
--3640-- object doesn't have a dynamic symbol table
--3640-- Reading syms from /data/local/Inst/lib/valgrind/memcheck-arm-linux
--3640-- svma 0x0038000000, avma 0x0038000000
--3640-- object doesn't have a dynamic symbol table
--3640-- Scheduler: using generic scheduler lock implementation.
--3640-- Reading suppressions file: /data/local/Inst/lib/valgrind/default.supp
==3640== embedded gdbserver: reading from /data/local/Inst/vgdb-pipe-from-vgdb-to-3640-by-???-on-???
==3640== embedded gdbserver: writing to /data/local/Inst/vgdb-pipe-to-vgdb-from-3640-by-???-on-???
==3640== embedded gdbserver: shared mem /data/local/Inst/vgdb-pipe-shared-mem-vgdb-3640-by-???-on-???
==3640==
==3640== TO CONTROL THIS PROCESS USING vgdb (which you probably
==3640== don't want to do, unless you know exactly what you're doing,
==3640== or are doing some strange experiment):
==3640== /data/local/Inst/lib/valgrind/../../bin/vgdb --pid=3640 ...command...
==3640==
==3640== TO DEBUG THIS PROCESS USING GDB: start GDB like this
==3640== /path/to/gdb sleep
==3640== and then give GDB the following command
==3640== target remote | /data/local/Inst/lib/valgrind/../../bin/vgdb --pid=3640
==3640== --pid is optional if only one valgrind process is running
==3640==
--3640-- TT/TC: initialise sector 0
The vgdb command is (there is no output until it's killed):
# ./vgdb instrumentation on
^Csyscall failed: Interrupted system call
error opening /data/local/Inst/vgdb-pipe-to-vgdb-from-3640-by-???-on-??? read cmd result from pid
Some notes:
On the real device, the HOSTNAME and USER are not ??? but actually are t0lte and root properly. It probably has nothing to do with this issue.
I'm sure that FIFO piping works in the aforementioned /data/local/Inst directory because the following works:
In a root shell inside /data/local/Inst:
# mkfifo examplepipe
# echo message > examplepipe
... command exits after the pipe is read in another shell ...
#
In another shell:
# cat examplepipe
message
I'm also sure that vgdb is finding the valgrind instance because it doesn't report FIFO not found error.
I'm guessing at this point that the reason vgdb hangs is that valgrind does not listen to the pipe for some reason.
valgrind operation by itself runs as expected. Callgrind outputs are produced etc. But since vgdb doesn't work, instrumentation starting/stopping and therefore on-demand profiling is not possible.
What may be the issue?
This is a known limitation of vgdb on android.
The vgdb-invoker-ptrace.c should be ported on android.
See https://bugs.kde.org/show_bug.cgi?id=338977
for more details
I have followed swap to zram section in this link: https://source.android.com/devices/low-ram.html.
Given in the link:
zRAM swap can increase the amount of memory available in the system by compressing memory pages and putting them in a dynamically allocated swap area of memory.
Again, since this is trading off CPU time for a small increase in memory, you should be careful about measuring the performance impact zRAM swap has on your system.
Android handles swap to zRAM at several levels:
First, the following kernel options must be enabled to use zRAM swap effectively:
CONFIG_SWAP
CONFIG_CGROUP_MEM_RES_CTLR
CONFIG_CGROUP_MEM_RES_CTLR_SWAP
CONFIG_ZRAM
Then, you should add a line that looks like this to your fstab:
/dev/block/zram0 none swap defaults zramsize=<size in bytes>,swapprio=<swap partition priority>
zramsize is mandatory and indicates how much uncompressed memory you want the zram area to hold. Compression ratios in the 30-50% range are usually observed.
swapprio is optional and not needed if you don't have more than one swap area.
By default, the Linux kernel swaps in 8 pages of memory at a time. When using ZRAM, the incremental cost of reading 1 page at a time is negligible and may help in case the device is under extreme memory pressure. To read only 1 page at a time, add the following to your init.rc:
`write /proc/sys/vm/page-cluster 0`
In your init.rc, after the `mount_all /fstab.X` line, add:
`swapon_all /fstab.X`
The memory cgroups are automatically configured at boot time if the feature is enabled in kernel.
If memory cgroups are available, the ActivityManager will mark lower priority threads as being more swappable than other threads. If memory is needed, the Android kernel will start migrating memory pages to zRAM swap, giving a higher priority to those memory pages that have been marked by ActivityManager.
As per the steps given below: zramfs is getting created with node /dev/zram0.
I wanted to test the performance by doing read/write.(I have allotted zram size as 50MB)
For testing I came across the link:https://code.google.com/p/compcache/wiki/zramperf
Read test given in the link:
Read benchmark
1G file was copied to (z)ramdisk which was then synchronously read into /dev/null using different block sizes.
if [ -z "$1" ]; then
echo "Missing file to read into /dev/null"
exit 1
else
FI="$1"
fi
if [ -z "$2" ]; then
echo "Missing file to dump output"
exit 1
else
FO="$2"
fi
for B in 64 128 256 512 1K 2K 4K 8K 16K 32K 64K 128K 256K 512K 1M; do
echo "$B" | tee -a "$FO"
echo 1 > /proc/sys/vm/drop_caches
echo 1 > /proc/sys/vm/drop_caches
sleep 1
dd if="$FI" of=/dev/null bs="$B" iflag=sync 2>&1 | tee -a "$FO"
done
Write test:
Write benchmark
First make sure that test (512M) file was completely cached. Then synchronously write this file to (z)ramdisk.
if [ -z "$1" ]; then
echo "Missing file to be written"
exit 1
else
FI="$1"
fi
# make sure input file is cached
dd if="$FI" of=/dev/null
dd if="$FI" of=/dev/null
dd if="$FI" of=/dev/null
dd if="$FI" of=/dev/null
for B in 64 128 256 512 1K 2K 4K 8K 16K 32K 64K 128K 256K 512K 1M; do
echo "$B" | tee -a "$FO"
dd if="$FI" of=`basename "$FI"` bs="$B" oflag=sync 2>&1 | tee -a "$FO"
done
I am not comfortable with shell. Further someone please tell what should i give arg option for 1 and 2 in read benchmark and arg option 1 in write benchmark.
Please help me run performance test on this.
thanks.