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
2913158Sgabeblack@google.com */
3012855Sgabeblack@google.com
3112855Sgabeblack@google.com#include <iostream>
32#include <fstream>
33#include <string>
34#include <sys/types.h>
35#include <sys/wait.h>
36#include <sys/ptrace.h>
37#include <unistd.h>
38
39#include "tracechild.hh"
40#include "printer.hh"
41
42using namespace std;
43
44void printUsage(const char * execName)
45{
46        cout << execName << " -f <output format file> | -h | -r -- <command> <arguments>" << endl;
47}
48
49int main(int argc, char * argv[], char * envp[])
50{
51        TraceChild * child = genTraceChild();
52        NestingPrinter printer(child);
53        string args;
54        int startProgramArgs;
55
56        //Parse the command line arguments
57        bool formatStringSet = false;
58        bool printInitial = false;
59        bool printTrace = true;
60        string format;
61        for(int x = 1; x < argc; x++)
62        {
63                if(!strcmp(argv[x], "-f"))
64                {
65                        if(formatStringSet)
66                        {
67                                cerr << "Attempted to set format twice!"
68                                        << endl;
69                                printUsage(argv[0]);
70                                return 1;
71                        }
72                        formatStringSet = true;
73                        x++;
74                        if(x >= argc)
75                        {
76                                cerr << "Incorrect usage.\n" << endl;
77                                printUsage(argv[0]);
78                                return 1;
79                        }
80                        ifstream formatFile(argv[x]);
81                        if(!formatFile)
82                        {
83                                cerr << "Problem opening file "
84                                        << argv[x] << "." << endl;
85                                return 1;
86                        }
87                        format = "";
88                        while(formatFile)
89                        {
90                                string line;
91                                getline(formatFile, line);
92                                if(formatFile.eof())
93                                {
94                                        format += line;
95                                        break;
96                                }
97                                if(!formatFile)
98                                {
99                                        cerr << "Problem reading from file "
100                                                << argv[x] << "." << endl;
101                                        return 1;
102                                }
103                                format += line + '\n';
104                        }
105                }
106                else if(!strcmp(argv[x], "-h"))
107                {
108                        printUsage(argv[0]);
109                        return 0;
110                }
111                else if(!strcmp(argv[x], "-r"))
112                {
113                        cout << "Legal register names:" << endl;
114                        int numRegs = child->getNumRegs();
115                        for(unsigned int x = 0; x < numRegs; x++)
116                        {
117                                cout << "\t" << child->getRegName(x) << endl;
118                        }
119                        return 0;
120                }
121                else if(!strcmp(argv[x], "-i"))
122                {
123                    printInitial = true;
124                }
125                else if(!strcmp(argv[x], "-nt"))
126                {
127                    printTrace = false;
128                }
129                else if(!strcmp(argv[x], "--"))
130                {
131                        x++;
132                        if(x >= argc)
133                        {
134                                cerr << "Incorrect usage.\n" << endl;
135                                printUsage(argv[0]);
136                                return 1;
137                        }
138                        startProgramArgs = x;
139                        break;
140                }
141                else
142                {
143                        cerr << "Incorrect usage.\n" << endl;
144                        printUsage(argv[0]);
145                        return 1;
146                }
147        }
148        /*for(unsigned int x = startProgramArgs; x < argc; x++)
149        {
150            cout << "Adding argument " << argv[x];
151            args += string(" ") + argv[x];
152        }*/
153        if(!child->startTracing(argv[startProgramArgs],
154                    argv + startProgramArgs))
155        {
156                cerr << "Couldn't start target program" << endl;
157                return 1;
158        }
159        if(printInitial)
160        {
161            child->outputStartState(cout);
162        }
163        if(printTrace)
164        {
165            if(!formatStringSet)
166            {
167                    cerr << "No output format set!" << endl;
168                    child->stopTracing();
169                    printUsage(argv[0]);
170                    return 1;
171            }
172            if(!printer.configure(format))
173            {
174                    cerr << "Problem in the output format" << endl;
175                    child->stopTracing();
176                    return 1;
177            }
178            child->step();
179            while(child->isTracing())
180            {
181                    cout << printer;
182                    child->step();
183            }
184            cout << printer;
185        }
186        if(!child->stopTracing())
187        {
188                cerr << "Couldn't stop child" << endl;
189                return 1;
190        }
191        return 0;
192}
193
194