statetrace.cc revision 6408
12632Sstever@eecs.umich.edu/* 22632Sstever@eecs.umich.edu * Copyright (c) 2006-2007 The Regents of The University of Michigan 32632Sstever@eecs.umich.edu * All rights reserved. 42632Sstever@eecs.umich.edu * 52632Sstever@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 62632Sstever@eecs.umich.edu * modification, are permitted provided that the following conditions are 72632Sstever@eecs.umich.edu * met: redistributions of source code must retain the above copyright 84479Sbinkertn@umich.edu * notice, this list of conditions and the following disclaimer; 94479Sbinkertn@umich.edu * redistributions in binary form must reproduce the above copyright 104479Sbinkertn@umich.edu * notice, this list of conditions and the following disclaimer in the 116498Snate@binkert.org * documentation and/or other materials provided with the distribution; 126498Snate@binkert.org * neither the name of the copyright holders nor the names of its 136498Snate@binkert.org * contributors may be used to endorse or promote products derived from 142632Sstever@eecs.umich.edu * this software without specific prior written permission. 152632Sstever@eecs.umich.edu * 162632Sstever@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172632Sstever@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 184479Sbinkertn@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 194479Sbinkertn@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202632Sstever@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212632Sstever@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222632Sstever@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232632Sstever@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242632Sstever@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252632Sstever@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 266498Snate@binkert.org * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272632Sstever@eecs.umich.edu * 282632Sstever@eecs.umich.edu * Authors: Gabe Black 292632Sstever@eecs.umich.edu */ 302632Sstever@eecs.umich.edu 312632Sstever@eecs.umich.edu#include <cstring> 322632Sstever@eecs.umich.edu#include <errno.h> 334479Sbinkertn@umich.edu#include <fstream> 346498Snate@binkert.org#include <iostream> 352632Sstever@eecs.umich.edu#include <netdb.h> 366498Snate@binkert.org#include <netinet/in.h> 374479Sbinkertn@umich.edu#include <stdio.h> 386498Snate@binkert.org#include <string> 392632Sstever@eecs.umich.edu#include <sys/ptrace.h> 404479Sbinkertn@umich.edu#include <sys/socket.h> 412632Sstever@eecs.umich.edu#include <sys/types.h> 422632Sstever@eecs.umich.edu#include <sys/wait.h> 432632Sstever@eecs.umich.edu#include <unistd.h> 442632Sstever@eecs.umich.edu 452632Sstever@eecs.umich.edu#include "printer.hh" 464479Sbinkertn@umich.edu#include "tracechild.hh" 474479Sbinkertn@umich.edu 482632Sstever@eecs.umich.eduusing namespace std; 492632Sstever@eecs.umich.edu 502632Sstever@eecs.umich.eduvoid printUsage(const char * execName) 512632Sstever@eecs.umich.edu{ 522632Sstever@eecs.umich.edu cout << execName << " -h | -r -- <command> <arguments>" << endl; 532632Sstever@eecs.umich.edu} 544479Sbinkertn@umich.edu 554479Sbinkertn@umich.eduint main(int argc, char * argv[], char * envp[]) 564479Sbinkertn@umich.edu{ 572632Sstever@eecs.umich.edu TraceChild * child = genTraceChild(); 584479Sbinkertn@umich.edu string args; 592632Sstever@eecs.umich.edu int startProgramArgs; 606498Snate@binkert.org 612632Sstever@eecs.umich.edu //Parse the command line arguments 624479Sbinkertn@umich.edu bool printInitial = false; 634479Sbinkertn@umich.edu bool printTrace = true; 644479Sbinkertn@umich.edu string host = "localhost"; 654479Sbinkertn@umich.edu for(int x = 1; x < argc; x++) 664479Sbinkertn@umich.edu { 674479Sbinkertn@umich.edu if(!strcmp(argv[x], "-h")) 684479Sbinkertn@umich.edu { 694479Sbinkertn@umich.edu printUsage(argv[0]); 704479Sbinkertn@umich.edu return 0; 712632Sstever@eecs.umich.edu } 724479Sbinkertn@umich.edu if(!strcmp(argv[x], "--host")) 734479Sbinkertn@umich.edu { 744479Sbinkertn@umich.edu x++; 752632Sstever@eecs.umich.edu if(x >= argc) 764479Sbinkertn@umich.edu { 774479Sbinkertn@umich.edu cerr << "Incorrect usage.\n" << endl; 784479Sbinkertn@umich.edu printUsage(argv[0]); 792632Sstever@eecs.umich.edu return 1; 804479Sbinkertn@umich.edu } 814479Sbinkertn@umich.edu host = argv[x]; 824479Sbinkertn@umich.edu } 832632Sstever@eecs.umich.edu else if(!strcmp(argv[x], "-r")) 844479Sbinkertn@umich.edu { 854479Sbinkertn@umich.edu cout << "Legal register names:" << endl; 862632Sstever@eecs.umich.edu int numRegs = child->getNumRegs(); 874479Sbinkertn@umich.edu for(unsigned int x = 0; x < numRegs; x++) 882632Sstever@eecs.umich.edu { 896498Snate@binkert.org cout << "\t" << child->getRegName(x) << endl; 904479Sbinkertn@umich.edu } 912632Sstever@eecs.umich.edu return 0; 924479Sbinkertn@umich.edu } 936498Snate@binkert.org else if(!strcmp(argv[x], "-i")) 946498Snate@binkert.org { 956498Snate@binkert.org printInitial = true; 966498Snate@binkert.org } 972632Sstever@eecs.umich.edu else if(!strcmp(argv[x], "-nt")) 984479Sbinkertn@umich.edu { 992632Sstever@eecs.umich.edu printTrace = false; 1002632Sstever@eecs.umich.edu } 1012632Sstever@eecs.umich.edu else if(!strcmp(argv[x], "--")) 1022632Sstever@eecs.umich.edu { 1032632Sstever@eecs.umich.edu x++; 1042632Sstever@eecs.umich.edu if(x >= argc) 1052632Sstever@eecs.umich.edu { 1064479Sbinkertn@umich.edu cerr << "Incorrect usage.\n" << endl; 1072632Sstever@eecs.umich.edu printUsage(argv[0]); 108 return 1; 109 } 110 startProgramArgs = x; 111 break; 112 } 113 else 114 { 115 cerr << "Incorrect usage.\n" << endl; 116 printUsage(argv[0]); 117 return 1; 118 } 119 } 120 if(!child->startTracing(argv[startProgramArgs], 121 argv + startProgramArgs)) 122 { 123 cerr << "Couldn't start target program" << endl; 124 return 1; 125 } 126 if(printInitial) 127 { 128 child->outputStartState(cout); 129 } 130 if(printTrace) 131 { 132 // Connect to m5 133 bool portSet = false; 134 int port; 135 int sock = socket(AF_INET, SOCK_STREAM, 0); 136 if(sock < 0) 137 { 138 cerr << "Error opening socket! " << strerror(errno) << endl; 139 return 1; 140 } 141 struct hostent *server; 142 server = gethostbyname(host.c_str()); 143 if(!server) 144 { 145 cerr << "Couldn't get host ip! " << strerror(errno) << endl; 146 return 1; 147 } 148 struct sockaddr_in serv_addr; 149 bzero((char *)&serv_addr, sizeof(serv_addr)); 150 serv_addr.sin_family = AF_INET; 151 bcopy((char *)server->h_addr, 152 (char *)&serv_addr.sin_addr.s_addr, 153 server->h_length); 154 serv_addr.sin_port = htons(8000); 155 if(connect(sock, (sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) 156 { 157 cerr << "Couldn't connect to server! " << strerror(errno) << endl; 158 return 1; 159 } 160 child->step(); 161 while(child->isTracing()) 162 { 163 if(!child->sendState(sock)) 164 break; 165 child->step(); 166 } 167 } 168 if(!child->stopTracing()) 169 { 170 cerr << "Couldn't stop child" << endl; 171 return 1; 172 } 173 return 0; 174} 175 176