Closed Bug 686728 Opened 13 years ago Closed 13 years ago

Investigate possible loss of ashmem regions used by library loader

Categories

(Core Graveyard :: Widget: Android, defect)

All
Android
defect
Not set
normal

Tracking

(Not tracked)

RESOLVED WORKSFORME

People

(Reporter: mwu, Assigned: glandium)

References

Details

Attachments

(1 file)

Ashmem regions are killable by the kernel under low memory conditions. We should investigate how common process deaths caused by losing libraries loaded in ashmem is, and possibly do something about it.
Unfortunately, from the point of view of the crash reporter, this would look like a crash on a random portion of the code. They wouldn't even cumulate in the crash stats since they likely would crash in completely different parts of the code.

The easy fix is to pin the ashmem zones we use for the linker until we have a mechanism to handle the situation.
Blocks: 686694
Presumably we could start by looking for crashes that are SIGSEGV where the faulting address == the faulting instruction pointer, and the top frame is inside one of our libraries, not a bare address. I'm not sure that Socorro's search is powerful enough for this, but we could probably do it in a map/reduce job if we need to.
Attached file ashmem.c
So, I did a bit of experimentation and the attached source exhibits ashmem behaviour (build with $NDK_DIR/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc -o ashmem ashmem.c, run as root in a shell on the device)

ASHMEM_PURGE_ALL_CACHES forces ashmem eviction by the kernel (if I read the ashmem patch correctly, it evicts all unpinned ashmem system-wide, not only that of the file descriptor it is used on). It requires CAP_SYS_ADMIN which is why you'd need to run the program as root.

Anyways, so the little program here allocates ashmem, purges once, at which point *nothing happens*, pin our ashmem, purge again, still nothing (obviously), unpin our ashmem, purge again, and ... data is nulled out.

So, four lessons here:
- unless we unpin ashmem, it's safe and won't be purged.
- purged ashmem is not segfaulting, it is as if it was newly allocated.
- if I read vmscan.c from the kernel correctly, it looks possible that only parts of the ashmem are purged when the kernel starts reclaiming memory, but ashmem doesn't partially purge ashmem ranges. So, it looks like if we unpin by chunks, we could end up with partially purged data, while if we unpin the complete ashmem, it will be purged in one go.
- if our libs were unpinned and purged, that would mean we would end up executing null instructions until we either reach unmapped memory or non-executable memory and segfault there, or reach mapped memory with some executable content and execute random stuff. The former is the most likely, since there is unreadable non-executable mapped memory after .text sections. So, we could detect such faults, but we wouldn't be able to tell actually where we were jumping in originally.
Assignee: nobody → mh+mozilla
Status: NEW → RESOLVED
Closed: 13 years ago
Resolution: --- → WORKSFORME
Product: Core → Core Graveyard
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: