1<html>
2<head>
3
4<title>ANR</title>
5
6<style>
7body {
8  height: 100%;
9  margin: 0;
10  padding: 0;
11  font-family: sans-serif;
12  display: flex;
13  flex-direction: column;
14  background-color: #eee;
15}
16
17.TopNav {
18  flex: 0 0 auto;
19  display: flex;
20  flex-direction: row;
21  align-items: baseline;
22}
23
24h1 {
25  font-size: 18pt;
26  margin: 0;
27  padding: 8px 16px 8px 16px;
28  flex: 1 1 auto;
29}
30
31h2 {
32  font-family: sans-serif;
33}
34
35a:link.
36a:visited {
37  color: #008;
38}
39
40a:hover {
41  color: #004;
42}
43
44a:active {
45  color: #00e;
46}
47
48.TopRightNav {
49  flex: 0 0 auto;
50  font-size: 10pt;
51  align-items: baseline;
52}
53
54.TopRightNav:last-child {
55  padding-right: 16px;
56}
57
58.TopRightNav input {
59  margin-left: 12px;
60}
61
62.Page {
63  flex: 1 1 auto;
64  display: flex;
65  flex-direction: row;
66}
67
68ul.LeftNav {
69  flex: 0 0 auto;
70  margin: 0;
71  padding: 0;
72  list-style: none;
73  overflow-y: scroll;
74}
75
76.LeftNavSection ul {
77  margin: 0;
78  padding: 0;
79  list-style: none;
80}
81
82.LeftNav li {
83  padding: 4px 16px 4px 16px;
84  font-size: 10pt;
85}
86
87.LeftNavPid {
88  font-size: 9pt;
89  color: #555;
90}
91
92.Content {
93  flex: 1 1 auto;
94  background-color: #fff;
95  overflow: scroll;
96}
97
98table.TriageInfo {
99  font-size: inherit;
100  padding-left: 12px;
101  margin: 0;
102}
103
104table.TriageInfo th {
105  white-space: nowrap;
106  padding: 2px 8px 2px 0;
107}
108
109table.TriageInfo th,
110table.TriageInfo td {
111  text-align: left;
112  vertical-align: top;
113}
114
115.Explanation {
116  font-size: 9pt;
117  font-family: sans-serif;
118  font-weight: normal;
119  color: #999;
120}
121
122.TriageHeader h2 {
123  margin: 8px 0 8px 0;
124  padding-left: 12px;
125}
126
127.Panel {
128  display: none;
129  padding: 24px;
130  font-family: monospace;
131  font-size: 10pt;
132}
133
134.Panel table {
135  font-size: 10pt;
136}
137
138.Panel > h2 {
139  box-shadow: 3px 3px 15px #888;
140  padding: 8px 8px 8px 20px;
141  margin-top: 40px;
142}
143
144.Panel > h2:first-child {
145  margin: 0 0 16px 0;
146}
147
148.Process,
149.TriageHeader {
150  box-shadow: 3px 3px 15px #888;
151  padding: 8px;
152  margin-bottom: 24px;
153}
154
155.ProcessCmdLine,
156.ProcessInfo {
157  margin-left: 12px;
158}
159
160.Thread {
161  margin: 16px 0 0 12px;
162  padding-left: 10px;
163}
164
165.ThreadBlocked {
166  border-left: 2px solid red;
167  padding-left: 8px;
168}
169
170.ThreadBinder {
171  border-left: 2px solid green;
172  padding-left: 8px;
173}
174
175.ThreadInteresting {
176  border-left: 2px solid blue;
177  padding-left: 8px;
178}
179
180.ThreadName {
181  font-weight: bold;
182}
183
184.ThreadTid {
185  font-weight: normal;
186  color: #999;
187}
188
189.ThreadInfo {
190  margin: 4px 0 0 2px;
191  color: #999;
192}
193
194.ThreadExtras {
195}
196
197.Extra {
198  display: none;
199}
200
201.ThreadStack {
202  margin-top: 4px;
203}
204
205.ThreadStack td {
206  padding: 0;
207  vertical-align: top;
208}
209
210.ThreadStack td.FrameType {
211  padding: 0 8px 0 0;
212}
213
214.FrameLock {
215  margin: 2px 0 1px 16px;
216  font:size: 9pt;
217}
218
219.NativeFrame {
220  display: none;
221}
222
223.FrameUnimportant {
224  color: #999;
225}
226
227.FrameImportant {
228  color: black;
229}
230
231.LogcatLines {
232}
233
234.LogcatLine {
235  font-size: 9pt;
236  vertical-align: top;
237  display: flex;
238}
239
240.LogcatBufferBegin {
241  flex: 0 0 auto;
242  white-space: pre;
243  margin-left: 8px;
244  font-style: italic;
245}
246
247.LogcatHeader {
248  flex: 0 0 auto;
249  white-space: pre;
250  margin-left: 8px;
251}
252
253.LogcatTag {
254}
255
256.LogcatText {
257  color: #444;
258}
259
260.LogcatData {
261  flex: 1 1 auto;
262  white-space: pre-wrap;
263  word-break: break-word;
264}
265
266.LogLevelE .LogcatHeader,
267.LogLevelE .LogcatTag,
268.LogLevelE .LogcatText {
269  color: #800;
270}
271
272.LogcatMarkerSpacer {
273  flex: 0 0 2px;
274}
275
276.LogcatMarkerAnr {
277  flex: 0 0 2px;
278  background-color: #00f;
279}
280
281.LogcatMarkerBugreport {
282  flex: 0 0 2px;
283  background-color: #000;
284}
285
286.InterestingLogcatLineInfo {
287}
288
289
290</style>
291
292<script type="text/javascript">
293/**
294 * Navigate to the panel with the id _panel_id_.
295 */
296var currentPanel = null;
297function nav(panel_id) {
298  if (currentPanel != null) {
299    currentPanel.style.display = "none";
300  }
301  currentPanel = document.getElementById(panel_id);
302  currentPanel.style.display = "block";
303  window.setTimeout(function() {
304    currentPanel.focus();
305  }, 0);
306
307  currentPanel.focus();
308}
309
310/**
311 * Toggle the display of the native java stack frames.
312 */
313function show_native() {
314  var checkbox = document.getElementById("checkbox_show_native");
315  var display = checkbox.checked ? "table-row" : "none";
316  replaceCssStyleRule(".NativeFrame", "display: " + display + ";");
317}
318
319/**
320 * Toggle the display of extras.
321 */
322function extras() {
323  var checkbox = document.getElementById("checkbox_extras");
324  var display = checkbox.checked ? "block" : "none";
325  replaceCssStyleRule(".Extra", "display: " + display + ";");
326}
327
328/**
329 * Get a CSS Style rule for the given selector.
330 */
331function replaceCssStyleRule(selector, text) {
332  var stylesheet = document.styleSheets[0];
333  for (var i=0; i<stylesheet.cssRules.length; i++) {
334    if (stylesheet.cssRules[i].selectorText == selector) {
335      stylesheet.deleteRule(i);
336      break;
337    }
338  }
339  stylesheet.insertRule(selector + " { " + text + " }", i);
340}
341
342/**
343 * In the log panel, scroll to the log line with the given lineno.
344 */
345function scroll_to_log_line(lineno) {
346  var id = "logcat_line_" + lineno;
347  var element = document.getElementById(id);
348  if (element != null) {
349    element.scrollIntoView();
350  }
351}
352
353</script>
354
355<?cs def:render_tids(tid, sysTid) ?><?cs
356  if:tid >= 0 ?>tid=<?cs var:tid ?><?cs /if
357  ?><?cs if:sysTid >= 0 ?><?cs if:tid >= 0 ?> <?cs /if ?>sysTid=<?cs var:sysTid ?><?cs /if
358?><?cs /def ?>
359
360<?cs def:render_thread(thread) ?>
361  <div class="Thread <?cs if:thread.blocked
362        ?>ThreadBlocked<?cs
363      elif:thread.binder
364        ?>ThreadBinder<?cs
365      elif:thread.interesting
366        ?>ThreadInteresting<?cs
367      /if ?>">
368    <!-- binder=<?cs var:thread.binder ?> -->
369    <div class="ThreadName"><?cs var:thread.name ?> <span class="ThreadTid">(<?cs call:render_tids(thread.tid, thread.sysTid) ?>)</span></div>
370    <div class="ThreadInfo">
371      <?cs if:thread.runnable ?>
372        <div>Runnable</div>
373      <?cs /if ?>
374      <?cs if:thread.outboundBinderCall ?>
375        <div>Outbound binder call: <?cs var:thread.outboundBinderCall ?></div>
376      <?cs /if ?>
377      <?cs if:thread.inboundBinderCall ?>
378        <div>Inbound binder call: <?cs var:thread.inboundBinderCall ?></div>
379      <?cs /if ?>
380      <?cs if:thread.heldMutexes ?>
381        <div class="ThreadHeldMutexes">Held mutexes: <?cs var:thread.heldMutexes ?></div>
382      <?cs /if ?>
383      <div class="ThreadExtras Extra">
384        VM State: <?cs var:thread.vmState ?><br>
385        Priority: <?cs var:thread.priority ?><br>
386        <?cs if:thread.daemon ?><?cs var:thread.daemon ?><br><?cs /if ?>
387        <?cs each:attr = thread.attributes ?>
388          <?cs var:attr ?><br>
389        <?cs /each ?>
390      </div>
391    </div>
392    <table class="ThreadStack">
393      <?cs each:frame = thread.frames ?>
394        <tr class="<?cs if: frame.frameType == 'native' || frame.frameType == 'kernel' ?>NativeFrame<?cs /if ?>">
395        <?cs if:frame.frameType == "native" ?>
396          <td class="FrameType"><span class="FrameUnimportant">native</span></td>
397          <td><span class="FrameImportant"><?cs var:frame.symbol ?></span><span class="FrameUnimportant"><?cs if:frame.offset >= 0 ?>+<?cs var:frame.offset ?><?cs /if ?> <?cs var:frame.library ?></span></td>
398        <?cs elif:frame.frameType == "kernel" ?>
399          <td class="FrameType"><span class="FrameUnimportant">kernel</span></td>
400          <td><span class="FrameImportant"><?cs var:frame.syscall ?></span><span class="FrameUnimportant">+<?cs var:frame.offset0 ?> / <?cs var: frame.offset1 ?></span></td>
401        <?cs elif:frame.frameType == "java" ?>
402          <td class="FrameType"><span class="FrameUnimportant"><?cs var:frame.language ?></span></td>
403          <td><span class="FrameImportant"><?cs if:frame.packageName ?><?cs
404            var:frame.packageName ?>.<?cs /if ?><?cs var:frame.className ?>.<?cs
405            var:frame.methodName ?></span>
406            <?cs if:frame.sourceFile ?><span class="FrameUnimportant"><?cs var:frame.sourceFile
407              ?><?cs if:frame.sourceLine ?>:<?cs var:frame.sourceLine ?><?cs /if
408            ?></span><?cs /if ?>
409            <?cs each:lock = frame.locks ?>
410              <div class="FrameLock"><span class="FrameUnimportant"><?cs var:lock.type ?>
411                <?cs if:lock.className ?>on a
412                  <?cs if:lock.packageName ?><?cs var:lock.packageName ?>.<?cs /if ?><?cs var:lock.className ?> (0x<?cs var:lock.address ?>)
413                  <?cs if:lock.threadId >= 0 ?>held by thread
414                    <?cs if:lock.threadName ?>
415                      "<?cs var:lock.threadName ?>" (<?cs call:render_tids(lock.threadId, lock.threadSysTid) ?>)
416                    <?cs else ?>
417                      tid <?cs var:lock.threadId ?>
418                    <?cs /if ?>
419                  <?cs /if ?>
420                <?cs else ?>
421                  on an unknown object
422                <?cs /if ?></span>
423            <?cs /each ?>
424            </td>
425        <?cs else ?>
426          <td class="FrameType"></td>
427          <td><span class="FrameUnimportant"><?cs var:frame.text ?></span></td>
428        <?cs /if ?>
429        </tr>
430      <?cs /each ?>
431    </table>
432  </div>
433<?cs /def ?>
434
435<?cs def:render_process(process) ?>
436  <div class="Process">
437    <div class="ProcessCmdLine"><b>Process:</b> <?cs var: process.cmdLine ?></div>
438    <div class="ProcessInfo">
439      <b>PID:</b> <?cs var: process.pid ?><br>
440      <div class="Extra">
441        <b>Timestamp:</b> <?cs var: process.date ?><br>
442      </div>
443    </div>
444
445    <?cs each:thread = process.threads ?>
446      <?cs call:render_thread(thread) ?>
447    <?cs /each ?>
448  </div>
449<?cs /def ?>
450
451</head>
452
453<body onload="nav('panel_triage')">
454<div class="TopNav">
455  <h1>ANR</h1>
456  <div class="TopRightNav">
457    <input type="checkbox" id="checkbox_show_native" onclick="javascript:show_native()">
458    <label for="checkbox_show_native">native</label>
459
460    <input type="checkbox" id="checkbox_extras" onclick="javascript:extras()">
461    <label for="checkbox_extras">extras</label>
462  </div>
463</div>
464
465<div class="Page">
466
467<ul class="LeftNav">
468  <li><a href="javascript:nav('panel_triage');">Triage</a></li>
469  <li><a href="javascript:nav('panel_logcat');">Logcat</a></li>
470<!--  <li><a href="javascript:nav('panel_cpu_info');">CPU Info</a></li> -->
471  <?cs if:subcount(monkey.processes) > 0 ?>
472    <li class="LeftNavSection">
473      Monkey ANR Stack Traces
474      <ul>
475        <?cs each:process = monkey.processes ?>
476          <li><a href="javascript:nav('panel_<?cs var:process.panelId ?>');"><?cs var:process.cmdLine ?></a> <span class="LeftNavPid">(pid <?cs var:process.pid ?>)</span></li>
477        <?cs /each ?>
478      </ul>
479    </li>
480  <?cs /if ?>
481  <?cs if:subcount(vmTracesLastAnr.processes) > 0 ?>
482    <li class="LeftNavSection">
483      Last ANR Stack Traces
484      <ul>
485        <?cs each:process = vmTracesLastAnr.processes ?>
486          <li><a href="javascript:nav('panel_<?cs var:process.panelId ?>');"><?cs var:process.cmdLine ?></a> <span class="LeftNavPid">(pid <?cs var:process.pid ?>)</span></li>
487        <?cs /each ?>
488      </ul>
489    </li>
490  <?cs /if ?>
491  <?cs if:subcount(vmTracesJustNow.processes) > 0 ?>
492    <li class="LeftNavSection">
493      Stack Traces Just Now
494      <ul>
495        <?cs each:process = vmTracesJustNow.processes ?>
496          <li><a href="javascript:nav('panel_<?cs var:process.panelId ?>');"><?cs var:process.cmdLine ?></a> <span class="LeftNavPid">(pid <?cs var:process.pid ?>)</span></li>
497        <?cs /each ?>
498      </ul>
499    </li>
500  <?cs /if ?>
501</ul> <!-- class="LeftNav" -->
502
503<div class="Content">
504
505<div class="Panel" id="panel_triage" style="display: block;">
506  <h2>ANR Triage</h2>
507  <div class="TriageHeader">
508    <table class="TriageInfo">
509    <tr><th>Process Name: </th><td><?cs var: triage.processName ?></tr>
510    <tr><th>PID:</th><td><?cs var:triage.pid ?></td></tr>
511    <tr><th>Active Component:</th><td><?cs var: triage.componentPackage ?>/<?cs var:triage.componentClass ?></tr>
512    <tr><th>Reason:</th><td><?cs var:triage.reason ?></td></tr>
513    </table>
514    <?cs call:render_thread(triage.mainThread) ?>
515  </div>
516
517  <?cs if:subcount(triage.deadlockedProcesses) > 0 ?>
518    <h2>Deadlocked Threads
519    <div class="Explanation">
520      Deadlocked threads are blocked on each other, either via a set of java object locks
521      or binder calls.
522    </div>
523    </h2>
524
525    <?cs each:process = triage.deadlockedProcesses ?>
526      <?cs call:render_process(process) ?>
527    <?cs /each ?>
528  <?cs /if ?>
529
530  <?cs if:subcount(triage.interestingProcesses) > 0 ?>
531    <h2>Active Processes &amp; Threads
532    <div class="Explanation">
533      "Active" processes are processes that have or one or more
534      threads that are runnable, not blocked in an event loop or thread pool, with a
535      certain set of VM threads excluded as well.
536    </div>
537    </h2>
538
539    <?cs each:process = triage.interestingProcesses ?>
540      <?cs call:render_process(process) ?>
541    <?cs /each ?>
542  <?cs /if ?>
543
544</div>
545
546<div class="Panel" id="panel_logcat">
547  <div class="Logcat">
548    <h2>Interesting Log Lines</h2>
549    <?cs if:subcount(logcat.interesting) ?>
550      <div class="InterestingLogcatLines">
551        <?cs each:line = logcat.interesting ?>
552          <div class="InterestingLogcatLine">
553            <a href="javascript:scroll_to_log_line(<?cs var:line.lineno ?>)">
554              <div class="LogcatLine">
555                <?cs if:line.bufferBegin ?>
556                  <div class="LogcatBufferBegin"><?cs var:line.rawText ?></div>
557                <?cs else ?>
558                  <div class="LogcatHeader"><?cs var:line.header ?></div>
559                  <div class="LogcatData"><?cs var:line.tag ?>: <?cs var:line.text ?></span></div>
560                <?cs /if ?>
561              </div>
562            </a>
563          </div>
564        <?cs /each ?>
565      </div>
566    <?cs /if ?>
567    <h2>Logcat</h2>
568
569    <div class="LogcatLines">
570        <?cs each:line = logcat.lines ?>
571          <div class="LogcatLine LogLevel<?cs var:line.level ?>"
572              id="logcat_line_<?cs var:line.lineno ?>">
573            <div class="<?cs if:line.regionAnr ?>LogcatMarkerAnr<?cs else ?>LogcatMarkerSpacer<?cs /if ?>"></div>
574            <div class="<?cs if:line.regionBugreport ?>LogcatMarkerBugreport<?cs else ?>LogcatMarkerSpacer<?cs /if ?>"></div>
575            <?cs if:line.bufferBegin ?>
576              <div class="LogcatBufferBegin"><?cs var:line.rawText ?></div>
577            <?cs else ?>
578              <div class="LogcatHeader"
579                <?cs if:line.title ?>title="<?cs var:line.title ?>" <?cs /if ?>
580                ><?cs var:line.header ?></div>
581              <div class="LogcatData"><span class="LogcatTag"><?cs var:line.tag ?></span><span class="LogcatText">: <?cs var:line.text ?></span></div>
582            <?cs /if ?>
583          </div>
584        <?cs /each ?>
585    </div>
586  </div>
587</div>
588
589<div class="Panel" id="panel_cpu_info">
590CPU Info
591</div>
592
593<?cs each:process = monkey.processes ?>
594  <div class="Panel" id="panel_<?cs var:process.panelId ?>">
595    <?cs call:render_process(process) ?>
596  </div> <!-- Panel -->
597<?cs /each ?>
598
599<?cs each:process = vmTracesLastAnr.processes ?>
600  <div class="Panel" id="panel_<?cs var:process.panelId ?>">
601    <?cs call:render_process(process) ?>
602  </div> <!-- Panel -->
603<?cs /each ?>
604
605<?cs each:process = vmTracesJustNow.processes ?>
606  <div class="Panel" id="panel_<?cs var:process.panelId ?>">
607    <?cs call:render_process(process) ?>
608  </div> <!-- Panel -->
609<?cs /each ?>
610
611
612</div> <!-- class="Content" -->
613
614</div> <!-- class="Page" -->
615</body>
616</html>
617
618<!-- vim: set ts=2 sw=2 sts=2 nocindent: -->
619