Systematic Solution for Android Native Memory Leak

  • Limitations on read-only memory (ROM) make routine development and testing inconvenient.
  • An environment must be prepared for each troubleshooting operation that must be manually performed through CLI or DDMS. This process does not support comparative analysis and produces final results that are not intuitive.

Stack Backtrace Acceleration

The Android platform uses Libunwind to perform stack backtrace, which usually meets the needs in most scenarios. However, global locks and unwind table parsing in the Libunwind implementation may result in performance loss and further renders application unresponsive and unavailable in case of frequent multithreaded calls.

Acceleration Principles

A compiler has the -finstrument-functions compilation option that supports the insertion of user-defined functions (UDFs) in the beginning and at the end of a function.

  1. Record call addresses in TLS in the form of arrays and cursors to insert, remove, and acquire code as fast as possible.
  • Initialize the storage key of thread_stack_t in TLS
  • Initialize thread_stack_t and put it in TLS
  1. Compile the preceding logic as a dynamic library as other service modules depend on the dynamic library compilation. Insert -finstrument-functions into the compilation flag for instrumentation so that calls to all functions are recorded in TLS. You can acquire the call stack by calling get_tls_backtrace(void** backtrace, int max) in any place.

Performance Comparison

Following charts outline the performance comparison based on Google Benchmarking performed on the 5.1 operating system of Huawei Enjoy 5s:

Advantages and Disadvantages

The primary advantage of this solution is the highly improved acquisition speed which meets the requirement of frequent stack backtrace.

Systematization

After accelerating the acquisition of the memory allocation stack, you can troubleshoot native memory leaks by using Google-provided tools, such as DDMS and the adb shell am dumpheap -n pid /data/local/tmp/heap.txt command. However, such troubleshooting is inefficient and must be performed in the defined mobile phone environment.

  • Use get_tls_backtrace to execute LIBC_HIDDEN int32_t get_backtrace_external(uintptr_t* frames, size_t max_depth) that is used in the malloc_debug module, in combination with stack backtrace acceleration.
  • Establish socket communication to enable external programs for exchanging data through a socket and conveniently acquire memory data.
  • Build a web client to acquire and parse the uploaded memory data for display. The address must be reverse engineered by using addr2line.
  • Write test cases to be executed in combination with automatic testing. When testing begins, use the socket to collect memory information and subsequently store it. When testing ends, upload the memory information to the platform for parsing and send an evaluation email. When an alert is triggered, you can perform troubleshooting on the web client based on the memory curve and call stack information.

Original Source

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store