2 * Copyright (c) 1996 Barton P. Miller
4 * We provide the Paradyn Parallel Performance Tools (below
5 * described as Paradyn") on an AS IS basis, and do not warrant its
6 * validity or performance. We reserve the right to update, modify,
7 * or discontinue this software at any time. We shall have no
8 * obligation to supply such updates or modifications or any other
9 * form of support to you.
11 * This license is for research uses. For such uses, there is no
12 * charge. We define "research use" to mean you may freely use it
13 * inside your organization for whatever purposes you see fit. But you
14 * may not re-distribute Paradyn or parts of Paradyn, in any form
15 * source or binary (including derivatives), electronic or otherwise,
16 * to any other organization or entity without our permission.
18 * (for other uses, please contact us at paradyn@cs.wisc.edu)
20 * All warranties, including without limitation, any warranty of
21 * merchantability or fitness for a particular purpose, are hereby
24 * By your use of Paradyn, you understand and agree that we (or any
25 * other person or entity with proprietary rights in Paradyn) are
26 * under no obligation to provide either maintenance services,
27 * update services, notices of latent defects, or correction of
28 * defects for Paradyn.
30 * Even if advised of the possibility of such damages, under no
31 * circumstances shall we (or any other person or entity with
32 * proprietary rights in the software licensed hereunder) be liable
33 * to you or any third party for direct, indirect, or consequential
34 * damages of any character regardless of type of action, including,
35 * without limitation, loss of profits, loss of use, loss of good
36 * will, or computer failure or malfunction. You agree to indemnify
37 * us (and any other person or entity with proprietary rights in the
38 * software licensed hereunder) for any and all liability it may
39 * incur to third parties resulting from your use of Paradyn.
42 * This file contains special versions of some of the functions in process.C
43 * that have been modified for the dyninstAPI library.
46 * $Log: process2.C,v $
47 * Revision 1.2 1997/05/07 19:03:20 naim
48 * Getting rid of old support for threads and turning it off until the new
49 * version is finished. Additionally, new superTable, baseTable and superVector
50 * classes for future support of multiple threads. The fastInferiorHeap class has
53 * Revision 1.1 1997/03/18 19:44:23 buck
54 * first commit of dyninst library. Also includes:
55 * moving templates from paradynd to dyninstAPI
56 * converting showError into a function (in showerror.C)
57 * many ifdefs for BPATCH_LIBRARY in dyinstAPI/src.
64 int pvmputenv (const char *);
69 #include "util/h/headers.h"
70 #include "dyninstAPI/src/symtab.h"
71 #include "dyninstAPI/src/pdThread.h"
72 #include "dyninstAPI/src/process.h"
73 #include "dyninstAPI/src/util.h"
74 #include "dyninstAPI/src/inst.h"
75 #include "dyninstAPI/src/instP.h"
76 #include "dyninstAPI/src/dyninstP.h"
77 #include "dyninstAPI/src/os.h"
78 #include "paradynd/src/showerror.h"
79 #include "paradynd/src/perfStream.h"
80 #include "dyninstAPI/src/dynamiclinking.h"
82 #include "util/h/debugOstream.h"
84 #ifdef ATTACH_DETACH_DEBUG
85 extern debug_ostream attach_cerr;
87 extern debug_ostream attach_cerr;
90 extern unsigned activeProcesses; // number of active processes
91 extern vector<process*> processVec;
93 extern bool dyninstAPI_forkNewProcess(string file, string dir,
94 vector<string> argv, vector<string>envp, string inputFile,
95 string outputFile, int &traceLink, int &ioLink, int &pid, int &tid,
96 int &procHandle, int &thrHandle);
99 * Create a new instance of the named process. Read the symbols and start
102 process *dyninstAPI_createProcess(const string File, vector<string> argv,
103 vector<string> envp, const string dir = "")
105 // prepend the directory (if any) to the file, unless the filename
108 if (!file.prefixed_by("/") && dir.length() > 0)
109 file = dir + "/" + file;
121 ioLink = traceLink = -1;
122 if (!dyninstAPI_forkNewProcess(file, dir, argv, envp, inputFile, outputFile,
123 traceLink, ioLink, pid, tid, procHandle, thrHandle)) {
124 // forkNewProcess is resposible for displaying error messages
129 #if defined(rs6000_ibm_aix3_2) || defined(rs6000_ibm_aix4_1)
130 extern bool establishBaseAddrs(int pid, int &status, bool waitForTrap);
133 if (!establishBaseAddrs(pid, status, true)) {
138 image *img = image::parseImage(file);
140 // For better error reporting, two failure return values would be useful
141 // One for simple error like because-file-not-because
142 // Another for serious errors like found-but-parsing-failed (internal error;
143 // please report to paradyn@cs.wisc.edu)
145 string msg = string("Unable to parse image: ") + file;
146 showErrorCallback(68, msg.string_of());
147 // destroy child process
154 statusLine("initializing process data structures");
157 vector<fastInferiorHeapMgr::oneHeapStats> theShmHeapStats(3);
158 theShmHeapStats[0].elemNumBytes = sizeof(intCounter);
159 theShmHeapStats[0].maxNumElems = numIntCounters;
161 theShmHeapStats[1].elemNumBytes = sizeof(tTimer);
162 theShmHeapStats[1].maxNumElems = numWallTimers;
164 theShmHeapStats[2].elemNumBytes = sizeof(tTimer);
165 theShmHeapStats[2].maxNumElems = numProcTimers;
168 process *ret = new process(pid, img, traceLink, ioLink
170 , 7000, // shm seg key to try first
174 // change this to a ctor that takes in more args
181 // find the signal handler function
182 ret->findSignalHandler(); // should this be in the ctor?
184 // initializing vector of threads - thread[0] is really the
186 ret->threads += new pdThread(ret);
188 // we use this flag to solve race condition between inferiorRPC and
189 // continueProc message from paradyn - naim
190 ret->deferredContinueProc = false;
192 ret->numOfActCounters_is=0;
193 ret->numOfActProcTimers_is=0;
194 ret->numOfActWallTimers_is=0;
201 process *dyninstAPI_attachProcess(const string &progpath, int pid,
204 // implementation of dynRPC::attach() (the igen call)
205 // This is meant to be "the other way" to start a process (competes w/ createProcess)
207 // progpath gives the full path name of the executable, which we use ONLY to
208 // read the symbol table.
210 // We try to make progpath optional, since given pid, we should be able to
211 // calculate it with a clever enough search of the process' PATH, examining
212 // its argv[0], examining its current directory, etc. /proc gives us this
213 // information on solaris...not sure about other platforms...
215 // possible values for afterAttach: 1 --> pause, 2 --> run, 0 --> leave as is
217 attach_cerr << "welcome to attachProcess for pid " << pid << endl;
219 // QUESTION: When we attach to a process, do we want to redirect its stdout/stderr
220 // (like we do when we fork off a new process the 'usual' way)?
221 // My first guess would be no. -ari
222 // But although we may ignore the io, we still need the trace stream.
224 // When we attach to a process, we don't fork...so this routine is much simpler
225 // than its "competitor", createProcess() (above).
227 // TODO: What about AIX establishBaseAddrs??? Do that now?
229 string fullPathToExecutable = process::tryToFindExecutable(progpath, pid);
230 if (!fullPathToExecutable.length())
233 image *theImage = image::parseImage(fullPathToExecutable);
234 if (theImage == NULL) {
235 // two failure return values would be useful here, to differentiate
236 // file-not-found vs. catastrophic-parse-error.
237 string msg = string("Unable to parse image: ") + fullPathToExecutable;
238 showErrorCallback(68, msg.string_of());
239 return NULL; // failure
243 vector<fastInferiorHeapMgr::oneHeapStats> theShmHeapStats(3);
244 theShmHeapStats[0].elemNumBytes = sizeof(intCounter);
245 theShmHeapStats[0].maxNumElems = numIntCounters;
247 theShmHeapStats[1].elemNumBytes = sizeof(tTimer);
248 theShmHeapStats[1].maxNumElems = numWallTimers;
250 theShmHeapStats[2].elemNumBytes = sizeof(tTimer);
251 theShmHeapStats[2].maxNumElems = numProcTimers;
254 // NOTE: the actual attach happens in the process "attach" constructor:
255 process *theProc = new process(pid, theImage, afterAttach
257 ,7000, // shm seg key to try first
263 // the attach ctor always leaves us stopped...we may get continued once
264 // DYNINSTinit has finished running...
265 assert(theProc->status() == stopped);
267 processVec += theProc;
270 // find the signal handler function
271 theProc->findSignalHandler(); // shouldn't this be in the ctor?
273 return theProc; // successful