statetrace.cc revision 3115
14679Sgblack@eecs.umich.edu/* 24679Sgblack@eecs.umich.edu * Copyright (c) 2006 The Regents of The University of Michigan 34679Sgblack@eecs.umich.edu * All rights reserved. 44679Sgblack@eecs.umich.edu * 54679Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 64679Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 74679Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 84679Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 94679Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 104679Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 114679Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 124679Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 134679Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 144679Sgblack@eecs.umich.edu * this software without specific prior written permission. 154679Sgblack@eecs.umich.edu * 164679Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 174679Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 184679Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 194679Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 204679Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 214679Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 224679Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 234679Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 244679Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 254679Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 264679Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 274679Sgblack@eecs.umich.edu * 284679Sgblack@eecs.umich.edu * Authors: Gabe Black 294679Sgblack@eecs.umich.edu */ 304679Sgblack@eecs.umich.edu 314679Sgblack@eecs.umich.edu#include <iostream> 324679Sgblack@eecs.umich.edu#include <fstream> 334679Sgblack@eecs.umich.edu#include <string> 344679Sgblack@eecs.umich.edu#include <sys/types.h> 354679Sgblack@eecs.umich.edu#include <sys/wait.h> 364679Sgblack@eecs.umich.edu#include <sys/ptrace.h> 374679Sgblack@eecs.umich.edu#include <unistd.h> 384679Sgblack@eecs.umich.edu 394679Sgblack@eecs.umich.edu#include "tracechild.hh" 404679Sgblack@eecs.umich.edu#include "printer.hh" 414679Sgblack@eecs.umich.edu 424679Sgblack@eecs.umich.eduusing namespace std; 434679Sgblack@eecs.umich.edu 444679Sgblack@eecs.umich.eduvoid printUsage(const char * execName) 454679Sgblack@eecs.umich.edu{ 464679Sgblack@eecs.umich.edu cout << execName << " -f <output format file> | -h | -r -- <command> <arguments>" << endl; 474679Sgblack@eecs.umich.edu} 484679Sgblack@eecs.umich.edu 494679Sgblack@eecs.umich.eduint main(int argc, char * argv[], char * envp[]) 504679Sgblack@eecs.umich.edu{ 514679Sgblack@eecs.umich.edu TraceChild * child = genTraceChild(); 524679Sgblack@eecs.umich.edu NestingPrinter printer(child); 534679Sgblack@eecs.umich.edu string args; 544679Sgblack@eecs.umich.edu int startProgramArgs; 554679Sgblack@eecs.umich.edu 564679Sgblack@eecs.umich.edu //Parse the command line arguments 574679Sgblack@eecs.umich.edu bool formatStringSet = false; 584679Sgblack@eecs.umich.edu bool printInitial = false; 594679Sgblack@eecs.umich.edu bool printTrace = true; 604679Sgblack@eecs.umich.edu string format; 614679Sgblack@eecs.umich.edu for(int x = 1; x < argc; x++) 624679Sgblack@eecs.umich.edu { 634679Sgblack@eecs.umich.edu if(!strcmp(argv[x], "-f")) 644679Sgblack@eecs.umich.edu { 654688Sgblack@eecs.umich.edu if(formatStringSet) 664688Sgblack@eecs.umich.edu { 674688Sgblack@eecs.umich.edu cerr << "Attempted to set format twice!" 684688Sgblack@eecs.umich.edu << endl; 694688Sgblack@eecs.umich.edu printUsage(argv[0]); 704688Sgblack@eecs.umich.edu return 1; 714688Sgblack@eecs.umich.edu } 724688Sgblack@eecs.umich.edu formatStringSet = true; 734688Sgblack@eecs.umich.edu x++; 744688Sgblack@eecs.umich.edu if(x >= argc) 754688Sgblack@eecs.umich.edu { 764688Sgblack@eecs.umich.edu cerr << "Incorrect usage.\n" << endl; 774688Sgblack@eecs.umich.edu printUsage(argv[0]); 784688Sgblack@eecs.umich.edu return 1; 794688Sgblack@eecs.umich.edu } 804688Sgblack@eecs.umich.edu ifstream formatFile(argv[x]); 814688Sgblack@eecs.umich.edu if(!formatFile) 824688Sgblack@eecs.umich.edu { 834688Sgblack@eecs.umich.edu cerr << "Problem opening file " 844688Sgblack@eecs.umich.edu << argv[x] << "." << endl; 854688Sgblack@eecs.umich.edu return 1; 864688Sgblack@eecs.umich.edu } 874688Sgblack@eecs.umich.edu format = ""; 884688Sgblack@eecs.umich.edu while(formatFile) 894688Sgblack@eecs.umich.edu { 904688Sgblack@eecs.umich.edu string line; 914688Sgblack@eecs.umich.edu getline(formatFile, line); 924688Sgblack@eecs.umich.edu if(formatFile.eof()) 934688Sgblack@eecs.umich.edu { 944688Sgblack@eecs.umich.edu format += line; 954688Sgblack@eecs.umich.edu break; 964688Sgblack@eecs.umich.edu } 974688Sgblack@eecs.umich.edu if(!formatFile) 984688Sgblack@eecs.umich.edu { 994688Sgblack@eecs.umich.edu cerr << "Problem reading from file " 1004688Sgblack@eecs.umich.edu << argv[x] << "." << endl; 1014688Sgblack@eecs.umich.edu return 1; 1024688Sgblack@eecs.umich.edu } 1034688Sgblack@eecs.umich.edu format += line + '\n'; 1044688Sgblack@eecs.umich.edu } 1054688Sgblack@eecs.umich.edu } 1064679Sgblack@eecs.umich.edu else if(!strcmp(argv[x], "-h")) 1074679Sgblack@eecs.umich.edu { 1084679Sgblack@eecs.umich.edu printUsage(argv[0]); 1094688Sgblack@eecs.umich.edu return 0; 1104679Sgblack@eecs.umich.edu } 1114679Sgblack@eecs.umich.edu else if(!strcmp(argv[x], "-r")) 1124679Sgblack@eecs.umich.edu { 1134688Sgblack@eecs.umich.edu cout << "Legal register names:" << endl; 1144688Sgblack@eecs.umich.edu int numRegs = child->getNumRegs(); 1154688Sgblack@eecs.umich.edu for(unsigned int x = 0; x < numRegs; x++) 1164688Sgblack@eecs.umich.edu { 1174688Sgblack@eecs.umich.edu cout << "\t" << child->getRegName(x) << endl; 1184688Sgblack@eecs.umich.edu } 1194688Sgblack@eecs.umich.edu return 0; 1204688Sgblack@eecs.umich.edu } 1214688Sgblack@eecs.umich.edu else if(!strcmp(argv[x], "-i")) 1224688Sgblack@eecs.umich.edu { 1234688Sgblack@eecs.umich.edu printInitial = true; 1244688Sgblack@eecs.umich.edu } 1254688Sgblack@eecs.umich.edu else if(!strcmp(argv[x], "-nt")) 1264688Sgblack@eecs.umich.edu { 1274688Sgblack@eecs.umich.edu printTrace = false; 1284688Sgblack@eecs.umich.edu } 1294688Sgblack@eecs.umich.edu else if(!strcmp(argv[x], "--")) 1304688Sgblack@eecs.umich.edu { 1314688Sgblack@eecs.umich.edu x++; 1324688Sgblack@eecs.umich.edu if(x >= argc) 1334688Sgblack@eecs.umich.edu { 1344688Sgblack@eecs.umich.edu cerr << "Incorrect usage.\n" << endl; 1354688Sgblack@eecs.umich.edu printUsage(argv[0]); 1364688Sgblack@eecs.umich.edu return 1; 1374688Sgblack@eecs.umich.edu } 1384688Sgblack@eecs.umich.edu startProgramArgs = x; 1394688Sgblack@eecs.umich.edu break; 1404688Sgblack@eecs.umich.edu } 1414688Sgblack@eecs.umich.edu else 1424679Sgblack@eecs.umich.edu { 1434679Sgblack@eecs.umich.edu cerr << "Incorrect usage.\n" << endl; 1444679Sgblack@eecs.umich.edu printUsage(argv[0]); 1454679Sgblack@eecs.umich.edu return 1; 1464679Sgblack@eecs.umich.edu } 1474679Sgblack@eecs.umich.edu } 1484679Sgblack@eecs.umich.edu for(unsigned int x = startProgramArgs; x < argc; x++) 1494679Sgblack@eecs.umich.edu args += argv[x]; 1504688Sgblack@eecs.umich.edu if(!child->startTracing(argv[startProgramArgs], args.c_str())) 1514679Sgblack@eecs.umich.edu { 1524688Sgblack@eecs.umich.edu cerr << "Couldn't start target program" << endl; 1534679Sgblack@eecs.umich.edu return 1; 1544688Sgblack@eecs.umich.edu } 1554679Sgblack@eecs.umich.edu if(printInitial) 1564688Sgblack@eecs.umich.edu { 1574679Sgblack@eecs.umich.edu child->outputStartState(cout); 1584679Sgblack@eecs.umich.edu } 1594679Sgblack@eecs.umich.edu if(printTrace) 1604679Sgblack@eecs.umich.edu { 1614679Sgblack@eecs.umich.edu if(!formatStringSet) 1624679Sgblack@eecs.umich.edu { 1634679Sgblack@eecs.umich.edu cerr << "No output format set!" << endl; 1644688Sgblack@eecs.umich.edu child->stopTracing(); 1654679Sgblack@eecs.umich.edu printUsage(argv[0]); 1664679Sgblack@eecs.umich.edu return 1; 1674679Sgblack@eecs.umich.edu } 1684679Sgblack@eecs.umich.edu if(!printer.configure(format)) 1694679Sgblack@eecs.umich.edu { 1704679Sgblack@eecs.umich.edu cerr << "Problem in the output format" << endl; 1714679Sgblack@eecs.umich.edu child->stopTracing(); 1724679Sgblack@eecs.umich.edu return 1; 1734679Sgblack@eecs.umich.edu } 1744679Sgblack@eecs.umich.edu child->step(); 1754688Sgblack@eecs.umich.edu while(child->isTracing()) 1764679Sgblack@eecs.umich.edu { 1774688Sgblack@eecs.umich.edu cout << printer; 1784679Sgblack@eecs.umich.edu child->step(); 1794688Sgblack@eecs.umich.edu } 1804679Sgblack@eecs.umich.edu cout << printer; 1814688Sgblack@eecs.umich.edu } 1824679Sgblack@eecs.umich.edu if(!child->stopTracing()) 1834679Sgblack@eecs.umich.edu { 1844679Sgblack@eecs.umich.edu cerr << "Couldn't stop child" << endl; 1854679Sgblack@eecs.umich.edu return 1; 1864679Sgblack@eecs.umich.edu } 1874679Sgblack@eecs.umich.edu return 0; 1884679Sgblack@eecs.umich.edu} 1894679Sgblack@eecs.umich.edu 1904679Sgblack@eecs.umich.edu