main.py revision 8666:97d873b8b13e
1# Copyright (c) 2005 The Regents of The University of Michigan 2# All rights reserved. 3# 4# Redistribution and use in source and binary forms, with or without 5# modification, are permitted provided that the following conditions are 6# met: redistributions of source code must retain the above copyright 7# notice, this list of conditions and the following disclaimer; 8# redistributions in binary form must reproduce the above copyright 9# notice, this list of conditions and the following disclaimer in the 10# documentation and/or other materials provided with the distribution; 11# neither the name of the copyright holders nor the names of its 12# contributors may be used to endorse or promote products derived from 13# this software without specific prior written permission. 14# 15# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26# 27# Authors: Nathan Binkert 28 29import code 30import datetime 31import os 32import socket 33import sys 34 35__all__ = [ 'options', 'arguments', 'main' ] 36 37usage="%prog [gem5 options] script.py [script options]" 38version="%prog 2.0" 39brief_copyright=\ 40 "gem5 is copyrighted software; use the --copyright option for details." 41 42def parse_options(): 43 import config 44 from options import OptionParser 45 46 options = OptionParser(usage=usage, version=version, 47 description=brief_copyright) 48 option = options.add_option 49 group = options.set_group 50 51 # Help options 52 option('-B', "--build-info", action="store_true", default=False, 53 help="Show build information") 54 option('-C', "--copyright", action="store_true", default=False, 55 help="Show full copyright information") 56 option('-R', "--readme", action="store_true", default=False, 57 help="Show the readme") 58 59 # Options for configuring the base simulator 60 option('-d', "--outdir", metavar="DIR", default="m5out", 61 help="Set the output directory to DIR [Default: %default]") 62 option('-r', "--redirect-stdout", action="store_true", default=False, 63 help="Redirect stdout (& stderr, without -e) to file") 64 option('-e', "--redirect-stderr", action="store_true", default=False, 65 help="Redirect stderr to file") 66 option("--stdout-file", metavar="FILE", default="simout", 67 help="Filename for -r redirection [Default: %default]") 68 option("--stderr-file", metavar="FILE", default="simerr", 69 help="Filename for -e redirection [Default: %default]") 70 option('-i', "--interactive", action="store_true", default=False, 71 help="Invoke the interactive interpreter after running the script") 72 option("--pdb", action="store_true", default=False, 73 help="Invoke the python debugger before running the script") 74 option('-p', "--path", metavar="PATH[:PATH]", action='append', split=':', 75 help="Prepend PATH to the system path when invoking the script") 76 option('-q', "--quiet", action="count", default=0, 77 help="Reduce verbosity") 78 option('-v', "--verbose", action="count", default=0, 79 help="Increase verbosity") 80 81 # Statistics options 82 group("Statistics Options") 83 option("--stats-file", metavar="FILE", default="stats.txt", 84 help="Sets the output file for statistics [Default: %default]") 85 86 # Configuration Options 87 group("Configuration Options") 88 option("--dump-config", metavar="FILE", default="config.ini", 89 help="Dump configuration output file [Default: %default]") 90 option("--json-config", metavar="FILE", default="config.json", 91 help="Create JSON output of the configuration [Default: %default]") 92 93 # Debugging options 94 group("Debugging Options") 95 option("--debug-break", metavar="TIME[,TIME]", action='append', split=',', 96 help="Cycle to create a breakpoint") 97 option("--debug-help", action='store_true', 98 help="Print help on trace flags") 99 option("--debug-flags", metavar="FLAG[,FLAG]", action='append', split=',', 100 help="Sets the flags for tracing (-FLAG disables a flag)") 101 option("--remote-gdb-port", type='int', default=7000, 102 help="Remote gdb base port (set to 0 to disable listening)") 103 104 # Tracing options 105 group("Trace Options") 106 option("--trace-start", metavar="TIME", type='int', 107 help="Start tracing at TIME (must be in ticks)") 108 option("--trace-file", metavar="FILE", default="cout", 109 help="Sets the output file for tracing [Default: %default]") 110 option("--trace-ignore", metavar="EXPR", action='append', split=':', 111 help="Ignore EXPR sim objects") 112 113 # Help options 114 group("Help Options") 115 option("--list-sim-objects", action='store_true', default=False, 116 help="List all built-in SimObjects, their params and default values") 117 118 # load the options.py config file to allow people to set their own 119 # default options 120 options_file = config.get('options.py') 121 if options_file: 122 scope = { 'options' : options } 123 execfile(options_file, scope) 124 125 arguments = options.parse_args() 126 return options,arguments 127 128def interact(scope): 129 banner = "gem5 Interactive Console" 130 sys.argv = [] 131 try: 132 from IPython.Shell import IPShellEmbed 133 ipshell = IPShellEmbed(banner=banner,user_ns=scope) 134 ipshell() 135 except ImportError: 136 code.InteractiveConsole(scope).interact(banner) 137 138def main(*args): 139 import m5 140 141 import core 142 import debug 143 import defines 144 import event 145 import info 146 import stats 147 import trace 148 149 from util import fatal 150 151 if len(args) == 0: 152 options, arguments = parse_options() 153 elif len(args) == 2: 154 options, arguments = args 155 else: 156 raise TypeError, "main() takes 0 or 2 arguments (%d given)" % len(args) 157 158 m5.options = options 159 160 def check_tracing(): 161 if defines.TRACING_ON: 162 return 163 164 fatal("Tracing is not enabled. Compile with TRACING_ON") 165 166 if not os.path.isdir(options.outdir): 167 os.makedirs(options.outdir) 168 169 # These filenames are used only if the redirect_std* options are set 170 stdout_file = os.path.join(options.outdir, options.stdout_file) 171 stderr_file = os.path.join(options.outdir, options.stderr_file) 172 173 # Print redirection notices here before doing any redirection 174 if options.redirect_stdout and not options.redirect_stderr: 175 print "Redirecting stdout and stderr to", stdout_file 176 else: 177 if options.redirect_stdout: 178 print "Redirecting stdout to", stdout_file 179 if options.redirect_stderr: 180 print "Redirecting stderr to", stderr_file 181 182 # Now redirect stdout/stderr as desired 183 if options.redirect_stdout: 184 redir_fd = os.open(stdout_file, os. O_WRONLY | os.O_CREAT | os.O_TRUNC) 185 os.dup2(redir_fd, sys.stdout.fileno()) 186 if not options.redirect_stderr: 187 os.dup2(redir_fd, sys.stderr.fileno()) 188 189 if options.redirect_stderr: 190 redir_fd = os.open(stderr_file, os. O_WRONLY | os.O_CREAT | os.O_TRUNC) 191 os.dup2(redir_fd, sys.stderr.fileno()) 192 193 done = False 194 195 if options.build_info: 196 done = True 197 print 'Build information:' 198 print 199 print 'compiled %s' % defines.compileDate; 200 print 'build options:' 201 keys = defines.buildEnv.keys() 202 keys.sort() 203 for key in keys: 204 val = defines.buildEnv[key] 205 print ' %s = %s' % (key, val) 206 print 207 208 if options.copyright: 209 done = True 210 print info.COPYING 211 print 212 213 if options.readme: 214 done = True 215 print 'Readme:' 216 print 217 print info.README 218 print 219 220 if options.debug_help: 221 done = True 222 check_tracing() 223 debug.help() 224 225 if options.list_sim_objects: 226 import SimObject 227 done = True 228 print "SimObjects:" 229 objects = SimObject.allClasses.keys() 230 objects.sort() 231 for name in objects: 232 obj = SimObject.allClasses[name] 233 print " %s" % obj 234 params = obj._params.keys() 235 params.sort() 236 for pname in params: 237 param = obj._params[pname] 238 default = getattr(param, 'default', '') 239 print " %s" % pname 240 if default: 241 print " default: %s" % default 242 print " desc: %s" % param.desc 243 print 244 print 245 246 if done: 247 sys.exit(0) 248 249 # setting verbose and quiet at the same time doesn't make sense 250 if options.verbose > 0 and options.quiet > 0: 251 options.usage(2) 252 253 verbose = options.verbose - options.quiet 254 if options.verbose >= 0: 255 print "gem5 Simulator System. http://gem5.org" 256 print brief_copyright 257 print 258 259 print "gem5 compiled %s" % defines.compileDate; 260 261 print "gem5 started %s" % \ 262 datetime.datetime.now().strftime("%b %e %Y %X") 263 print "gem5 executing on %s" % socket.gethostname() 264 265 print "command line:", 266 for argv in sys.argv: 267 print argv, 268 print 269 270 # check to make sure we can find the listed script 271 if not arguments or not os.path.isfile(arguments[0]): 272 if arguments and not os.path.isfile(arguments[0]): 273 print "Script %s not found" % arguments[0] 274 275 options.usage(2) 276 277 # tell C++ about output directory 278 core.setOutputDir(options.outdir) 279 280 # update the system path with elements from the -p option 281 sys.path[0:0] = options.path 282 283 # set stats options 284 stats.initText(options.stats_file) 285 286 # set debugging options 287 debug.setRemoteGDBPort(options.remote_gdb_port) 288 for when in options.debug_break: 289 debug.schedBreakCycle(int(when)) 290 291 if options.debug_flags: 292 check_tracing() 293 294 on_flags = [] 295 off_flags = [] 296 for flag in options.debug_flags: 297 off = False 298 if flag.startswith('-'): 299 flag = flag[1:] 300 off = True 301 302 if flag not in debug.flags: 303 print >>sys.stderr, "invalid debug flag '%s'" % flag 304 sys.exit(1) 305 306 if off: 307 debug.flags[flag].disable() 308 else: 309 debug.flags[flag].enable() 310 311 if options.trace_start: 312 check_tracing() 313 e = event.create(trace.enable, event.Event.Trace_Enable_Pri) 314 event.mainq.schedule(e, options.trace_start) 315 else: 316 trace.enable() 317 318 trace.output(options.trace_file) 319 320 for ignore in options.trace_ignore: 321 check_tracing() 322 trace.ignore(ignore) 323 324 sys.argv = arguments 325 sys.path = [ os.path.dirname(sys.argv[0]) ] + sys.path 326 327 filename = sys.argv[0] 328 filedata = file(filename, 'r').read() 329 filecode = compile(filedata, filename, 'exec') 330 scope = { '__file__' : filename, 331 '__name__' : '__m5_main__' } 332 333 # we want readline if we're doing anything interactive 334 if options.interactive or options.pdb: 335 exec "import readline" in scope 336 337 # if pdb was requested, execfile the thing under pdb, otherwise, 338 # just do the execfile normally 339 if options.pdb: 340 import pdb 341 import traceback 342 343 pdb = pdb.Pdb() 344 try: 345 pdb.run(filecode, scope) 346 except SystemExit: 347 print "The program exited via sys.exit(). Exit status: ", 348 print sys.exc_info()[1] 349 except: 350 traceback.print_exc() 351 print "Uncaught exception. Entering post mortem debugging" 352 t = sys.exc_info()[2] 353 while t.tb_next is not None: 354 t = t.tb_next 355 pdb.interaction(t.tb_frame,t) 356 else: 357 exec filecode in scope 358 359 # once the script is done 360 if options.interactive: 361 interact(scope) 362 363if __name__ == '__main__': 364 from pprint import pprint 365 366 options, arguments = parse_options() 367 368 print 'opts:' 369 pprint(options, indent=4) 370 print 371 372 print 'args:' 373 pprint(arguments, indent=4) 374