Exemple #1
0
  def _load_nm(prepared_data_dir, maps_filename, nm_json_filename):
    with open(os.path.join(prepared_data_dir, maps_filename), mode='r') as f:
      maps = parse_proc_maps(f)
    with open(os.path.join(prepared_data_dir, nm_json_filename), mode='r') as f:
      nm_files = json.load(f)

    symbol_tables = {}
    for entry in maps.iter(executable_condition):
      if nm_files.has_key(entry.name):
        if nm_files[entry.name]['format'] == 'bsd':
          with open(os.path.join(prepared_data_dir,
                                 nm_files[entry.name]['file']), mode='r') as f:
            symbol_tables[entry.name] = _get_static_symbols_from_nm_bsd(
                f, nm_files[entry.name]['mangled'])

    return StaticSymbols(maps, symbol_tables)
Exemple #2
0
def _find_runtime_symbols(prepared_data_dir, addresses, outputter, loglevel=logging.WARN):
    log = logging.getLogger("find_runtime_symbols")
    log.setLevel(loglevel)
    handler = logging.StreamHandler()
    handler.setLevel(loglevel)
    formatter = logging.Formatter("%(message)s")
    handler.setFormatter(formatter)
    log.addHandler(handler)

    if not os.path.exists(prepared_data_dir):
        log.warn("Nothing found: %s" % prepared_data_dir)
        return 1
    if not os.path.isdir(prepared_data_dir):
        log.warn("Not a directory: %s" % prepared_data_dir)
        return 1

    with open(os.path.join(prepared_data_dir, "maps"), mode="r") as f:
        maps = parse_proc_maps(f)

    with open(os.path.join(prepared_data_dir, "nm.json"), mode="r") as f:
        nm_files = json.load(f)

    symbol_table = {}
    for entry in maps.iter(executable_condition):
        if nm_files.has_key(entry.name):
            if nm_files[entry.name]["format"] == "bsd":
                with open(os.path.join(prepared_data_dir, nm_files[entry.name]["file"]), mode="r") as f:
                    symbol_table[entry.name] = get_procedure_boundaries_from_nm_bsd(f, nm_files[entry.name]["mangled"])

    for address in addresses:
        if isinstance(address, str):
            address = int(address, 16)
        is_found = False
        for entry in maps.iter(executable_condition):
            if entry.begin <= address < entry.end:
                if entry.name in symbol_table:
                    found = symbol_table[entry.name].find_procedure(address - (entry.begin - entry.offset))
                    outputter.output(address, found)
                else:
                    outputter.output(address)
                is_found = True
                break
        if not is_found:
            outputter.output(address)

    return 0
Exemple #3
0
  def _load_files(prepared_data_dir, maps_filename, files_filename):
    with open(os.path.join(prepared_data_dir, maps_filename), mode='r') as f:
      maps = parse_proc_maps(f)
    with open(os.path.join(prepared_data_dir, files_filename), mode='r') as f:
      files = json.load(f)

    symbol_tables = {}
    for entry in maps.iter(executable_condition):
      if entry.name in files:
        if 'nm' in files[entry.name]:
          nm_entry = files[entry.name]['nm']
          if nm_entry['format'] == 'bsd':
            with open(os.path.join(prepared_data_dir, nm_entry['file']),
                      mode='r') as f:
              symbol_tables[entry.name] = _get_static_symbols_from_nm_bsd(
                  f, nm_entry['mangled'])
        if 'readelf-e' in files:
          readelf_entry = files[entry.name]['readelf-e']
          # TODO(dmikurube) Implement it.

    return StaticSymbols(maps, symbol_tables)
def prepare_symbol_info(maps_path, output_dir_path=None, loglevel=logging.WARN):
  log = logging.getLogger('prepare_symbol_info')
  log.setLevel(loglevel)
  handler = logging.StreamHandler()
  handler.setLevel(loglevel)
  formatter = logging.Formatter('%(message)s')
  handler.setFormatter(formatter)
  log.addHandler(handler)

  if not output_dir_path:
    matched = re.match('^(.*)\.maps$', os.path.basename(maps_path))
    if matched:
      output_dir_path = matched.group(1) + '.pre'
  if not output_dir_path:
    matched = re.match('^/proc/(.*)/maps$', os.path.realpath(maps_path))
    if matched:
      output_dir_path = matched.group(1) + '.pre'
  if not output_dir_path:
    output_dir_prefix = os.path.basename(maps_path) + '.pre'
  # TODO(dmikurube): Find another candidate for output_dir_path.

  log.info('Data for profiling will be collected in "%s".' % output_dir_path)
  output_dir_path_exists = False
  if os.path.exists(output_dir_path):
    if os.path.isdir(output_dir_path) and not os.listdir(output_dir_path):
      log.warn('Using an empty directory existing at "%s".' % output_dir_path)
    else:
      log.warn('A file or a directory exists at "%s".' % output_dir_path)
      output_dir_path_exists = True
  else:
    log.info('Creating a new directory at "%s".' % output_dir_path)
    os.mkdir(output_dir_path)

  if output_dir_path_exists:
    return 1

  shutil.copyfile(maps_path, os.path.join(output_dir_path, 'maps'))

  with open(maps_path, mode='r') as f:
    maps = parse_proc_maps(f)

  log.debug('Listing up symbols.')
  nm_files = {}
  for entry in maps.iter(executable_condition):
    log.debug('  %016x-%016x +%06x %s' % (
        entry.begin, entry.end, entry.offset, entry.name))
    with tempfile.NamedTemporaryFile(
        prefix=os.path.basename(entry.name) + '.',
        suffix='.nm', delete=False, mode='w', dir=output_dir_path) as f:
      nm_filename = os.path.realpath(f.name)
      nm_succeeded = False
      cppfilt_succeeded = False
      p_nm = subprocess.Popen(
          'nm -n --format bsd %s' % entry.name, shell=True,
          stdout=subprocess.PIPE, stderr=subprocess.PIPE)
      p_cppfilt = subprocess.Popen(
          'c++filt', shell=True,
          stdin=p_nm.stdout, stdout=f, stderr=subprocess.PIPE)

      if p_nm.wait() == 0:
        nm_succeeded = True
      for line in p_nm.stderr:
        log.debug(line.rstrip())
      if p_cppfilt.wait() == 0:
        cppfilt_succeeded = True
      for line in p_cppfilt.stderr:
        log.debug(line.rstrip())

    if nm_succeeded and cppfilt_succeeded:
      nm_files[entry.name] = {
        'file': os.path.basename(nm_filename),
        'format': 'bsd',
        'mangled': False}
    else:
      os.remove(nm_filename)

  with open(os.path.join(output_dir_path, 'nm.json'), 'w') as f:
    json.dump(nm_files, f, indent=2, sort_keys=True)

  log.info('Collected symbol information at "%s".' % output_dir_path)
  return 0
Exemple #5
0
def prepare_symbol_info(maps_path, output_dir_path=None, loglevel=logging.WARN):
  log = logging.getLogger('prepare_symbol_info')
  log.setLevel(loglevel)
  handler = logging.StreamHandler()
  handler.setLevel(loglevel)
  formatter = logging.Formatter('%(message)s')
  handler.setFormatter(formatter)
  log.addHandler(handler)

  if not output_dir_path:
    matched = re.match('^(.*)\.maps$', os.path.basename(maps_path))
    if matched:
      output_dir_path = matched.group(1) + '.pre'
  if not output_dir_path:
    matched = re.match('^/proc/(.*)/maps$', os.path.realpath(maps_path))
    if matched:
      output_dir_path = matched.group(1) + '.pre'
  if not output_dir_path:
    output_dir_prefix = os.path.basename(maps_path) + '.pre'
  # TODO(dmikurube): Find another candidate for output_dir_path.

  log.info('Data for profiling will be collected in "%s".' % output_dir_path)
  output_dir_path_exists = False
  if os.path.exists(output_dir_path):
    if os.path.isdir(output_dir_path) and not os.listdir(output_dir_path):
      log.warn('Using an empty directory existing at "%s".' % output_dir_path)
    else:
      log.warn('A file or a directory exists at "%s".' % output_dir_path)
      output_dir_path_exists = True
  else:
    log.info('Creating a new directory at "%s".' % output_dir_path)
    os.mkdir(output_dir_path)

  if output_dir_path_exists:
    return 1

  shutil.copyfile(maps_path, os.path.join(output_dir_path, 'maps'))

  with open(maps_path, mode='r') as f:
    maps = parse_proc_maps(f)

  log.debug('Listing up symbols.')
  files = {}
  for entry in maps.iter(executable_condition):
    log.debug('  %016x-%016x +%06x %s' % (
        entry.begin, entry.end, entry.offset, entry.name))
    nm_filename = _dump_command_result(
        'nm -n --format bsd %s | c++filt' % entry.name,
        output_dir_path, os.path.basename(entry.name), '.nm', log)
    if not nm_filename:
      continue
    readelf_e_filename = _dump_command_result(
        'readelf -e %s' % entry.name,
        output_dir_path, os.path.basename(entry.name), '.readelf-e', log)
    if not readelf_e_filename:
      continue

    files[entry.name] = {}
    files[entry.name]['nm'] = {
        'file': os.path.basename(nm_filename),
        'format': 'bsd',
        'mangled': False}
    files[entry.name]['readelf-e'] = {
        'file': os.path.basename(readelf_e_filename)}

  with open(os.path.join(output_dir_path, 'files.json'), 'w') as f:
    json.dump(files, f, indent=2, sort_keys=True)

  log.info('Collected symbol information at "%s".' % output_dir_path)
  return 0