record-trace 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. #!/usr/bin/env python
  2. import sys, os, getopt, subprocess
  3. sys.path.append(os.path.join(os.path.dirname(__file__), 'tools'))
  4. import debugpin, run_sniper
  5. HOME = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0])))
  6. def usage():
  7. print 'Collect SIFT instruction trace'
  8. print 'Usage:'
  9. print ' %s -o <output file (default=trace)> [--roi] [-f <fast-forward instrs (default=none)] [-d <detailed instrs (default=all)] [-b <block size (instructions, default=all)> [-e <syscall emulation> (default=0)] [-r <use response files (default=0)>] [--gdb|--gdb-wait|--gdb-quit] [--follow] [--routine-tracing] [--outputdir <outputdir (.)>] [--stop-address <insn end address>] { --pinball=<pinball-basename> | --pid <pid> | -- <cmdline> }' % sys.argv[0]
  10. sys.exit(2)
  11. # From http://stackoverflow.com/questions/6767649/how-to-get-process-status-using-pid
  12. def procStatus(pid):
  13. for line in open("/proc/%d/status" % pid).readlines():
  14. if line.startswith("State:"):
  15. return line.split(":",1)[1].strip().split(' ')[0]
  16. return None
  17. # From http://stackoverflow.com/questions/5568646/usleep-in-python
  18. import time
  19. usleep = lambda x: time.sleep(x/1000000.0)
  20. outputfile = 'trace'
  21. use_roi = False
  22. roi_mpi = False
  23. fastforward = 0
  24. detailed = 0
  25. blocksize = 0
  26. syscallemulation = 0
  27. siftcountoffset = 0
  28. useresponsefiles = 0
  29. use_gdb = False
  30. gdb_wait = False
  31. gdb_quit = False
  32. gdb_screen = False
  33. use_follow = False
  34. use_pa = False
  35. use_routine_tracing = False
  36. pinball = None
  37. pinplay_addrtrans = False
  38. outputdir = '.'
  39. verbose = False
  40. extra_args = []
  41. use_pid = None
  42. pid_continue = False
  43. stop_address = 0
  44. if not sys.argv[1:]:
  45. usage()
  46. try:
  47. opts, cmdline = getopt.getopt(sys.argv[1:], "hvo:d:f:b:e:s:r:X:", [ "roi", "roi-mpi", "gdb", "gdb-wait", "gdb-quit", "gdb-screen", "follow", "pa", "routine-tracing", "pinball=", "outputdir=", "pinplay-addr-trans", "pid=", "stop-address=", "pid-continue" ])
  48. except getopt.GetoptError, e:
  49. # print help information and exit:
  50. print e
  51. usage()
  52. for o, a in opts:
  53. if o == '-h':
  54. usage()
  55. sys.exit()
  56. if o == '-v':
  57. verbose = True
  58. if o == '-o':
  59. outputfile = a
  60. if o == '--roi':
  61. use_roi = True
  62. if o == '--roi-mpi':
  63. roi_mpi = True
  64. if o == '-f':
  65. fastforward = long(float(a))
  66. if o == '-d':
  67. detailed = long(float(a))
  68. if o == '-b':
  69. blocksize = long(float(a))
  70. if o == '-e':
  71. syscallemulation = long(float(a))
  72. if o == '-s':
  73. siftcountoffset = long(float(a))
  74. if o == '-r':
  75. useresponsefiles = int(a) and 1 or 0
  76. if o == '--gdb':
  77. use_gdb = True
  78. if o == '--gdb-wait':
  79. use_gdb = True
  80. gdb_wait = True
  81. if o == '--gdb-quit':
  82. use_gdb = True
  83. gdb_wait = False
  84. gdb_quit = True
  85. if o == '--gdb-screen':
  86. gdb_screen = 1
  87. if o == '--pinplay-addr-trans':
  88. pinplay_addrtrans = True
  89. if o == '--follow':
  90. use_follow = True
  91. if o == '--pa':
  92. use_pa = True
  93. if o == '--routine-tracing':
  94. use_routine_tracing = True
  95. if o == '--pinball':
  96. if not os.path.exists('%s.address' % a):
  97. print >> sys.stderr, 'Unable to locate a pinball at (%s), make sure that (%s.address) exists.' % (a, a)
  98. sys.exit(1)
  99. pinball = a
  100. if o == '--outputdir':
  101. outputdir = a
  102. if o == '-X':
  103. extra_args.append(a)
  104. if o == '--pid':
  105. use_pid = int(a)
  106. if o == '--stop-address':
  107. stop_address = int(a,0)
  108. if o == '--pid-continue':
  109. pid_continue = True
  110. outputdir = os.path.realpath(outputdir)
  111. if not os.path.exists(outputdir):
  112. try:
  113. os.makedirs(outputdir)
  114. except OSError:
  115. print >> sys.stderr, 'Failed to create output directory', outputdir
  116. sys.exit(-1)
  117. configfile = os.path.join(HOME, 'config/sniper.py')
  118. config = {}
  119. execfile(configfile, {}, config)
  120. arch = config.get('target', 'intel64')
  121. # convert paths in config to absolute paths
  122. for d in ('pin_home',):
  123. absdir = os.path.join(HOME, config[d])
  124. if not os.path.isdir(absdir):
  125. sys.stderr.write('Cannot find %s %s, please check %s\n' % (d, absdir, configfile))
  126. sys.exit(-1)
  127. exec "%s = '%s'" % (d, absdir)
  128. sim_root = HOME
  129. # convert to absolute path
  130. outputfile = os.path.realpath(os.path.join(outputfile))
  131. pinoptions = '-mt -injection child -xyzzy -enable_vsm 0'
  132. if use_pid:
  133. pinoptions += (' -pid %d' % (use_pid))
  134. if use_gdb:
  135. pinoptions += ' -pause_tool 1'
  136. if use_follow:
  137. pinoptions += ' -follow_execv'
  138. pinballoptions = ''
  139. if pinball:
  140. pinballoptions += '-replay -replay:basename "%s" -pinplay:msgfile "%s" -replay:resultfile "%s"' % (pinball, os.path.join(outputdir,'pinball_replay.app%d' % siftcountoffset), os.path.join(outputdir,'pinball_result.app%d' % siftcountoffset))
  141. if pinplay_addrtrans:
  142. pinballoptions += " -replay:addr_trans"
  143. else:
  144. pinoptions += ' -xyzzy -reserve_memory "%s.address"' % pinball
  145. # Replace the command line with the null app for use with PinPlay
  146. cmdline = ['%(pin_home)s/extras/pinplay/bin/%(arch)s/nullapp' % locals()]
  147. env = run_sniper.setup_env(HOME, pin_home, arch)
  148. value_roi = use_roi and 1 or 0
  149. value_roi_mpi = roi_mpi and 1 or 0
  150. value_pa = use_pa and 1 or 0
  151. value_routine_tracing = use_routine_tracing and 1 or 0
  152. value_verbose = verbose and 1 or 0
  153. extra_args = ' '.join(extra_args)
  154. cmd = '%(pin_home)s/%(arch)s/bin/pinbin %(pinoptions)s -t %(HOME)s/sift/recorder/sift_recorder -verbose %(value_verbose)d -debug %(gdb_screen)d -roi %(value_roi)d -roi-mpi %(value_roi_mpi)d -f %(fastforward)d -d %(detailed)d -b %(blocksize)d -o %(outputfile)s -e %(syscallemulation)d -s %(siftcountoffset)d -r %(useresponsefiles)d -pa %(value_pa)d -rtntrace %(value_routine_tracing)d -stop %(stop_address)d %(pinballoptions)s %(extra_args)s -- ' % locals() + ' '.join(cmdline)
  155. if verbose:
  156. print '[SIFT_RECORDER]', 'Running', cmd
  157. sys.stdout.flush()
  158. if use_gdb:
  159. debugpin.execute_gdb(cmd = cmd, env = env, pin_home = pin_home, arch = arch, quiet = True, wait = gdb_wait, quit = gdb_quit)
  160. else:
  161. subproc = subprocess.Popen([ 'bash', '-c', cmd ], env = env)
  162. if use_pid and pid_continue:
  163. import signal
  164. while procStatus(use_pid).strip() != 'T':
  165. usleep(100)
  166. os.kill(use_pid, signal.SIGCONT)
  167. pid, rc, usage = os.wait4(subproc.pid, 0)