statetrace.cc revision 7414
12SN/A/* 21762SN/A * Copyright (c) 2006-2007 The Regents of The University of Michigan 32SN/A * All rights reserved. 42SN/A * 52SN/A * Redistribution and use in source and binary forms, with or without 62SN/A * modification, are permitted provided that the following conditions are 72SN/A * met: redistributions of source code must retain the above copyright 82SN/A * notice, this list of conditions and the following disclaimer; 92SN/A * redistributions in binary form must reproduce the above copyright 102SN/A * notice, this list of conditions and the following disclaimer in the 112SN/A * documentation and/or other materials provided with the distribution; 122SN/A * neither the name of the copyright holders nor the names of its 132SN/A * contributors may be used to endorse or promote products derived from 142SN/A * this software without specific prior written permission. 152SN/A * 162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * Authors: Gabe Black 292665Ssaidi@eecs.umich.edu */ 302SN/A 312SN/A#include <cstring> 32360SN/A#include <errno.h> 33360SN/A#include <fstream> 342SN/A#include <iostream> 352SN/A#include <netdb.h> 362SN/A#include <netinet/in.h> 372SN/A#include <stdio.h> 382SN/A#include <string> 392SN/A#include <sys/ptrace.h> 401858SN/A#include <sys/socket.h> 411858SN/A#include <sys/types.h> 421858SN/A#include <sys/wait.h> 432SN/A#include <unistd.h> 444117Sgblack@eecs.umich.edu 45180SN/A#include "printer.hh" 462SN/A#include "tracechild.hh" 476329Sgblack@eecs.umich.edu 482378SN/Ausing namespace std; 496214Snate@binkert.org 506658Snate@binkert.orgvoid printUsage(const char * execName) 5156SN/A{ 525958Sgblack@eecs.umich.edu cout << execName << " <options> -- <command> <arguments>" << endl; 532SN/A cout << "options:" << endl; 546658Snate@binkert.org cout << " -h print this help" << endl; 555154Sgblack@eecs.umich.edu cout << " --host remote m5 host to connect to" << endl; 565154Sgblack@eecs.umich.edu cout << " -r print register names" << endl; 575154Sgblack@eecs.umich.edu cout << " -i print initial stack state" << endl; 585154Sgblack@eecs.umich.edu cout << " -nt don't print an instruction trace" << endl; 595154Sgblack@eecs.umich.edu} 605154Sgblack@eecs.umich.edu 612680Sktlim@umich.eduint main(int argc, char * argv[], char * envp[]) 622401SN/A{ 632378SN/A TraceChild * child = genTraceChild(); 645758Shsul@eecs.umich.edu string args; 655771Shsul@eecs.umich.edu int startProgramArgs; 665758Shsul@eecs.umich.edu 675758Shsul@eecs.umich.edu //Parse the command line arguments 685771Shsul@eecs.umich.edu bool printInitial = false; 695758Shsul@eecs.umich.edu bool printTrace = true; 705771Shsul@eecs.umich.edu string host = "localhost"; 715758Shsul@eecs.umich.edu 725758Shsul@eecs.umich.edu if (argc == 1) { 735771Shsul@eecs.umich.edu printUsage(argv[0]); 745758Shsul@eecs.umich.edu return 0; 755758Shsul@eecs.umich.edu } 762SN/A for(int x = 1; x < argc; x++) 772SN/A { 782SN/A if(!strcmp(argv[x], "-h")) 792SN/A { 802378SN/A printUsage(argv[0]); 812378SN/A return 0; 822378SN/A } 832378SN/A if(!strcmp(argv[x], "--host")) 842680Sktlim@umich.edu { 852SN/A x++; 862SN/A if(x >= argc) 872SN/A { 882SN/A cerr << "Incorrect usage.\n" << endl; 895183Ssaidi@eecs.umich.edu printUsage(argv[0]); 905183Ssaidi@eecs.umich.edu return 1; 912680Sktlim@umich.edu } 925713Shsul@eecs.umich.edu host = argv[x]; 93180SN/A } 943971Sgblack@eecs.umich.edu else if(!strcmp(argv[x], "-r")) 956658Snate@binkert.org { 963971Sgblack@eecs.umich.edu cout << "Legal register names:" << endl; 973971Sgblack@eecs.umich.edu int numRegs = child->getNumRegs(); 983971Sgblack@eecs.umich.edu for(unsigned int x = 0; x < numRegs; x++) 99180SN/A { 1005713Shsul@eecs.umich.edu cout << "\t" << child->getRegName(x) << endl; 1012SN/A } 1022SN/A return 0; 1032SN/A } 1042SN/A else if(!strcmp(argv[x], "-i")) 1052SN/A { 1062680Sktlim@umich.edu printInitial = true; 1072SN/A } 1082680Sktlim@umich.edu else if(!strcmp(argv[x], "-nt")) 1092SN/A { 1105543Ssaidi@eecs.umich.edu printTrace = false; 1112SN/A } 1122SN/A else if(!strcmp(argv[x], "--")) 1132SN/A { 1142SN/A x++; 1152SN/A if(x >= argc) 1165543Ssaidi@eecs.umich.edu { 1172SN/A cerr << "Incorrect usage.\n" << endl; 1185543Ssaidi@eecs.umich.edu printUsage(argv[0]); 1195543Ssaidi@eecs.umich.edu return 1; 1205543Ssaidi@eecs.umich.edu } 1212SN/A startProgramArgs = x; 1225154Sgblack@eecs.umich.edu break; 1235154Sgblack@eecs.umich.edu } 1245154Sgblack@eecs.umich.edu else 1252SN/A { 1262SN/A cerr << "Incorrect usage.\n" << endl; 1272SN/A printUsage(argv[0]); 128360SN/A return 1; 1291408SN/A } 1301408SN/A } 131360SN/A if(!child->startTracing(argv[startProgramArgs], 1321514SN/A argv + startProgramArgs)) 1331514SN/A { 1341514SN/A cerr << "Couldn't start target program" << endl; 1351514SN/A return 1; 1365543Ssaidi@eecs.umich.edu } 1372SN/A child->step(); 1385999Snate@binkert.org if(printInitial) 1392SN/A { 1402SN/A child->outputStartState(cout); 1412SN/A } 1422SN/A if(printTrace) 1435154Sgblack@eecs.umich.edu { 1442SN/A // Connect to m5 1451395SN/A bool portSet = false; 1461395SN/A int port; 1472SN/A int sock = socket(AF_INET, SOCK_STREAM, 0); 1482SN/A if(sock < 0) 1492378SN/A { 1502401SN/A cerr << "Error opening socket! " << strerror(errno) << endl; 1512378SN/A return 1; 1522378SN/A } 1532378SN/A struct hostent *server; 1542SN/A server = gethostbyname(host.c_str()); 1554997Sgblack@eecs.umich.edu if(!server) 1564997Sgblack@eecs.umich.edu { 1574997Sgblack@eecs.umich.edu cerr << "Couldn't get host ip! " << strerror(errno) << endl; 1584997Sgblack@eecs.umich.edu return 1; 1595282Srstrong@cs.ucsd.edu } 1605282Srstrong@cs.ucsd.edu struct sockaddr_in serv_addr; 1615282Srstrong@cs.ucsd.edu bzero((char *)&serv_addr, sizeof(serv_addr)); 1625282Srstrong@cs.ucsd.edu serv_addr.sin_family = AF_INET; 1635282Srstrong@cs.ucsd.edu bcopy((char *)server->h_addr, 1645282Srstrong@cs.ucsd.edu (char *)&serv_addr.sin_addr.s_addr, 1655282Srstrong@cs.ucsd.edu server->h_length); 1665282Srstrong@cs.ucsd.edu serv_addr.sin_port = htons(8000); 1675282Srstrong@cs.ucsd.edu if(connect(sock, (sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) 1685282Srstrong@cs.ucsd.edu { 1695282Srstrong@cs.ucsd.edu cerr << "Couldn't connect to server! " << strerror(errno) << endl; 1705282Srstrong@cs.ucsd.edu return 1; 1715282Srstrong@cs.ucsd.edu } 1725282Srstrong@cs.ucsd.edu while(child->isTracing()) 1735282Srstrong@cs.ucsd.edu { 1745282Srstrong@cs.ucsd.edu if(!child->sendState(sock)) 1755282Srstrong@cs.ucsd.edu break; 1765282Srstrong@cs.ucsd.edu child->step(); 1775282Srstrong@cs.ucsd.edu } 1785282Srstrong@cs.ucsd.edu } 1795282Srstrong@cs.ucsd.edu if(!child->stopTracing()) 1805282Srstrong@cs.ucsd.edu { 1815282Srstrong@cs.ucsd.edu cerr << "Couldn't stop child" << endl; 1825282Srstrong@cs.ucsd.edu return 1; 1835282Srstrong@cs.ucsd.edu } 1845282Srstrong@cs.ucsd.edu return 0; 1855282Srstrong@cs.ucsd.edu} 1865282Srstrong@cs.ucsd.edu 1875282Srstrong@cs.ucsd.edu