1#!/usr/bin/env python
2# Copyright 2014 The Chromium Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6"""Simple mock for addr2line.
7
8Outputs mock symbol information, with each symbol being a function of the
9original address (so it is easy to double-check consistency in unittests).
10"""
11
12import optparse
13import os
14import posixpath
15import sys
16import time
17
18
19def main(argv):
20  parser = optparse.OptionParser()
21  parser.add_option('-e', '--exe', dest='exe')  # Path of the debug-library.so.
22  # Silently swallow the other unnecessary arguments.
23  parser.add_option('-C', '--demangle', action='store_true')
24  parser.add_option('-f', '--functions', action='store_true')
25  parser.add_option('-i', '--inlines', action='store_true')
26  options, _ = parser.parse_args(argv[1:])
27  lib_file_name = posixpath.basename(options.exe)
28  processed_sym_count = 0
29  crash_every = int(os.environ.get('MOCK_A2L_CRASH_EVERY', 0))
30  hang_every = int(os.environ.get('MOCK_A2L_HANG_EVERY', 0))
31
32  while(True):
33    line = sys.stdin.readline().rstrip('\r')
34    if not line:
35      break
36
37    # An empty line should generate '??,??:0' (is used as marker for inlines).
38    if line == '\n':
39      print '??'
40      print '??:0'
41      sys.stdout.flush()
42      continue
43
44    addr = int(line, 16)
45    processed_sym_count += 1
46    if crash_every and processed_sym_count % crash_every == 0:
47      sys.exit(1)
48    if hang_every and processed_sym_count % hang_every == 0:
49      time.sleep(1)
50
51    # Addresses < 1M will return good mock symbol information.
52    if addr < 1024 * 1024:
53      print 'mock_sym_for_addr_%d' % addr
54      print 'mock_src/%s.c:%d' % (lib_file_name, addr)
55
56    # Addresses 1M <= x < 2M will return symbols with a name but a missing path.
57    elif addr < 2 * 1024 * 1024:
58      print 'mock_sym_for_addr_%d' % addr
59      print '??:0'
60
61    # Addresses 2M <= x < 3M will return unknown symbol information.
62    elif addr < 3 * 1024 * 1024:
63      print '??'
64      print '??'
65
66    # Addresses 3M <= x < 4M will return inlines.
67    elif addr < 4 * 1024 * 1024:
68      print 'mock_sym_for_addr_%d_inner' % addr
69      print 'mock_src/%s.c:%d' % (lib_file_name, addr)
70      print 'mock_sym_for_addr_%d_middle' % addr
71      print 'mock_src/%s.c:%d' % (lib_file_name, addr)
72      print 'mock_sym_for_addr_%d_outer' % addr
73      print 'mock_src/%s.c:%d' % (lib_file_name, addr)
74
75    sys.stdout.flush()
76
77
78if __name__ == '__main__':
79  main(sys.argv)