main.py revision 11161
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 option("--dot-config", metavar="FILE", default="config.dot", 93 help="Create DOT & pdf outputs of the configuration [Default: %default]") 94 95 # Debugging options 96 group("Debugging Options") 97 option("--debug-break", metavar="TIME[,TIME]", action='append', split=',', 98 help="Tick to create a breakpoint") 99 option("--debug-help", action='store_true', 100 help="Print help on debug flags") 101 option("--debug-flags", metavar="FLAG[,FLAG]", action='append', split=',', 102 help="Sets the flags for debug output (-FLAG disables a flag)") 103 option("--debug-start", metavar="TIME", type='int', 104 help="Start debug output at TIME (must be in ticks)") 105 option("--debug-file", metavar="FILE", default="cout", 106 help="Sets the output file for debug [Default: %default]") 107 option("--debug-ignore", metavar="EXPR", action='append', split=':', 108 help="Ignore EXPR sim objects") 109 option("--remote-gdb-port", type='int', default=7000, 110 help="Remote gdb base port (set to 0 to disable listening)") 111 112 # Help options 113 group("Help Options") 114 option("--list-sim-objects", action='store_true', default=False, 115 help="List all built-in SimObjects, their params and default values") 116 117 # load the options.py config file to allow people to set their own 118 # default options 119 options_file = config.get('options.py') 120 if options_file: 121 scope = { 'options' : options } 122 execfile(options_file, scope) 123 124 arguments = options.parse_args() 125 return options,arguments 126 127def interact(scope): 128 banner = "gem5 Interactive Console" 129 130 ipshell = None 131 prompt_in1 = "gem5 \\#> " 132 prompt_out = "gem5 \\#: " 133 134 # Is IPython version 0.10 or earlier available? 135 try: 136 from IPython.Shell import IPShellEmbed 137 ipshell = IPShellEmbed(argv=["-prompt_in1", prompt_in1, 138 "-prompt_out", prompt_out], 139 banner=banner, user_ns=scope) 140 except ImportError: 141 pass 142 143 # Is IPython version 0.11 or later available? 144 if not ipshell: 145 try: 146 import IPython 147 from IPython.config.loader import Config 148 from IPython.frontend.terminal.embed import InteractiveShellEmbed 149 150 cfg = Config() 151 cfg.PromptManager.in_template = prompt_in1 152 cfg.PromptManager.out_template = prompt_out 153 ipshell = InteractiveShellEmbed(config=cfg, user_ns=scope, 154 banner1=banner) 155 except ImportError: 156 pass 157 158 if ipshell: 159 ipshell() 160 else: 161 # Use the Python shell in the standard library if IPython 162 # isn't available. 163 code.InteractiveConsole(scope).interact(banner) 164 165def main(*args): 166 import m5 167 168 import core 169 import debug 170 import defines 171 import event 172 import info 173 import stats 174 import trace 175 176 from util import fatal 177 178 if len(args) == 0: 179 options, arguments = parse_options() 180 elif len(args) == 2: 181 options, arguments = args 182 else: 183 raise TypeError, "main() takes 0 or 2 arguments (%d given)" % len(args) 184 185 m5.options = options 186 187 def check_tracing(): 188 if defines.TRACING_ON: 189 return 190 191 fatal("Tracing is not enabled. Compile with TRACING_ON") 192 193 # Set the main event queue for the main thread. 194 event.mainq = event.getEventQueue(0) 195 event.setEventQueue(event.mainq) 196 197 if not os.path.isdir(options.outdir): 198 os.makedirs(options.outdir) 199 200 # These filenames are used only if the redirect_std* options are set 201 stdout_file = os.path.join(options.outdir, options.stdout_file) 202 stderr_file = os.path.join(options.outdir, options.stderr_file) 203 204 # Print redirection notices here before doing any redirection 205 if options.redirect_stdout and not options.redirect_stderr: 206 print "Redirecting stdout and stderr to", stdout_file 207 else: 208 if options.redirect_stdout: 209 print "Redirecting stdout to", stdout_file 210 if options.redirect_stderr: 211 print "Redirecting stderr to", stderr_file 212 213 # Now redirect stdout/stderr as desired 214 if options.redirect_stdout: 215 redir_fd = os.open(stdout_file, os. O_WRONLY | os.O_CREAT | os.O_TRUNC) 216 os.dup2(redir_fd, sys.stdout.fileno()) 217 if not options.redirect_stderr: 218 os.dup2(redir_fd, sys.stderr.fileno()) 219 220 if options.redirect_stderr: 221 redir_fd = os.open(stderr_file, os. O_WRONLY | os.O_CREAT | os.O_TRUNC) 222 os.dup2(redir_fd, sys.stderr.fileno()) 223 224 done = False 225 226 if options.build_info: 227 done = True 228 print 'Build information:' 229 print 230 print 'compiled %s' % defines.compileDate; 231 print 'build options:' 232 keys = defines.buildEnv.keys() 233 keys.sort() 234 for key in keys: 235 val = defines.buildEnv[key] 236 print ' %s = %s' % (key, val) 237 print 238 239 if options.copyright: 240 done = True 241 print info.COPYING 242 print 243 244 if options.readme: 245 done = True 246 print 'Readme:' 247 print 248 print info.README 249 print 250 251 if options.debug_help: 252 done = True 253 check_tracing() 254 debug.help() 255 256 if options.list_sim_objects: 257 import SimObject 258 done = True 259 print "SimObjects:" 260 objects = SimObject.allClasses.keys() 261 objects.sort() 262 for name in objects: 263 obj = SimObject.allClasses[name] 264 print " %s" % obj 265 params = obj._params.keys() 266 params.sort() 267 for pname in params: 268 param = obj._params[pname] 269 default = getattr(param, 'default', '') 270 print " %s" % pname 271 if default: 272 print " default: %s" % default 273 print " desc: %s" % param.desc 274 print 275 print 276 277 if done: 278 sys.exit(0) 279 280 # setting verbose and quiet at the same time doesn't make sense 281 if options.verbose > 0 and options.quiet > 0: 282 options.usage(2) 283 284 verbose = options.verbose - options.quiet 285 if verbose >= 0: 286 print "gem5 Simulator System. http://gem5.org" 287 print brief_copyright 288 print 289 290 print "gem5 compiled %s" % defines.compileDate; 291 292 print "gem5 started %s" % \ 293 datetime.datetime.now().strftime("%b %e %Y %X") 294 print "gem5 executing on %s, pid %d" % \ 295 (socket.gethostname(), os.getpid()) 296 297 # in Python 3 pipes.quote() is moved to shlex.quote() 298 import pipes 299 print "command line:", " ".join(map(pipes.quote, sys.argv)) 300 print 301 302 # check to make sure we can find the listed script 303 if not arguments or not os.path.isfile(arguments[0]): 304 if arguments and not os.path.isfile(arguments[0]): 305 print "Script %s not found" % arguments[0] 306 307 options.usage(2) 308 309 # tell C++ about output directory 310 core.setOutputDir(options.outdir) 311 312 # update the system path with elements from the -p option 313 sys.path[0:0] = options.path 314 315 # set stats options 316 stats.initText(options.stats_file) 317 318 # set debugging options 319 debug.setRemoteGDBPort(options.remote_gdb_port) 320 for when in options.debug_break: 321 debug.schedBreak(int(when)) 322 323 if options.debug_flags: 324 check_tracing() 325 326 on_flags = [] 327 off_flags = [] 328 for flag in options.debug_flags: 329 off = False 330 if flag.startswith('-'): 331 flag = flag[1:] 332 off = True 333 334 if flag not in debug.flags: 335 print >>sys.stderr, "invalid debug flag '%s'" % flag 336 sys.exit(1) 337 338 if off: 339 debug.flags[flag].disable() 340 else: 341 debug.flags[flag].enable() 342 343 if options.debug_start: 344 check_tracing() 345 e = event.create(trace.enable, event.Event.Debug_Enable_Pri) 346 event.mainq.schedule(e, options.debug_start) 347 else: 348 trace.enable() 349 350 trace.output(options.debug_file) 351 352 for ignore in options.debug_ignore: 353 check_tracing() 354 trace.ignore(ignore) 355 356 sys.argv = arguments 357 sys.path = [ os.path.dirname(sys.argv[0]) ] + sys.path 358 359 filename = sys.argv[0] 360 filedata = file(filename, 'r').read() 361 filecode = compile(filedata, filename, 'exec') 362 scope = { '__file__' : filename, 363 '__name__' : '__m5_main__' } 364 365 # we want readline if we're doing anything interactive 366 if options.interactive or options.pdb: 367 exec "import readline" in scope 368 369 # if pdb was requested, execfile the thing under pdb, otherwise, 370 # just do the execfile normally 371 if options.pdb: 372 import pdb 373 import traceback 374 375 pdb = pdb.Pdb() 376 try: 377 pdb.run(filecode, scope) 378 except SystemExit: 379 print "The program exited via sys.exit(). Exit status: ", 380 print sys.exc_info()[1] 381 except: 382 traceback.print_exc() 383 print "Uncaught exception. Entering post mortem debugging" 384 t = sys.exc_info()[2] 385 while t.tb_next is not None: 386 t = t.tb_next 387 pdb.interaction(t.tb_frame,t) 388 else: 389 exec filecode in scope 390 391 # once the script is done 392 if options.interactive: 393 interact(scope) 394 395if __name__ == '__main__': 396 from pprint import pprint 397 398 options, arguments = parse_options() 399 400 print 'opts:' 401 pprint(options, indent=4) 402 print 403 404 print 'args:' 405 pprint(arguments, indent=4) 406