statetrace.cc revision 4125
15331Sgblack@eecs.umich.edu/*
25331Sgblack@eecs.umich.edu * Copyright (c) 2006-2007 The Regents of The University of Michigan
35331Sgblack@eecs.umich.edu * All rights reserved.
45331Sgblack@eecs.umich.edu *
55331Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
65331Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
75331Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
85331Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
95331Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
105331Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
115331Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
125331Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
135331Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
145331Sgblack@eecs.umich.edu * this software without specific prior written permission.
155331Sgblack@eecs.umich.edu *
165331Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
175331Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
185331Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
195331Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
205331Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
215331Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
225331Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
235331Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
245331Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
255331Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
265331Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
275331Sgblack@eecs.umich.edu *
285331Sgblack@eecs.umich.edu * Authors: Gabe Black
295331Sgblack@eecs.umich.edu */
304276Sgblack@eecs.umich.edu
314276Sgblack@eecs.umich.edu#include <iostream>
324276Sgblack@eecs.umich.edu#include <fstream>
334276Sgblack@eecs.umich.edu#include <string>
344276Sgblack@eecs.umich.edu#include <sys/types.h>
354276Sgblack@eecs.umich.edu#include <sys/wait.h>
364276Sgblack@eecs.umich.edu#include <sys/ptrace.h>
374276Sgblack@eecs.umich.edu#include <unistd.h>
384276Sgblack@eecs.umich.edu
394276Sgblack@eecs.umich.edu#include "tracechild.hh"
404276Sgblack@eecs.umich.edu#include "printer.hh"
414276Sgblack@eecs.umich.edu
424276Sgblack@eecs.umich.eduusing namespace std;
434276Sgblack@eecs.umich.edu
444276Sgblack@eecs.umich.eduvoid printUsage(const char * execName)
454276Sgblack@eecs.umich.edu{
464276Sgblack@eecs.umich.edu        cout << execName << " -f <output format file> | -h | -r -- <command> <arguments>" << endl;
474276Sgblack@eecs.umich.edu}
484276Sgblack@eecs.umich.edu
494276Sgblack@eecs.umich.eduint main(int argc, char * argv[], char * envp[])
504276Sgblack@eecs.umich.edu{
514276Sgblack@eecs.umich.edu        TraceChild * child = genTraceChild();
524276Sgblack@eecs.umich.edu        NestingPrinter printer(child);
534276Sgblack@eecs.umich.edu        string args;
544276Sgblack@eecs.umich.edu        int startProgramArgs;
554276Sgblack@eecs.umich.edu
564276Sgblack@eecs.umich.edu        //Parse the command line arguments
574276Sgblack@eecs.umich.edu        bool formatStringSet = false;
584276Sgblack@eecs.umich.edu        bool printInitial = false;
594276Sgblack@eecs.umich.edu        bool printTrace = true;
604276Sgblack@eecs.umich.edu        string format;
614276Sgblack@eecs.umich.edu        for(int x = 1; x < argc; x++)
624276Sgblack@eecs.umich.edu        {
634276Sgblack@eecs.umich.edu                if(!strcmp(argv[x], "-f"))
644276Sgblack@eecs.umich.edu                {
654276Sgblack@eecs.umich.edu                        if(formatStringSet)
664276Sgblack@eecs.umich.edu                        {
674276Sgblack@eecs.umich.edu                                cerr << "Attempted to set format twice!"
684276Sgblack@eecs.umich.edu                                        << endl;
694276Sgblack@eecs.umich.edu                                printUsage(argv[0]);
704276Sgblack@eecs.umich.edu                                return 1;
714276Sgblack@eecs.umich.edu                        }
724276Sgblack@eecs.umich.edu                        formatStringSet = true;
734276Sgblack@eecs.umich.edu                        x++;
744276Sgblack@eecs.umich.edu                        if(x >= argc)
754276Sgblack@eecs.umich.edu                        {
764276Sgblack@eecs.umich.edu                                cerr << "Incorrect usage.\n" << endl;
774276Sgblack@eecs.umich.edu                                printUsage(argv[0]);
784276Sgblack@eecs.umich.edu                                return 1;
794276Sgblack@eecs.umich.edu                        }
804276Sgblack@eecs.umich.edu                        ifstream formatFile(argv[x]);
814276Sgblack@eecs.umich.edu                        if(!formatFile)
824276Sgblack@eecs.umich.edu                        {
834276Sgblack@eecs.umich.edu                                cerr << "Problem opening file "
844276Sgblack@eecs.umich.edu                                        << argv[x] << "." << endl;
854276Sgblack@eecs.umich.edu                                return 1;
864276Sgblack@eecs.umich.edu                        }
874276Sgblack@eecs.umich.edu                        format = "";
884276Sgblack@eecs.umich.edu                        while(formatFile)
894711Sgblack@eecs.umich.edu                        {
904276Sgblack@eecs.umich.edu                                string line;
914276Sgblack@eecs.umich.edu                                getline(formatFile, line);
925238Sgblack@eecs.umich.edu                                if(formatFile.eof())
935238Sgblack@eecs.umich.edu                                {
945238Sgblack@eecs.umich.edu                                        format += line;
955238Sgblack@eecs.umich.edu                                        break;
965937Sgblack@eecs.umich.edu                                }
975902Sgblack@eecs.umich.edu                                if(!formatFile)
985238Sgblack@eecs.umich.edu                                {
995238Sgblack@eecs.umich.edu                                        cerr << "Problem reading from file "
1005238Sgblack@eecs.umich.edu                                                << argv[x] << "." << endl;
1015238Sgblack@eecs.umich.edu                                        return 1;
1025238Sgblack@eecs.umich.edu                                }
1035238Sgblack@eecs.umich.edu                                format += line + '\n';
1045238Sgblack@eecs.umich.edu                        }
1055238Sgblack@eecs.umich.edu                }
1065238Sgblack@eecs.umich.edu                else if(!strcmp(argv[x], "-h"))
1075238Sgblack@eecs.umich.edu                {
1085238Sgblack@eecs.umich.edu                        printUsage(argv[0]);
1095238Sgblack@eecs.umich.edu                        return 0;
1105238Sgblack@eecs.umich.edu                }
1115238Sgblack@eecs.umich.edu                else if(!strcmp(argv[x], "-r"))
1125238Sgblack@eecs.umich.edu                {
1135238Sgblack@eecs.umich.edu                        cout << "Legal register names:" << endl;
1145238Sgblack@eecs.umich.edu                        int numRegs = child->getNumRegs();
1155238Sgblack@eecs.umich.edu                        for(unsigned int x = 0; x < numRegs; x++)
1165238Sgblack@eecs.umich.edu                        {
1175238Sgblack@eecs.umich.edu                                cout << "\t" << child->getRegName(x) << endl;
1185238Sgblack@eecs.umich.edu                        }
1195238Sgblack@eecs.umich.edu                        return 0;
1205238Sgblack@eecs.umich.edu                }
1215238Sgblack@eecs.umich.edu                else if(!strcmp(argv[x], "-i"))
1225238Sgblack@eecs.umich.edu                {
1235238Sgblack@eecs.umich.edu                    printInitial = true;
1245238Sgblack@eecs.umich.edu                }
1255238Sgblack@eecs.umich.edu                else if(!strcmp(argv[x], "-nt"))
1265238Sgblack@eecs.umich.edu                {
1275238Sgblack@eecs.umich.edu                    printTrace = false;
1286055Sgblack@eecs.umich.edu                }
1296054Sgblack@eecs.umich.edu                else if(!strcmp(argv[x], "--"))
1305238Sgblack@eecs.umich.edu                {
1315683Sgblack@eecs.umich.edu                        x++;
1325238Sgblack@eecs.umich.edu                        if(x >= argc)
1335238Sgblack@eecs.umich.edu                        {
1345238Sgblack@eecs.umich.edu                                cerr << "Incorrect usage.\n" << endl;
1355238Sgblack@eecs.umich.edu                                printUsage(argv[0]);
1365238Sgblack@eecs.umich.edu                                return 1;
1375238Sgblack@eecs.umich.edu                        }
1385238Sgblack@eecs.umich.edu                        startProgramArgs = x;
1395238Sgblack@eecs.umich.edu                        break;
1405291Sgblack@eecs.umich.edu                }
1415291Sgblack@eecs.umich.edu                else
1425291Sgblack@eecs.umich.edu                {
1435291Sgblack@eecs.umich.edu                        cerr << "Incorrect usage.\n" << endl;
1445291Sgblack@eecs.umich.edu                        printUsage(argv[0]);
1455291Sgblack@eecs.umich.edu                        return 1;
1465291Sgblack@eecs.umich.edu                }
1475291Sgblack@eecs.umich.edu        }
1485291Sgblack@eecs.umich.edu        /*for(unsigned int x = startProgramArgs; x < argc; x++)
1495292Sgblack@eecs.umich.edu        {
1505292Sgblack@eecs.umich.edu            cout << "Adding argument " << argv[x];
1515292Sgblack@eecs.umich.edu            args += string(" ") + argv[x];
1525292Sgblack@eecs.umich.edu        }*/
1535292Sgblack@eecs.umich.edu        if(!child->startTracing(argv[startProgramArgs],
1545292Sgblack@eecs.umich.edu                    argv + startProgramArgs))
1555292Sgblack@eecs.umich.edu        {
1565292Sgblack@eecs.umich.edu                cerr << "Couldn't start target program" << endl;
1575292Sgblack@eecs.umich.edu                return 1;
1586055Sgblack@eecs.umich.edu        }
1596054Sgblack@eecs.umich.edu        if(printInitial)
1605359Sgblack@eecs.umich.edu        {
1615238Sgblack@eecs.umich.edu            child->outputStartState(cout);
1625238Sgblack@eecs.umich.edu        }
1635238Sgblack@eecs.umich.edu        if(printTrace)
1644276Sgblack@eecs.umich.edu        {
1654276Sgblack@eecs.umich.edu            if(!formatStringSet)
1665789Sgblack@eecs.umich.edu            {
1675789Sgblack@eecs.umich.edu                    cerr << "No output format set!" << endl;
1685789Sgblack@eecs.umich.edu                    child->stopTracing();
1695789Sgblack@eecs.umich.edu                    printUsage(argv[0]);
1705789Sgblack@eecs.umich.edu                    return 1;
1715789Sgblack@eecs.umich.edu            }
1725789Sgblack@eecs.umich.edu            if(!printer.configure(format))
1735789Sgblack@eecs.umich.edu            {
1745789Sgblack@eecs.umich.edu                    cerr << "Problem in the output format" << endl;
1755789Sgblack@eecs.umich.edu                    child->stopTracing();
1765789Sgblack@eecs.umich.edu                    return 1;
1775789Sgblack@eecs.umich.edu            }
1785789Sgblack@eecs.umich.edu            child->step();
1795789Sgblack@eecs.umich.edu            while(child->isTracing())
1805789Sgblack@eecs.umich.edu            {
1815789Sgblack@eecs.umich.edu                    cout << printer;
1825789Sgblack@eecs.umich.edu                    child->step();
1835789Sgblack@eecs.umich.edu            }
1845789Sgblack@eecs.umich.edu            cout << printer;
1855789Sgblack@eecs.umich.edu        }
1865789Sgblack@eecs.umich.edu        if(!child->stopTracing())
1875789Sgblack@eecs.umich.edu        {
1885789Sgblack@eecs.umich.edu                cerr << "Couldn't stop child" << endl;
1895789Sgblack@eecs.umich.edu                return 1;
1905789Sgblack@eecs.umich.edu        }
1915789Sgblack@eecs.umich.edu        return 0;
1925789Sgblack@eecs.umich.edu}
1935789Sgblack@eecs.umich.edu
1945789Sgblack@eecs.umich.edu