Documentation/Maemo Eclipse Tutorial/Eclipse Memory Profiling

Even if a developer provides an extensible round of tests, a certain type of problems cannot be easily detected by unit tests. In addition, such kind of problems may break the application and also disturb the normal execution of the platform. For example, a memory leak is a potential problem on applications for mobile devices, because it certainly consumes an important and limited resource. Maemo SDK provides Valgrind, a profiling tool often used to detect memory-related errors, such as memory leaks and problems on memory allocation.

Maemo IDE integration ESbox product provides support for profiling applications by using Valgrind memory profiler. This tutorial starts with a quick introduction to the Valgrind profiling tool. After that, it demonstrates how you can profile C/C++, Qt4 and Python applications at ESbox using the Valgrind memory profiler tool integration. Finally, you can see how to interpret Valgrind output at ESbox.

Valgrind memory profiling cannot be used with Maemo PluThon Eclipse IDE. Valgrind profiler be run only with Scratchbox and Maemo SDK for x86 binaries and Maemo PluThon does not support those (it is on-device development environment for Maemo devices).


[edit] Valgrind Memory Profiling

Valgrind is an Open Source suite of tools for debugging and profiling Linux programs. For Maemo environment it i susable only for x86 binaries. It is a powerful and easy-to-use tool that can save you a lot of debugging time. Since Valgrind works by simulating the x86 processor and instrumenting the binaries on the fly, it can control the program execution completely. On the downside, it makes program execution 10-300 times slower than normal, depending on the used Valgrind tools, and can take a huge amount of memory.

The Valgrind tool suite provides a number of debugging and profiling tools:

It is a profiler for cache memory. Cachegrind performs simulation of the I1, D1 and L2 caches in order to detect cache misses, wrong references and much more.
It is an extension of Cachegrind. It provides the same information as Cachegrind plus extra information about callgraphs.
It provides profilling information about heap memory by taking regular snapshots of a program's heap.
It is a useful tool to detect race conditions on multithreading applications, such as deadlocks.
It detects memory-management bugs on application. Memcheck keeps track of the validity (if a memory location is properly initialized) and addressability (if the memory address points to a valid memory block).

Since Valgrind tools instrument the code in order to obtain more accurate information about application execution, Memcheck is often used because it provides detailed information about memory problems, which are very common in mobile application development. It can detect many memory-related errors that are common in C and C++ programs and that can lead to crashes and unpredictable behaviour. Memcheck is the default tool on Maemo environment. The -leak-check option turns on the detailed memory leak detector. Memcheck will issue messages about memory errors and leaks that it detects.

[edit] Valgrind and IDE Integration

ESbox provides support only for the Valgrind memory (Memcheck) profiler tool for C/C++, Qt4 and Python projects. It uses the command valgrind -q -tool=memcheck -leak-check=yes to run Valgrind memory check tool (Memcheck) with detailed memory leak detector. This section shows how to profile your applications at ESbox and how to analyse profiling results.

[edit] Installation

You do not need to care about Valgrind installation. Once ESbox starts to profile your application with Valgrind, the system checks if necessary packages are properly installed in the environment. If they are not, ESbox installs and configure them. All these steps are performed by Validation Packages wizards, as shown in figure 10.1.

Figure 10.1: Installing Valgrind to environment

[edit] Profiling your Maemo application with Valgrind

Valgrind does not run on ARM Linux platform. Therefore, you can only use Valgrind with X86 Maemo SDK rootstraps.

At first, you must create a C/C++, Qt4 or Python Maemo Project and select an X86 Scratchbox target. To run Valgrind, right-click on the application (binary for C/C++ and Qt4 projects or the Python script for Python projects) and select Profile As > Local Valgrind Memory Profiler, figure 10.2. If the tool is not properly installed at the selected target, the system can automatically install it for you, figure 10.1.

Figure 10.2: Profiling an application with Valgrind

ESbox runs your application on the Maemo SDK X86 target and the result is shown in the Valgrind view, figure 10.3. All problems found by Valgrind are shown as a tree: problems as parent nodes and their details as children nodes. Valgrind error messages are explained in the #Analyzing results chapter.

Figure 10.3: Valgrind View
If you are planning to run the Valgrind profiler more than once, you will probably need to clear current Valgrind view results before running the current program. For that, you just need to click the Delete Current Sample button on the Valgrind view toolbar. If you do not, current results are merged with the older ones.

[edit] Analyzing results

During Valgrind memory profiling, different problems can be detected, such as:

  • Accessing memory locations that must not be accessed, for example, overrunning and underrunning heap blocks, overrunning the top of the stack, and accessing memory after it has been freed.
  • Using undefined values, that is, values that have not been initialised, or that have been derived from other undefined values.
  • Incorrect freeing of heap memory, such as double-freeing heap blocks, or mismatched use of malloc/new/new[] versus free/delete/delete[].
  • Overlapping src and dst pointers in memcpy and related functions.
  • Memory leaks.

This section presents a quick summary about some kinds of Valgrind error messages and how to interpret them.

[edit] Heap block overrun

A heap block overrun happens when you try to access (read/write) a block on heap memory that was not properly allocated. For example, an array of 10 integers is created (e.g, array[10]), but you try to access the 11th element, which does not exist. Most C compilers do not warn about this problem, and it is often a potential source of bugs. Most error messages look like the following one, which describes the heap block overrun problem, figure 10.4.

Figure 10.4: Heap block overrun

You must read each error message carefully to understand its information.

  • The number between == symbols is the process ID (for example, 7068).
  • The parent node (Invalid read of size 4) tells you what kind of error it is. Here, this message says that the program performed an illegal 4-byte read of address 0x406CDC7, which, as far as Memcheck can tell, is not a valid stack address, nor corresponds to any current heap blocks or recently freed heap blocks.
  • Details of the problems are shown as children nodes: a stack trace tells you where the problem occurred.
  • The code addresses (for example, 0x406CDC7) are usually unimportant, but occasionally crucial for tracking down weird bugs.
  • Some error messages have a second component which describes the memory address involved.

[edit] Memory leaks

Another kind of common error is the memory leak, which happens when you do not free previously allocated memory resources, for example arrays. For memory leaks, Valgrind outputs the following messages, figure 10.5.

Figure 10.5: Memory leak

Message details tells you where the memory leak is happening. However, it does not tell you why the memory leaks. Among few kinds of leaks, there are two important categories.

  • Definitely lost: when the program is really leaking memory.
  • Probably lost: when the program is possibly leaking memory.

[edit] Uninitialised values

Memory check also reports uses of uninitialised values, commonly with the message conditional jump or move depends on uninitialised value(s), figure 10.6.

Figure 10.6: Uninitialised values

An uninitialised-value error is reported when your program uses a value which has not been initialised. In our example, the undefined value was used somewhere inside the _dl_relocate_object.

[edit] System calls with invalid parameters

Another common error is a system call with invalid parameters, figure 10.7.

Figure 10.7: Invalid parameters

This error message shows that there is some uninitialised memory pointed to by buf System call parameter.

There are also other kinds of error messages not listed at this document. More information about them can be found at Valgrind Manual [1].

[edit] References

  1. Valgrind Manual.