I'm wondering what is the meaning of next records in /proc/<pid>/maps:
...
cdbc2000-cdbc6000 rw-p 00000000 00:04 1290888 /dev/ashmem/dalvik-large object space allocation (deleted)
cdbc6000-cdbcf000 rw-p 00000000 00:04 1290887 /dev/ashmem/dalvik-large object space allocation (deleted)
cdbcf000-cdbdf000 rw-p 00000000 00:04 1290886 /dev/ashmem/dalvik-large object space allocation (deleted)
...
Especially what does (deleted) mean? Is this memory range is held by something within process and should be released later or these records are just markers and there is no associated physical memory ? I.e. may plain call to mmap() return mapping that intersects such ranges?
P.S. range names may differ slightly but they always contain /dev/ashmem ... (deleted).
Related
This question already has an answer here:
Adb shell getevent method returns twice the value for X and Y on Nexus 4
(1 answer)
Closed 2 years ago.
Taken from the source file itself:
#define ABS_MT_POSITION_X 0x35 /* Center X ellipse position */
#define ABS_MT_POSITION_Y 0x36 /* Center Y ellipse position */
So when I get an output:
/dev/input/event2: 0003 0039 00000cc7
/dev/input/event2: 0001 014a 00000001
/dev/input/event2: 0001 0145 00000001
/dev/input/event2: 0003 0035 00000a2d //<---- X coordinate
/dev/input/event2: 0003 0036 00000e6c //<---- Y coordinate
/dev/input/event2: 0003 0030 00000008
/dev/input/event2: 0003 0031 00000008
/dev/input/event2: 0003 003e 0001017e
/dev/input/event2: 0000 0000 00000000
/dev/input/event2: 0003 003e 00000000
/dev/input/event2: 0003 0039 ffffffff
/dev/input/event2: 0001 014a 00000000
/dev/input/event2: 0001 0145 00000000
/dev/input/event2: 0000 0000 00000000
a2d to decimal is 2605 and e6c is 3692. The position, actually was (670,2141) on the screen. How can I convert the getevent coordinates to actual usable coordinates.
Plus, what exactly does "Center X ellipse position" and "Center Y ellipse position" mean?
Any help is appreciated.
EDIT: I touched the right bottom of the screen and the getevent output was:
/dev/input/event2: EV_ABS ABS_MT_TRACKING_ID 00000d4f
/dev/input/event2: EV_KEY BTN_TOUCH DOWN
/dev/input/event2: EV_KEY BTN_TOOL_FINGER DOWN
/dev/input/event2: EV_ABS ABS_MT_POSITION_X 00000f86 #<---X coordinate
/dev/input/event2: EV_ABS ABS_MT_POSITION_Y 00000f9d //<---Y coordinate
/dev/input/event2: EV_ABS 003e 0001017e
/dev/input/event2: EV_SYN SYN_REPORT 00000000
/dev/input/event2: EV_ABS 003e 00000000
/dev/input/event2: EV_ABS ABS_MT_TRACKING_ID ffffffff
/dev/input/event2: EV_KEY BTN_TOUCH UP
/dev/input/event2: EV_KEY BTN_TOOL_FINGER UP
/dev/input/event2: EV_SYN SYN_REPORT 00000000
Here, f86 = 3974and f9d = 3997. And the actual size of the screen is around (1057,2366) (approximately).
So I thought maybe it just uses proportions, instead of actual values. So basically if we do (co-ordinate given by getevent/ max coordinate size for getevent) * (Actual coordinate size), we might get the correct value.
And I did exactly that, and got correct values. (2905/3974)*1057 = 692 and (3692/3997)*2366 = 2185, both of which are close to the actual values.
So now the question becomes, is the canvas size always equal to (4000,4000)?
In order to use the X,Y coordinates provided by getevent into input tap x y, we need to do the following things:
Find out max X,Y for getevent by getevent -il /dev/input/event2 | grep ABS_MT_POSITION. That gave be (4000,4000)
Find out the actual screen size by adb shell wm size this gave me (1080,2400)
Now convert getevent (x,y) into (x*1080/4000,y*2400/4000) to get the actual results, which can be used with input tap x y.
I am running a relatively simple program that calls mmap() repeatedly to obtain 100MB+ memory (and touch every single page of them). The problem is that this program always triggers the OOM killer in the kernel (based on 3.4) even though there are still plenty of physical pages (2G RAM in total and 1.6G+ is free).
I do see that these two lines of output seem to indicate that there are not many small free blocks left in HighMem (but many big ones are available still):
Normal: 1220*4kB 1034*8kB 791*16kB 547*32kB 289*64kB 130*128kB 39*256kB 9*512kB 5*1024kB 3*2048kB 149*4096kB = 714608kB
HighMem: 1*4kB 0*8kB 1*16kB 0*32kB 1*64kB 1*128kB 1*256kB 1*512kB 1*1024kB 2*2048kB 254*4096kB = 1046484kB
But I just can't wrap my head around this when the system also says that there are 524288 pages of RAM and 440840 free pages (most are free).
Below is the detailed output. Any help is appreciated!
test_program invoked oom-killer: gfp_mask=0x0, order=0, oom_adj=-17, oom_score_adj=-1000
[<c0011074>] (unwind_backtrace+0x0/0xe0) from [<c00813f0>] (dump_header.isra.16+0x74/0x18c)
[<c00813f0>] (dump_header.isra.16+0x74/0x18c) from [<c0081674>] (oom_kill_process.part.19.constprop.20+0x44/0x268)
[<c0081674>] (oom_kill_process.part.19.constprop.20+0x44/0x268) from [<c0081d64>] (out_of_memory+0x328/0x3f4)
[<c0081d64>] (out_of_memory+0x328/0x3f4) from [<c0081ef0>] (pagefault_out_of_memory+0xc0/0x154)
[<c0081ef0>] (pagefault_out_of_memory+0xc0/0x154) from [<c00120e0>] (do_page_fault+0x1bc/0x244)
[<c00120e0>] (do_page_fault+0x1bc/0x244) from [<c0008364>] (do_DataAbort+0x34/0x98)
[<c0008364>] (do_DataAbort+0x34/0x98) from [<c000d3f4>] (__dabt_usr+0x34/0x40)
Exception stack(0xed479fb0 to 0xed479ff8)
9fa0: aee1cffc aeec2000 0db4da5f aee1d000
9fc0: 00000000 0001b184 00000040 00000059 00000000 00000000 00000000 be9ccacc
9fe0: 00000064 be9cc9f0 0000b037 0000830c 80000030 ffffffff
Mem-info:
Normal per-cpu:
CPU 0: hi: 186, btch: 31 usd: 157
HighMem per-cpu:
CPU 0: hi: 186, btch: 31 usd: 39
active_anon:37727 inactive_anon:936 isolated_anon:0
active_file:4108 inactive_file:25830 isolated_file:0
unevictable:1 dirty:12 writeback:0 unstable:0
free:440273 slab_reclaimable:1457 slab_unreclaimable:2172
mapped:12414 shmem:944 pagetables:752 bounce:0
Normal free:714608kB min:3512kB low:5052kB high:5932kB active_anon:0kB inactive_anon:0kB active_file:788kB inactive_file:1632kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:772160kB mlocked:0kB dirty:48kB writeback:0kB mapped:0kB shmem:0kB slab_reclaimable:5828kB slab_unreclaimable:8688kB kernel_stack:2032kB pagetables:3008kB unstable:0kB bounce:0kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? no
lowmem_reserve[]: 0 10223 10223
HighMem free:1046484kB min:512kB low:3128kB high:4616kB active_anon:150908kB inactive_anon:3744kB active_file:15644kB inactive_file:101688kB unevictable:4kB isolated(anon):0kB isolated(file):0kB present:1308608kB mlocked:4kB dirty:0kB writeback:0kB mapped:49656kB shmem:3776kB slab_reclaimable:0kB slab_unreclaimable:0kB kernel_stack:0kB pagetables:0kB unstable:0kB bounce:0kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? no
lowmem_reserve[]: 0 0 0
Normal: 1220*4kB 1034*8kB 791*16kB 547*32kB 289*64kB 130*128kB 39*256kB 9*512kB 5*1024kB 3*2048kB 149*4096kB = 714608kB
HighMem: 1*4kB 0*8kB 1*16kB 0*32kB 1*64kB 1*128kB 1*256kB 1*512kB 1*1024kB 2*2048kB 254*4096kB = 1046484kB
30879 total pagecache pages
0 pages in swap cache
Swap cache stats: add 0, delete 0, find 0/1
Free swap = 0kB
Total swap = 0kB
524288 pages of RAM
440840 free pages
9650 reserved pages
3629 slab pages
59279 pages shared
0 pages swap cached
I am working on enabling secure playback on Lollipop. I am using ExoPlayer to validate the usecase. I am able to create a secure OMX video decoder component(H264.secure).
However, after the creation, I am facing a crash in MediaCodec as shown below
signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0xf0300000
eax f0300000 ebx ec1da038 ecx 00000005 edx 00000002
esi ec3ca200 edi f325b148
xcs 00000023 xds 0000002b xes 0000002b xfs 000000bf xss 0000002b
eip ec0e1655 ebp e05ffb28 esp e05ffa90 flags 00210202
#00 pc 000b5655 /system/lib/libstagefright.so (android::MediaCodec::onQueueInputBuffer(android::sp<android::AMessage> const&)+1061)
#01 pc 000b7b16 /system/lib/libstagefright.so (android::MediaCodec::onMessageReceived(android::sp<android::AMessage> const&)+1894)
#02 pc 0000e039 /system/lib/libstagefright_foundation.so (android::ALooperRoster::deliverMessage(android::sp<android::AMessage> const&)+345)
#03 pc 0000d3d0 /system/lib/libstagefright_foundation.so (android::ALooper::loop()+256)
#04 pc 0000d4ed /system/lib/libstagefright_foundation.so (android::ALooper::LooperThread::threadLoop()+29)
#05 pc 000169de /system/lib/libutils.so (android::Thread::_threadLoop(void*)+398)
#06 pc 0006fe92 /system/lib/libandroid_runtime.so (android::AndroidRuntime::javaThreadShell(void*)+98)
#07 pc 000160fa /system/lib/libutils.so (thread_data_t::trampoline(thread_data_t const*)+122)
After some analysis i found that the crash occurs at function ACodec::allocateBuffersOnPort
I am a newbie on android. Any pointers to debug this would be helpful
To summarize, the issue is specific to a case when kFlagIsSecure is set and the creation of OMX buffer in a different process as compared to MediaCodec, which leads to a segmentation fault when accessed in MediaCodec. Please refer below for the detailed background about this issue.
To overcome this issue, I would recommend the following changes in ACodec
size_t totalSize = def.nBufferCountActual * def.nBufferSize;
mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
/* Check if the component resides in same pid as ACodec */
bool isLocalComponent = mOMX->livesLocally(mNode, getpid()); // New Code
for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
...
...
and modify the check for allocation as below
-- if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
-- || mUseMetadataOnEncoderOutput) {
// Modified check
++if (isLocalComponent && ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
++ || mUseMetadataOnEncoderOutput)) {
P.S: I would recommend you to check with Google about this solution.
Background:
ExoPlayer creates a video decoder as a MediaCodec component. When a new MediaCodec component is created, the corresponding object in JNI is created. Please note that there is no interaction with MediaPlayerService in this process.
MediaCodec internally creates an ACodec which interacts with the OMX core and subsequently OMX component.
ACodec is created in the same context as MediaCodec. When OMXClient::connect is invoked, the OMX handle is created in the MediaPlayer service's context. Hence, the process id of OMX component and ACodec would be different.
For secure input buffers, there is a special handling in ACodec::allocateBuffersOnPorts. Here, the buffer pointer returned from allocateBuffer is wrapped as ABuffer and queued for consumption. In my view, there is a potential issue in the current implementation as below.
ACodec::allocateBufferOnPort calls mOMX->allocateBuffer. mOMX is of type IOMX i.e. there is a binder interaction involved. Please do note this variable &buffer_data which will translate to ptr in ACodec::allocateBufferOnPorts layer as this is critical for the following part.
In OMXNodeInstance which actually runs in MediaPlayerService's context, a traditional OMX_AllocateBuffer is called. In OMXNodeInstance::allocateBuffer, after the allocation *buffer_data is initialized with header->pBuffer which is basically a local pointer allocated by the OMX component potentially through a simple malloc call.
When the control returns, the same pointer is written into the binder interface here and subsequently read back here. So, when the control comes out mOMX->allocateBuffer, the value of ptr is equivalent to header->pBuffer allocated by OMX component, but both of which are in 2 different processes.
Hence, when ACodec creates the ABuffer based on this ptr which is then accessed in MediaCodec, there will be an access violation as the address was created in a different process' context as compared to MediaCodec's process id.
I use showmap command on a PID, and I can't understand this part in the report:
16384 3752 689 0 3132 0 620 4 /dev/ashmem/dalvik-LinearAlloc (deleted)
2460 1748 934 0 828 0 920 18 /dev/ashmem/dalvik-aux-structure (deleted)
8192 572 572 0 0 0 572 1 /dev/ashmem/dalvik-bitmap-1 (deleted)
8192 0 0 0 0 0 0 1 /dev/ashmem/dalvik-bitmap-2 (deleted)
4100 312 312 0 0 0 312 1 /dev/ashmem/dalvik-card-table (deleted)
502140 14860 14860 0 0 0 14860 3 /dev/ashmem/dalvik-heap (deleted)
1500 280 280 0 0 0 280 1 /dev/ashmem/dalvik-jit-code-cache (deleted)
174764 0 0 0 0 0 0 1 /dev/ashmem/dalvik-mark-stack (deleted)
22148 22148 2141 0 20452 0 1696 1 /dev/ashmem/dalvik-zygote (deleted)
I want to know what data is in the dalvik-LinearAlloc, dalvik-aux-structure, dalvik-bitmap-1, dalvik-bitmap-2, dalvik-card-table, dalvik-mark-stack and dalvik-zygote.
These ashmem cost millions bytes memory, and I want to find a measure to shrink the size of these ashmem.
showmap is dumpping the smap data from one process. The smap is describing the process's memory area's detail. In virtual memory manage system, the memory can be gained by the system API such as mmap, brk. After gaining virtual memory address by these APIs, the address and length will be recorded in the smap.
And let's list each section of the dalvik relative memory usage:
Dalvik Heap section(Heap Management, GC)
dalvik-bitmap-1, dalvik-bitmap-2 is the Dalvik Heap management data stucture. In Dalvik, the GC is marksweep, and 8 bytes memory will be marked(Used or free) as one bit in the bitmap. These two bitmaps will be used as active map(used for marking # runtime) and the other will be used as marked map(used # GC time).
dalvik-mark-stack: For GC mark step use. The mark step will iterate the bitmap, so this is a Breadth-first search which will need a stack.
dalvik-card-table: is used for Dalvik Concurrent GC, in bitmap marking steps, the process will do other tasks which will lead using memory. These card tables is recording the memory dirty after first marking step. You can see the detail by searching mark sweep GC.
dalvik-heap is used for process memory usage
dalvik-zygote is one part of the hole heap, which will not be used # GC. All processes will share these memories such as framework resources.
dalvik-jit is The jit memory used in Dalvik. JIT: just in time, which will convert dex bytecode to machine code which can be executed by CPU.
dalvik-LinearAlloc: is the dalvik's perm memory such as: Method, Class definition datas, thread stack datas. These memory can be setted READONLY after parsing the class definition.
dalvik-aux-structure: auxillary data structures, which will compress the method/class/string const reference. These references will be used # each dex file, but sum of these memory will cost a large memory. So Dalvik create a tmp memory to shared these references.
If you want to analysis your program's memory, I suggest you to use MAT in eclipse. And the native heap usage, you can use mmap to manage.
I have a ASUS Nexus 7 running Android 4.2.2 My application is generatng a SIGSEGV in sk_malloc_flags when running the following code:
static Picture createDrawing() {
Path firstPath = new Path();
firstPath.moveTo(3058, 12365);
firstPath.lineTo(8499, 3038);
firstPath.lineTo(9494, 3619);
firstPath.lineTo(4053, 12946);
firstPath.close();
Path fourthPath = new Path();
fourthPath.moveTo(3065, 12332);
fourthPath.lineTo(4053, 12926);
fourthPath.lineTo(9615, 3669);
fourthPath.lineTo(8628, 3075);
fourthPath.close();
Picture picture = new Picture();
Canvas canvas = picture.beginRecording(12240, 15840);
canvas.clipPath(firstPath);
canvas.clipPath(fourthPath); << SIGSEGV occurs here
picture.endRecording();
return picture;
}
The SIGSEGV is reported as follows:
I/DEBUG ( 124): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr deadbaad
I/DEBUG ( 124): r0 00000027 r1 deadbaad r2 4017f258 r3 00000000
I/DEBUG ( 124): r4 00000000 r5 bed72434 r6 bed72508 r7 1be773bc
I/DEBUG ( 124): r8 1be730f9 r9 000042c3 sl 00000001 fp 67185010
I/DEBUG ( 124): ip 40443f3c sp bed72430 lr 401522f9 pc 4014e992 cpsr 60000030
...
I/DEBUG ( 124): backtrace:
I/DEBUG ( 124): #00 pc 0001a992 /system/lib/libc.so
I/DEBUG ( 124): #01 pc 00018070 /system/lib/libc.so (abort+4)
I/DEBUG ( 124): #02 pc 000be4b4 /system/lib/libskia.so (sk_malloc_flags(unsigned int, unsigned int)+28)
I/DEBUG ( 124): #03 pc 0008afc0 /system/lib/libskia.so (SkRegion::op(SkRegion const&, SkRegion const&, SkRegion::Op)+1716)
I/DEBUG ( 124): #04 pc 00089448 /system/lib/libskia.so (SkRasterClip::op(SkRasterClip const&, SkRegion::Op)+128)
I have obviously simplified the code to that shown above, the full application uses transforms, etc based on some input data to generate the values. Are they any suggestions as to how to fix this without implementing my own code for clipping in the general case?
This looks like an ill fated corner case for clipPath handling.
canvas.clipPath(fourthPath);
causes a merge with previous firstPath however since these are complex (non-rectangular) shapes system tries to draw them as scanlines and merge it afterwards. To make this merge, it needs to allocate some memory but as you can see in SkRegion.cpp, it goes for heuristic worst case.
static int compute_worst_case_count(int a_count, int b_count) {
int a_intervals = count_to_intervals(a_count);
int b_intervals = count_to_intervals(b_count);
// Our heuristic worst case is ai * (bi + 1) + bi * (ai + 1)
int intervals = 2 * a_intervals * b_intervals + a_intervals + b_intervals;
// convert back to number of RunType values
return intervals_to_count(intervals);
}
For your paths this worst_case_count becomes close to 2GB and you get an abort due to not getting that big memory from malloc.
I couldn't see any way out of it using different parameters. Anything which avoids merging clipPaths must help, like calling clipPath with Region.Op.REPLACE. Region.Op.INTERSECT should fail too.
I would concentrate on avoiding calling clipPath with a complex path on top of a complex path.
If it suits your use case, you can use same Path object for setting canvas.clipPath(). For example:
Picture picture = new Picture();
Canvas canvas = picture.beginRecording(12240, 15840);
Path path = new Path();
path.moveTo(3058, 12365);
path.lineTo(8499, 3038);
path.lineTo(9494, 3619);
path.lineTo(4053, 12946);
path.close();
canvas.clipPath(path);
// do stuff with canvas
path.moveTo(3065, 12332);
path.lineTo(4053, 12926);
path.lineTo(9615, 3669);
path.lineTo(8628, 3075);
path.close();
canvas.clipPath(path, Region.Op.REPLACE);
// do more stuff with canvas
picture.endRecording();
return picture;
Since path contains previous drawings, you can just continue updating it. If this is not applicable to your case, you either need to make those numbers smaller or partition your complex regions into smaller ones to avoid worst case heuristic to become too big.
Ok, let me put this in an answer, since it looks quite logical to me:
To see if the problem is comming from the consequtive calls to clipPath(Path), try removing the call at first or putting canvas.clipPath(fourthPath, Region.Op.REPLACE); in the place of canvas.clipPath(fourthPath); and see if that's the cause.
Another thing I can think of, is if you draw them separately:
Picture picture = new Picture();
Canvas canvas = picture.beginRecording(12240, 15840);
canvas.clipPath(firstPath);
picture.endRecording();
canvas = picture.beginRecording(12240, 15840);
canvas.clipPath(fourthPath);
picture.endRecording();
It looks like Canvas.clipPath() is not supported with hardware acceleration, at least doc says that:
http://developer.android.com/guide/topics/graphics/hardware-accel.html#unsupported
The only workaround that comes to my mind is to turn off hardware acceleration.
You can do it on:
Application level
<application android:hardwareAccelerated="true" ...>
in manifest
Activity level
android:hardwareAccelerated="false"
for activity in manifest
View level
view.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
for an individual view at runtime
Docs:
http://developer.android.com/guide/topics/graphics/hardware-accel.html#controlling