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