summaryrefslogtreecommitdiffstats
path: root/docs/html/tools/debugging/debugging-tracing.jd
blob: fa5b4e1254bce9160df6128ea985f263bcaf4232 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
page.title=Profiling with Traceview and dmtracedump
parent.title=Debugging
parent.link=index.html
@jd:body

 <div id="qv-wrapper">
    <div id="qv">
      <h2>In this document</h2>

      <ol>
        <li>
          <a href="#traceviewLayout">Traceview Layout</a>

          <ol>
            <li><a href="#timelinepanel">Timeline Panel</a></li>

            <li><a href="#profilepanel">Profile Panel</a></li>
          </ol>
        </li>

        <li><a href="#creatingtracefiles">Creating Trace Files</a></li>

        <li><a href="#copyingfiles">Copying Trace Files to a Host Machine</a></li>

        <li><a href="#runningtraceview">Viewing Trace Files in Traceview</a></li>

        <li><a href="#dmtracedump">Using dmtracedump</a></li>
        
        <li><a href="#knownissues">Traceview Known Issues</a></li>
      </ol>
    </div>
  </div>

  <p>Traceview is a graphical viewer for execution logs that you create by using the {@link
  android.os.Debug} class to log tracing information in your code. Traceview can help you debug
  your application and profile its performance.</p>

  <h2 id="traceviewLayout">Traceview Layout</h2>

  <p>When you have a trace log file (generated by adding tracing code to your application or by DDMS),
  you can load the log files in Traceview, which displays the log data in two panels:</p>

  <ul>
    <li>A <a href="#timelinepanel">timeline panel</a> -- describes when each thread and method
    started and stopped</li>

    <li>A <a href="#timelinepanel">profile panel</a> -- provides a summary of what happened inside
    a method</li>
  </ul>

  <p>The sections below provide addition information about the traceview output panes.</p>
  
  <h3 id="timelinepanel">Timeline Panel</h3>

  <p>Figure 1 shows a close up of the timeline panel. Each thread&rsquo;s execution is shown
  in its own row, with time increasing to the right. Each method is shown in another color (colors
  are reused in a round-robin fashion starting with the methods that have the most inclusive time).
  The thin lines underneath the first row show the extent (entry to exit) of all the calls to the
  selected method.</p>

  <img src="{@docRoot}images/traceview_timeline.png"
       alt="Traceview timeline panel"
       width="893"
       height="284" />
       <p class="img-caption"><strong>Figure 1.</strong> The Traceview Timeline Panel</p>

  <h3 id="profilepanel">Profile Panel</h3>

  <p>Figure 2 shows the profile pane, a summary of all the time spent
  in a method. The table shows both the inclusive and exclusive times (as well as the percentage of
  the total time). Exclusive time is the time spent in the method. Inclusive time is the time spent
  in the method plus the time spent in any called functions. We refer to calling methods as
  "parents" and called methods as "children." When a method is selected (by clicking on it), it
  expands to show the parents and children. Parents are shown with a purple background and children
  with a yellow background. The last column in the table shows the number of calls to this method
  plus the number of recursive calls. The last column shows the number of calls out of the total
  number of calls made to that method. In this view, we can see that there were 14 calls to
  <code>LoadListener.nativeFinished();</code> looking at the timeline panel shows that one of those calls took
  an unusually long time.</p>

  <img src="{@docRoot}images/traceview_profile.png"
       alt="Traceview profile panel."
       width="892"
       height="630" />
  <p class="img-caption"><strong>Figure 2.</strong> The Traceview Profile Panel</p>

  <h2 id="creatingtracefiles">Creating Trace Files</h2>

  <p>To use Traceview, you need to generate log files containing the trace information you want to
  analyze.</p>
  
  <p>There are two ways to generate trace logs:</p>
  <ul>
    <li>Include the {@link android.os.Debug} class in your code and call its
  methods such as {@link android.os.Debug#startMethodTracing()} and {@link
  android.os.Debug#stopMethodTracing()}, to start and stop logging of trace information to disk.
  This option is very precise because
  you can specify exactly where to start and stop logging trace data in your code.</li>
    <li>Use the method profiling feature of DDMS to generate trace logs. This option is less
    precise because you do not modify code, but rather specify when to start and stop logging with
    DDMS. Although you have less control on exactly where logging starts and stops,
    this option is useful if you don't have access to the application's code, or if you do
    not need precise log timing.
    </li>
  </ul>
  
  <p>Before you start generating trace logs, be aware of the following restrictions:</p>
  <ul>
    <li>If you are using the {@link android.os.Debug} class,
     your application must have permission to write to external storage
     ({@link android.Manifest.permission#READ_EXTERNAL_STORAGE}). </li>
    <li>If you are using DDMS:
      <ul>
        <li>Android 2.1 and earlier devices must
    have an SD card present and your application must have permission to write to the SD card.
        <li>Android 2.2 and later devices do not need an SD card. The trace log files are
    streamed directly to your development machine.</li>
      </ul>
    </li>
  </ul>
  
  <p>This document focuses on using the {@link android.os.Debug} class to generate trace data.  For more information on using DDMS
  to generate trace data, see <a href="ddms.html#profiling">Using the Dalvik Debug Monitor Server.</a>
  </p>
  
  <p>To create the trace files, include the {@link android.os.Debug} class and call one of the
  {@link android.os.Debug#startMethodTracing() startMethodTracing()} methods. In the call, you
  specify a base name for the trace files that the system generates. To stop tracing, call {@link
  android.os.Debug#stopMethodTracing() stopMethodTracing()}. These methods start and stop method
  tracing across the entire virtual machine. For example, you could call
  {@link android.os.Debug#startMethodTracing() startMethodTracing()} in
  your activity's {@link android.app.Activity#onCreate onCreate()} method, and call
  {@link android.os.Debug#stopMethodTracing() stopMethodTracing()} in that activity's
  {@link android.app.Activity#onDestroy()} method.</p>
  <pre>
    // start tracing to "/sdcard/calc.trace"
    Debug.startMethodTracing("calc");
    // ...
    // stop tracing
    Debug.stopMethodTracing();
</pre>

  <p>When your application calls {@link android.os.Debug#startMethodTracing() startMethodTracing()},
  the system creates a file called
  <code>&lt;trace-base-name&gt;.trace</code>. This contains the binary method trace data and a
  mapping table with thread and method names.</p>

  <p>The system then begins buffering the generated trace data, until your application calls
  {@link android.os.Debug#stopMethodTracing() stopMethodTracing()}, at which time it writes
  the buffered data to the output file. If the system
  reaches the maximum buffer size before you call {@link android.os.Debug#stopMethodTracing()
  stopMethodTracing()}, the system stops tracing
  and sends a notification to the console.</p>

  <p>Interpreted code runs more slowly when profiling is enabled. Don't try to generate
  absolute timings from the profiler results (such as, "function X takes 2.5 seconds to run"). The
  times are only useful in relation to other profile output, so you can see if changes have made
  the code faster or slower relative to a previous profiling run.</p>

  <p>In Android 4.4 and later, you can use sample-based profiling to profile with less runtime
  performance impact. To enable sample profiling, call {@link
  android.os.Debug#startMethodTracingSampling(java.lang.String, int, int)
  startMethodTracingSampling()} with a specified sampling interval. The system will then gather
  samples periodically until tracing is stopped via {@link android.os.Debug#stopMethodTracing()
  stopMethodTracing()}.</p>

  <h2 id="copyingfiles">Copying Trace Files to a Host Machine</h2>

  <p>After your application has run and the system has created your trace files
  <code>&lt;trace-base-name&gt;.trace</code> on a device or emulator, you must copy those files to
  your development computer. You can use <code>adb pull</code> to copy the files. Here's an example
  that shows how to copy an example file, calc.trace, from the default location on the emulator to
  the /tmp directory on the emulator host machine:</p>
  <pre>
adb pull /sdcard/calc.trace /tmp
</pre>

  <h2 id="runningtraceview">Viewing Trace Files in Traceview</h2>

  <p>To run Traceview and view the trace files, enter <code>traceview
  &lt;trace-base-name&gt;</code>. For example, to run Traceview on the example files copied in the
  previous section, use:</p>
  <pre>
traceview /tmp/calc
</pre>

  <p class="note"><strong>Note:</strong> If you are trying to view the trace logs of an application 
  that is built with ProGuard enabled (release mode build), some method and member names might be obfuscated.
  You can use the Proguard <code>mapping.txt</code> file to figure out the original unobfuscated names. For more information
  on this file, see the <a href="{@docRoot}tools/help/proguard.html">Proguard</a> documentation.</p>

      <h2 id="dmtracedump">Using dmtracedump</h2>

      <p><code>dmtracedump</code> is a tool that gives you an alternate way of generating
      graphical call-stack diagrams from trace log files. The tool uses the Graphviz Dot utility to
      create the graphical output, so you need to install Graphviz before running dmtracedump.</p>

      <p>The dmtracedump tool generates the call stack data as a tree diagram, with each call
      represented as a node. It shows call flow (from parent node to child nodes) using arrows. The
      diagram below shows an example of dmtracedump output.</p>
      <img src=
      "{@docRoot}images/tracedump.png"
          width="485"
          height="401" />
       <p class="img-caption"><strong>Figure 3.</strong> Screenshot of dmtracedump</p>

      <p>For each node, dmtracedump shows <code>&lt;ref&gt;
      <em>callname</em> (&lt;inc-ms&gt;, &lt;exc-ms&gt;,&lt;numcalls&gt;)</code>, where</p>

      <ul>
        <li><code>&lt;ref&gt;</code> -- Call reference number, as used in trace logs</li>

        <li><code>&lt;inc-ms&gt;</code> -- Inclusive elapsed time (milliseconds spent in method,
        including all child methods)</li>

        <li><code>&lt;exc-ms&gt;</code> -- Exclusive elapsed time (milliseconds spent in method,
        not including any child methods)</li>

        <li><code>&lt;numcalls&gt;</code> -- Number of calls</li>
      </ul>

      <p>The usage for dmtracedump is:</p>
      <pre>
dmtracedump [-ho] [-s sortable] [-d trace-base-name] [-g outfile] &lt;trace-base-name&gt;
</pre>

      <p>The tool then loads trace log data from <code>&lt;trace-base-name&gt;.data</code> and
      <code>&lt;trace-base-name&gt;.key</code>. The table below lists the options for dmtracedump.</p>

      <table>
        <tr>
          <th>Option</th>

          <th>Description</th>
        </tr>

        <tr>
          <td><code>-d&nbsp;&lt;trace-base-name&gt;</code></td>

          <td>Diff with this trace name</td>
        </tr>

        <tr>
          <td><code>-g&nbsp;&lt;outfile&gt;</code></td>

          <td>Generate output to &lt;outfile&gt;</td>
        </tr>

        <tr>
          <td><code>-h</code></td>

          <td>Turn on HTML output</td>
        </tr>

        <tr>
          <td><code>-o</code></td>

          <td>Dump the trace file instead of profiling</td>
        </tr>

        <tr>
          <td><code>-d&nbsp;&lt;trace-base-name&gt;</code></td>

          <td>URL base to the location of the sortable javascript file</td>
        </tr>

        <tr>
          <td><code>-t&nbsp;&lt;percent&gt;</code></td>

          <td>Minimum threshold for including child nodes in the graph (child's inclusive time as a
          percentage of parent inclusive time). If this option is not used, the default threshold
          is 20%.</td>
        </tr>
      </table>
  
  
    
  <h2 id="knownissues">Traceview Known Issues</h2>

  <dl>
    <dt>Threads</dt>

    <dd>
      Traceview logging does not handle threads well, resulting in these two problems:

      <ol>
        <li>If a thread exits during profiling, the thread name is not emitted (fixed in Android 5.1
	and later);</li>

        <li>The VM reuses thread IDs. If a thread stops and another starts, they may get the same
        ID.</li>
      </ol>
    </dd>

    </dl>