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