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