statetrace.cc revision 4125
112855Sgabeblack@google.com/*
212855Sgabeblack@google.com * Copyright (c) 2006-2007 The Regents of The University of Michigan
312855Sgabeblack@google.com * All rights reserved.
412855Sgabeblack@google.com *
512855Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without
612855Sgabeblack@google.com * modification, are permitted provided that the following conditions are
712855Sgabeblack@google.com * met: redistributions of source code must retain the above copyright
812855Sgabeblack@google.com * notice, this list of conditions and the following disclaimer;
912855Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright
1012855Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the
1112855Sgabeblack@google.com * documentation and/or other materials provided with the distribution;
1212855Sgabeblack@google.com * neither the name of the copyright holders nor the names of its
1312855Sgabeblack@google.com * contributors may be used to endorse or promote products derived from
1412855Sgabeblack@google.com * this software without specific prior written permission.
1512855Sgabeblack@google.com *
1612855Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1712855Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1812855Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1912855Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2012855Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2112855Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2212855Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2312855Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2412855Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2512855Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2612855Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2712855Sgabeblack@google.com *
2812855Sgabeblack@google.com * Authors: Gabe Black
2912855Sgabeblack@google.com */
3012855Sgabeblack@google.com
3112855Sgabeblack@google.com#include <iostream>
3212855Sgabeblack@google.com#include <fstream>
3312855Sgabeblack@google.com#include <string>
3412855Sgabeblack@google.com#include <sys/types.h>
3512855Sgabeblack@google.com#include <sys/wait.h>
3612855Sgabeblack@google.com#include <sys/ptrace.h>
3712855Sgabeblack@google.com#include <unistd.h>
3812855Sgabeblack@google.com
3912855Sgabeblack@google.com#include "tracechild.hh"
4012855Sgabeblack@google.com#include "printer.hh"
4112855Sgabeblack@google.com
4212855Sgabeblack@google.comusing namespace std;
4312855Sgabeblack@google.com
4412855Sgabeblack@google.comvoid printUsage(const char * execName)
4512855Sgabeblack@google.com{
4612855Sgabeblack@google.com        cout << execName << " -f <output format file> | -h | -r -- <command> <arguments>" << endl;
4712855Sgabeblack@google.com}
4812855Sgabeblack@google.com
4912855Sgabeblack@google.comint main(int argc, char * argv[], char * envp[])
5012855Sgabeblack@google.com{
5112855Sgabeblack@google.com        TraceChild * child = genTraceChild();
5212855Sgabeblack@google.com        NestingPrinter printer(child);
5312855Sgabeblack@google.com        string args;
5412855Sgabeblack@google.com        int startProgramArgs;
5512855Sgabeblack@google.com
5612855Sgabeblack@google.com        //Parse the command line arguments
5712855Sgabeblack@google.com        bool formatStringSet = false;
5812855Sgabeblack@google.com        bool printInitial = false;
5912855Sgabeblack@google.com        bool printTrace = true;
6012855Sgabeblack@google.com        string format;
6112855Sgabeblack@google.com        for(int x = 1; x < argc; x++)
6212855Sgabeblack@google.com        {
6312855Sgabeblack@google.com                if(!strcmp(argv[x], "-f"))
6412855Sgabeblack@google.com                {
6512855Sgabeblack@google.com                        if(formatStringSet)
6612855Sgabeblack@google.com                        {
6712855Sgabeblack@google.com                                cerr << "Attempted to set format twice!"
6812855Sgabeblack@google.com                                        << endl;
6912855Sgabeblack@google.com                                printUsage(argv[0]);
7012855Sgabeblack@google.com                                return 1;
7112855Sgabeblack@google.com                        }
7212855Sgabeblack@google.com                        formatStringSet = true;
7312855Sgabeblack@google.com                        x++;
7412855Sgabeblack@google.com                        if(x >= argc)
7512855Sgabeblack@google.com                        {
7612855Sgabeblack@google.com                                cerr << "Incorrect usage.\n" << endl;
7712855Sgabeblack@google.com                                printUsage(argv[0]);
7812855Sgabeblack@google.com                                return 1;
7912855Sgabeblack@google.com                        }
8012855Sgabeblack@google.com                        ifstream formatFile(argv[x]);
8112855Sgabeblack@google.com                        if(!formatFile)
8212855Sgabeblack@google.com                        {
8312855Sgabeblack@google.com                                cerr << "Problem opening file "
8412855Sgabeblack@google.com                                        << argv[x] << "." << endl;
8512855Sgabeblack@google.com                                return 1;
8612855Sgabeblack@google.com                        }
8712855Sgabeblack@google.com                        format = "";
8812855Sgabeblack@google.com                        while(formatFile)
8912855Sgabeblack@google.com                        {
9012855Sgabeblack@google.com                                string line;
9112855Sgabeblack@google.com                                getline(formatFile, line);
9212855Sgabeblack@google.com                                if(formatFile.eof())
9312855Sgabeblack@google.com                                {
9412855Sgabeblack@google.com                                        format += line;
9512855Sgabeblack@google.com                                        break;
9612855Sgabeblack@google.com                                }
9712855Sgabeblack@google.com                                if(!formatFile)
9812855Sgabeblack@google.com                                {
9912855Sgabeblack@google.com                                        cerr << "Problem reading from file "
10012855Sgabeblack@google.com                                                << argv[x] << "." << endl;
10112855Sgabeblack@google.com                                        return 1;
10212855Sgabeblack@google.com                                }
10312855Sgabeblack@google.com                                format += line + '\n';
10412855Sgabeblack@google.com                        }
10512855Sgabeblack@google.com                }
10612855Sgabeblack@google.com                else if(!strcmp(argv[x], "-h"))
10712855Sgabeblack@google.com                {
10812855Sgabeblack@google.com                        printUsage(argv[0]);
10912855Sgabeblack@google.com                        return 0;
11012855Sgabeblack@google.com                }
11112855Sgabeblack@google.com                else if(!strcmp(argv[x], "-r"))
11212855Sgabeblack@google.com                {
11312855Sgabeblack@google.com                        cout << "Legal register names:" << endl;
11412855Sgabeblack@google.com                        int numRegs = child->getNumRegs();
11512855Sgabeblack@google.com                        for(unsigned int x = 0; x < numRegs; x++)
11612855Sgabeblack@google.com                        {
11712855Sgabeblack@google.com                                cout << "\t" << child->getRegName(x) << endl;
11812855Sgabeblack@google.com                        }
11912855Sgabeblack@google.com                        return 0;
12012855Sgabeblack@google.com                }
12112855Sgabeblack@google.com                else if(!strcmp(argv[x], "-i"))
12212855Sgabeblack@google.com                {
12312855Sgabeblack@google.com                    printInitial = true;
12412855Sgabeblack@google.com                }
12512855Sgabeblack@google.com                else if(!strcmp(argv[x], "-nt"))
12612855Sgabeblack@google.com                {
12712855Sgabeblack@google.com                    printTrace = false;
12812855Sgabeblack@google.com                }
12912855Sgabeblack@google.com                else if(!strcmp(argv[x], "--"))
13012855Sgabeblack@google.com                {
13112855Sgabeblack@google.com                        x++;
13212855Sgabeblack@google.com                        if(x >= argc)
13312855Sgabeblack@google.com                        {
13412855Sgabeblack@google.com                                cerr << "Incorrect usage.\n" << endl;
13512855Sgabeblack@google.com                                printUsage(argv[0]);
13612855Sgabeblack@google.com                                return 1;
13712855Sgabeblack@google.com                        }
13812855Sgabeblack@google.com                        startProgramArgs = x;
13912855Sgabeblack@google.com                        break;
14012855Sgabeblack@google.com                }
14112855Sgabeblack@google.com                else
14212855Sgabeblack@google.com                {
14312855Sgabeblack@google.com                        cerr << "Incorrect usage.\n" << endl;
14412855Sgabeblack@google.com                        printUsage(argv[0]);
14512855Sgabeblack@google.com                        return 1;
14612855Sgabeblack@google.com                }
14712855Sgabeblack@google.com        }
14812855Sgabeblack@google.com        /*for(unsigned int x = startProgramArgs; x < argc; x++)
14912855Sgabeblack@google.com        {
15012855Sgabeblack@google.com            cout << "Adding argument " << argv[x];
15112855Sgabeblack@google.com            args += string(" ") + argv[x];
15212855Sgabeblack@google.com        }*/
15312855Sgabeblack@google.com        if(!child->startTracing(argv[startProgramArgs],
15412855Sgabeblack@google.com                    argv + startProgramArgs))
15512855Sgabeblack@google.com        {
15612855Sgabeblack@google.com                cerr << "Couldn't start target program" << endl;
15712855Sgabeblack@google.com                return 1;
15812855Sgabeblack@google.com        }
15912855Sgabeblack@google.com        if(printInitial)
16012855Sgabeblack@google.com        {
16112855Sgabeblack@google.com            child->outputStartState(cout);
16212855Sgabeblack@google.com        }
16312855Sgabeblack@google.com        if(printTrace)
16412855Sgabeblack@google.com        {
16512855Sgabeblack@google.com            if(!formatStringSet)
16612855Sgabeblack@google.com            {
16712855Sgabeblack@google.com                    cerr << "No output format set!" << endl;
16812855Sgabeblack@google.com                    child->stopTracing();
16912855Sgabeblack@google.com                    printUsage(argv[0]);
17012855Sgabeblack@google.com                    return 1;
17112855Sgabeblack@google.com            }
17212855Sgabeblack@google.com            if(!printer.configure(format))
17312855Sgabeblack@google.com            {
17412855Sgabeblack@google.com                    cerr << "Problem in the output format" << endl;
17512855Sgabeblack@google.com                    child->stopTracing();
17612855Sgabeblack@google.com                    return 1;
17712855Sgabeblack@google.com            }
17812855Sgabeblack@google.com            child->step();
17912855Sgabeblack@google.com            while(child->isTracing())
18012855Sgabeblack@google.com            {
18112855Sgabeblack@google.com                    cout << printer;
18212855Sgabeblack@google.com                    child->step();
18312855Sgabeblack@google.com            }
18412855Sgabeblack@google.com            cout << printer;
18512855Sgabeblack@google.com        }
18612855Sgabeblack@google.com        if(!child->stopTracing())
18712855Sgabeblack@google.com        {
18812855Sgabeblack@google.com                cerr << "Couldn't stop child" << endl;
18912855Sgabeblack@google.com                return 1;
19012855Sgabeblack@google.com        }
19112855Sgabeblack@google.com        return 0;
19212855Sgabeblack@google.com}
19312855Sgabeblack@google.com
19412855Sgabeblack@google.com