Home | History | Annotate | Download | only in debugging
      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 
      5 var lastModuleError = '';
      6 var crashed = false;
      7 
      8 function 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.
     16 function moduleDidLoad() {
     17   updateStatus('LOADED');
     18   setTimeout(boom, 2000);
     19 }
     20 
     21 function 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 
     53 function 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 
    102 function 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 
    113 function 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.
    124 function 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 
    142 function updateStatus(message) {
    143   common.updateStatus(message);
    144 
    145   if (message)
    146     document.getElementById('log').value += message + '\n';
    147 }
    148 
    149 function boom() {
    150   if (!crashed) {
    151     updateStatus('Send BOOM');
    152     common.naclModule.postMessage('BOOM');
    153   }
    154 }
    155