| Vladimir Chtchetkine | 5389aa1 | 2010-02-16 10:38:35 -0800 | [diff] [blame] | 1 | ANDROID MEMORY CHECKER COMPONENT |
| 2 | |
| 3 | The docs/ANDROID-MEMCHECK.TXT document contains description of a memory checker |
| 4 | implemented in the emulator |
| 5 | |
| 6 | The memory checker is intended to catch simple memory access violations in the |
| 7 | emulated system, including: |
| 8 | - Memory leaks |
| 9 | - Attempts to free / reallocate invalid pointers (including pointers that have |
| 10 | already been freed, or reallocated). |
| 11 | - Attempts to read from / write to areas outside of allocated blocks. |
| 12 | |
| 13 | To provide this functionality, the memory checker works in conjunction with |
| 14 | an instrumented version of libc.so library used by the emulated system. Both, |
| 15 | emulator's memory checking, and libc's instrumentation are turned on by the |
| 16 | -memcheck command-line option. If this argument is omitted, libc.so will run in |
| 17 | the regular, not instrumented mode, and the emulator will not perform any |
| 18 | actions related to the memory checking. |
| 19 | |
| 20 | The way emulator and instrumented libc.so work together is as such: |
| 21 | libc.so hooks up every memory allocation call (malloc, free, calloc, realloc, |
| 22 | and memalign). For each such call, libc sends a notification message to the |
| 23 | emulator, providing an allocation descriptor that contains information about |
| 24 | allocation block and operation that is being performed on this block. Emulator |
| 25 | and libc use a "magic page" that is set up in such a way that every write to |
| 26 | that page on the emulated system produces some sort of event in the emulator, |
| 27 | allowing emulator to receive data that emulated system has written to the "magic |
| David 'Digit' Turner | 6ba28da | 2014-01-10 12:21:19 +0100 | [diff] [blame^] | 28 | page". For more info on that, see hw/android/goldfish/trace.c |
| Vladimir Chtchetkine | 5389aa1 | 2010-02-16 10:38:35 -0800 | [diff] [blame] | 29 | |
| 30 | In response to events, received from libc.so, emulator keep tracks of all blocks |
| 31 | that have been allocated from the heap on emulated system. Block descriptors are |
| 32 | kept in a per-process basis, so when a process exits, emulator can list all the |
| 33 | leaked blocks the process left behind. |
| 34 | |
| 35 | When a free, or realloc operation is performed on the emulated system, emulator |
| 36 | can verify that the pointer passed to free/realloc matches the address of a |
| 37 | block recorded in the current process' descriptors table. This way emulator can |
| 38 | detect and report attempts to free/reallocate invalid pointers. |
| 39 | |
| 40 | To detect read/write violations, emulator uses prefix and suffix guarding areas |
| 41 | that were added to the allocated blocks by the instrumented libc. To watch for |
| 42 | access violations, emulator instruments ld_/st_mmu routines to verify that |
| 43 | accessed memory doesn't belong to a guarding area of a block allocated in |
| 44 | context of the current process. |
| 45 | |
| 46 | There are some tricky things like: |
| 47 | - invalidating every page containing allocated blocks every time anything has |
| 48 | been read, or written to that page, so we can be sure that we don't miss AV |
| 49 | on condition that page has been cached and ld_/st_mmu is omitted when |
| 50 | accessing memory in that page. |
| 51 | - Keeping track of each thread calling stack, so when access violation is |
| 52 | reported, we can pinpoint violation to precise location in the source code. |
| 53 | - etc. |
| 54 | |
| 55 | All the code related to memory checking is guarded in emulator's code by |
| 56 | CONFIG_MEMCHECK macro, making it easy to spot changes related to it in the |
| 57 | sources. |