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