example.js revision 1e9bf3e0803691d0a228da41fc608347b6db4340
1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5var lastModuleError = '';
6var crashed = false;
7
8function domContentLoaded(name, tc, config, width, height) {
9  common.attachDefaultListeners();
10  common.createNaClModule(name, tc, config, width, height);
11
12  updateStatus('Page Loaded');
13}
14
15// Indicate success when the NaCl module has loaded.
16function moduleDidLoad() {
17  updateStatus('LOADED');
18  setTimeout(boom, 2000);
19}
20
21function findAddress(addr, map) {
22  if (map.length < 1) {
23    return 'MAP Unavailable';
24  }
25  if (addr < map[0].offs) {
26    return 'Invalid Address';
27  }
28
29  for (var i = 1; i < map.length; i++) {
30    if (addr < map[i].offs) {
31      var offs = addr - map[i - 1].offs;
32      var filename = map[i - 1].file;
33
34      // Force filename to 50 chars
35      if (filename) {
36        if (filename.length > 50) {
37            filename = '...' + filename.substr(filename.length - 47);
38        }
39      } else {
40        filename = 'Unknown';
41      }
42      while (filename.length < 50) {
43        filename = ' ' + filename;
44      }
45      return filename + ' ' + map[i - 1].name + ' + 0x' + offs.toString(16);
46    }
47  }
48
49  var last = map.length - 1;
50  return filename + ' ' + map[last].name + ' + 0x' + offs.toString(16);
51}
52
53function buildTextMap(map) {
54  // The expected format of the map file is this:
55  // ...
56  // .text     0x00000000000201e0     0x10e0 newlib/Debug/debugging_x86_64.o
57  //           0x0000000000020280                layer5
58  //           0x00000000000202e0                layer4
59  //           0x0000000000020320                layer3
60  //           0x0000000000020380                layer2
61  //           0x00000000000203e0                layer1
62  //           0x0000000000020460                NexeMain
63  // ...
64  var lines = map.split('\n');
65  var orderedMap = [];
66  var inTextSection = false;
67  var fileName = '';
68
69  for (var i = 0; i < lines.length; i++) {
70    var line = lines[i];
71
72    if (inTextSection) {
73      //   <hex address>   <symbol name>
74      var vals = line.trim().split(/\s+/);
75      if (vals.length != 2) {
76        inTextSection = false;
77        continue;
78      }
79
80      var obj = {
81        offs: parseInt(vals[0], 16),
82        name: vals[1],
83        file: fileName
84      };
85
86      orderedMap.push(obj);
87    } else {
88      // If line starts with .text:
89      if (line.lastIndexOf(' .text', 0) === 0) {
90        inTextSection = true;
91        // .text    <hex address>   <size>  <filename>
92        var vals = line.trim().split(/\s+/);
93        fileName = vals[3];
94      }
95    }
96  }
97
98  orderedMap.sort(function(a, b) { return a.offs - b.offs; });
99  return orderedMap;
100}
101
102function updateStack(traceinfo, map) {
103  map = buildTextMap(map);
104  var text = 'Stack Trace\n';
105  for (var i = 0; i < traceinfo.frames.length; i++) {
106    var frame = traceinfo.frames[i];
107    var addr = findAddress(frame.prog_ctr, map);
108    text += '[' + i.toString(10) + '] ' + addr + '\n';
109  }
110  document.getElementById('trace').value = text;
111}
112
113function fetchMap(url, traceinfo) {
114  var xmlhttp = new XMLHttpRequest();
115  xmlhttp.open('GET', url, true);
116  xmlhttp.onload = function() {
117    updateStack(traceinfo, this.responseText);
118  };
119  xmlhttp.traceinfo = traceinfo;
120  xmlhttp.send();
121}
122
123// Handle a message coming from the NaCl module.
124function handleMessage(message_event) {
125  msg_type = message_event.data.substring(0, 4);
126  msg_data = message_event.data.substring(5, message_event.data.length);
127  if (msg_type == 'LOG:') {
128    document.getElementById('log').value += msg_data + '\n';
129    return;
130  }
131  if (msg_type == 'TRC:') {
132    crashed = true;
133    document.getElementById('json').value = msg_data;
134    crash_info = JSON.parse(msg_data);
135    updateStatus('Crash Reported');
136    src = common.naclModule.getAttribute('path');
137    fetchMap(src + '/debugging_' + crash_info['arch'] + '.map', crash_info);
138    return;
139  }
140}
141
142function updateStatus(message) {
143  common.updateStatus(message);
144
145  if (message)
146    document.getElementById('log').value += message + '\n';
147}
148
149function boom() {
150  if (!crashed) {
151    updateStatus('Send BOOM');
152    common.naclModule.postMessage('BOOM');
153  }
154}
155