Skip to content

Most visited

Recently visited

navigation

Native Tracing

This guide describes how to use the native tracing API (trace.h) to write trace events to the system buffer. You can then analyze this trace output by using the Systrace tool. The native tracing API is supported for Android API levels 23 and higher.

Overview

Creating a custom trace in native code is similar to the technique for the Java programming language, described in Tracing Application Code. You typically don’t need to put your native tracing code in try/catch blocks unless the traced section throws a native exception or uses an early return.

For each ATrace_beginSection() call, make sure you also have a corresponding ATrace_endSection() call, otherwise it might result in a corrupt trace file.

To avoid building complex strings or arguments when tracing is not enabled, you can add a guard by calling ATrace_isEnabled() .

Tracing a Function

One use case for the native tracing API is to observe the time taken by a particular block of code. Typically, this tracing would be during the pipeline processing stage (for example, when decoding an image, drawing a frame, or waiting on a network request).

To trace the time taken by a block of code, follow these steps:

  1. Include the trace.h header file.
    #include <android/trace.h>
    
  2. Specify a variable as the section name in ATrace_beginSection(). At the end of the block of code you want to trace, make a corresponding call to ATrace_endSection(). This is particularly important when the traced section throws a native exception or uses an early return.
    void myExpensiveFunction() {
      ATrace_beginSection("myExpensiveFunction");
      ... // trace-worthy work here
      ATrace_endSection();
    }
    
  3. (Optional) Create a convenience object/macro structure to trace blocks of code. The following example shows how you might implement such an object/macro called ATRACE_CALL().
    #define ATRACE_NAME(name) ScopedTrace ___tracer(name)
    
    // ATRACE_CALL is an ATRACE_NAME that uses the current function name.
    #define ATRACE_CALL() ATRACE_NAME(__FUNCTION__)
    
    class ScopedTrace {
      public:
        inline ScopedTrace(const char *name) {
          ATrace_beginSection(name);
        }
    
        inline ~ScopedTrace() {
          ATrace_endSection();
        }
    };
    
    Using the ATRACE_CALL() object/macro, you can simplify the code from the previous step as follows. By using the object/macro this way, you don't need to worry about adding try/catch blocks when the traced section throws an exception or uses an early return.
    void myExpensiveFunction() {
      ATRACE_CALL();
      ... // trace-worthy work here
    }
    
This site uses cookies to store your preferences for site-specific language and display options.

Browse this site in ?

You requested a page in , but your language preference for this site is .

Would you like to change your language preference and browse this site in ? If you want to change your language preference later, use the language menu at the bottom of each page.

This class requires API level or higher

This doc is hidden because your selected API level for the documentation is . You can change the documentation API level with the selector above the left navigation.

For more information about specifying the API level your app requires, read Supporting Different Platform Versions.

Take a short survey?
Help us improve the Android developer experience.
(Sep 2017 survey)