statetrace.cc revision 3115
1/* 2 * Copyright (c) 2006 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Authors: Gabe Black 29 */ 30 31#include <iostream> 32#include <fstream> 33#include <string> 34#include <sys/types.h> 35#include <sys/wait.h> 36#include <sys/ptrace.h> 37#include <unistd.h> 38 39#include "tracechild.hh" 40#include "printer.hh" 41 42using namespace std; 43 44void printUsage(const char * execName) 45{ 46 cout << execName << " -f <output format file> | -h | -r -- <command> <arguments>" << endl; 47} 48 49int main(int argc, char * argv[], char * envp[]) 50{ 51 TraceChild * child = genTraceChild(); 52 NestingPrinter printer(child); 53 string args; 54 int startProgramArgs; 55 56 //Parse the command line arguments 57 bool formatStringSet = false; 58 bool printInitial = false; 59 bool printTrace = true; 60 string format; 61 for(int x = 1; x < argc; x++) 62 { 63 if(!strcmp(argv[x], "-f")) 64 { 65 if(formatStringSet) 66 { 67 cerr << "Attempted to set format twice!" 68 << endl; 69 printUsage(argv[0]); 70 return 1; 71 } 72 formatStringSet = true; 73 x++; 74 if(x >= argc) 75 { 76 cerr << "Incorrect usage.\n" << endl; 77 printUsage(argv[0]); 78 return 1; 79 } 80 ifstream formatFile(argv[x]); 81 if(!formatFile) 82 { 83 cerr << "Problem opening file " 84 << argv[x] << "." << endl; 85 return 1; 86 } 87 format = ""; 88 while(formatFile) 89 { 90 string line; 91 getline(formatFile, line); 92 if(formatFile.eof()) 93 { 94 format += line; 95 break; 96 } 97 if(!formatFile) 98 { 99 cerr << "Problem reading from file " 100 << argv[x] << "." << endl; 101 return 1; 102 } 103 format += line + '\n'; 104 } 105 } 106 else if(!strcmp(argv[x], "-h")) 107 { 108 printUsage(argv[0]); 109 return 0; 110 } 111 else if(!strcmp(argv[x], "-r")) 112 { 113 cout << "Legal register names:" << endl; 114 int numRegs = child->getNumRegs(); 115 for(unsigned int x = 0; x < numRegs; x++) 116 { 117 cout << "\t" << child->getRegName(x) << endl; 118 } 119 return 0; 120 } 121 else if(!strcmp(argv[x], "-i")) 122 { 123 printInitial = true; 124 } 125 else if(!strcmp(argv[x], "-nt")) 126 { 127 printTrace = false; 128 } 129 else if(!strcmp(argv[x], "--")) 130 { 131 x++; 132 if(x >= argc) 133 { 134 cerr << "Incorrect usage.\n" << endl; 135 printUsage(argv[0]); 136 return 1; 137 } 138 startProgramArgs = x; 139 break; 140 } 141 else 142 { 143 cerr << "Incorrect usage.\n" << endl; 144 printUsage(argv[0]); 145 return 1; 146 } 147 } 148 for(unsigned int x = startProgramArgs; x < argc; x++) 149 args += argv[x]; 150 if(!child->startTracing(argv[startProgramArgs], args.c_str())) 151 { 152 cerr << "Couldn't start target program" << endl; 153 return 1; 154 } 155 if(printInitial) 156 { 157 child->outputStartState(cout); 158 } 159 if(printTrace) 160 { 161 if(!formatStringSet) 162 { 163 cerr << "No output format set!" << endl; 164 child->stopTracing(); 165 printUsage(argv[0]); 166 return 1; 167 } 168 if(!printer.configure(format)) 169 { 170 cerr << "Problem in the output format" << endl; 171 child->stopTracing(); 172 return 1; 173 } 174 child->step(); 175 while(child->isTracing()) 176 { 177 cout << printer; 178 child->step(); 179 } 180 cout << printer; 181 } 182 if(!child->stopTracing()) 183 { 184 cerr << "Couldn't stop child" << endl; 185 return 1; 186 } 187 return 0; 188} 189 190