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.
48 #include "BPatch_type.h"
51 extern bool dyninstAPI_init();
52 extern int dyninstAPI_handleSigChild(int pid, int status);
55 BPatch *BPatch::bpatch = NULL;
61 * Constructor for BPatch. Performs one-time initialization needed by the
64 BPatch::BPatch() : errorHandler(NULL), typeCheckOn(true)
67 extern double cyclesPerSecond;
68 extern double timing_loop(const unsigned, const unsigned);
70 // Save a pointer to the one-and-only bpatch object.
74 * (indicate an error somehow)
77 // XXX dyninstAPI_init returns success/failure -- should pass on somehow
79 cyclesPerSecond = timing_loop(1, 100000) * 1000000;
82 * Create the "error" and "untyped" types.
84 type_Error = new BPatch_type("<error>", true);
85 type_Untyped = new BPatch_type("<no type>", true);
88 * Initialize hash table of standard types.
90 stdTypes = new BPatch_typeCollection;
91 stdTypes->addType(new BPatch_type("int"));
92 stdTypes->addType(new BPatch_type("char *"));
99 * Destructor for BPatch. Free allocated memory.
111 * BPatch::registerErrorCallback
113 * Registers a function that is to be called by the library when an error
114 * occurs or when there is status to report. Returns the address of the
115 * previously registered error callback function.
117 * function The function to be called.
119 BPatchErrorCallback BPatch::registerErrorCallback(BPatchErrorCallback function)
121 BPatchErrorCallback ret;
124 errorHandler = function;
131 * BPatch::getEnglishErrorString
133 * Returns the descriptive error string for the passed error number.
135 * number The number that identifies the error.
137 const char *BPatch::getEnglishErrorString(int /* number */)
144 * BPatch::reportError
146 * Report an error using the callback mechanism.
148 * severity The severity level of the error.
149 * number Identifies the error.
150 * str A string to pass as the first element of the list of strings
151 * given to the callback function.
153 void BPatch::reportError(BPatchErrorLevel severity, int number, const char *str)
155 if (errorHandler != NULL) {
156 errorHandler(severity, number, &str);
162 * BPatch::formatErrorString
164 * Takes a format string with an error message (obtained from
165 * getEnglishErrorString) and an array of parameters that were passed to an
166 * error callback function, and creates a string with the parameters
167 * substituted into it.
169 * dst The address into which the formatted string should be copied.
170 * size If the formatted string is equal to or longer than this number
171 * of characters, then it will be truncated to size-1 characters
172 * and terminated with a nul ('\0').
173 * fmt The format string (returned by a function such as
174 * getEnglishErrorString).
175 * params The array of parameters that were passed to an error callback
178 void BPatch::formatErrorString(char *dst, int size,
179 const char *fmt, const char **params)
183 while (size > 1 && *fmt) {
185 if (fmt[1] == '\0') {
187 } else if (fmt[1] == '%') {
190 } else if (fmt[1] == 's') {
191 char *p = (char *)params[cur_param++];
192 while (size > 1 && *p) {
214 * BPatch::pidToThread
216 * Given a process ID, this function returns a pointer to the associated
217 * BPatch_thread object (or NULL if there is none).
219 BPatch_thread *BPatch::pidToThread(int pid)
221 for (int i = 0; i < threadVec.size(); i++)
222 if (threadVec[i]->getPid() == pid) return threadVec[i];
231 * Returns a vector of all threads that are currently defined. Includes
232 * threads created directly using the library and those created with UNIX fork
233 * or Windows NT spawn system calls. The caller is responsible for deleting
234 * the vector when it is no longer needed.
236 BPatch_Vector<BPatch_thread *> *BPatch::getThreads()
238 BPatch_Vector<BPatch_thread *> *result = new BPatch_Vector<BPatch_thread *>;
247 * pollForStatusChange
249 * Checks for changes in the state of any child process, and returns true if
250 * it discovers any such changes. Also updates the process object
251 * representing each process for which a change is detected.
253 * This function is declared as a friend of BPatch_thread so that it can use
254 * the BPatch_thread::pidToThread call and so that it can set the lastSignal
255 * member of a BPatch_thread object.
257 bool pollForStatusChange()
262 while ((pid = process::waitProcs(&status)) > 0) {
263 // There's been a change in a child process
265 assert(BPatch::bpatch != NULL);
266 BPatch_thread *thread = BPatch::bpatch->pidToThread(pid);
267 assert(thread != NULL);
268 if (thread != NULL) {
269 if (WIFSTOPPED(status))
270 thread->lastSignal = WSTOPSIG(status);
271 else if (WIFSIGNALED(status))
272 thread->lastSignal = WTERMSIG(status);
273 else if (WIFEXITED(status))
274 thread->lastSignal = 0; /* XXX Make into some constant */
276 dyninstAPI_handleSigChild(pid, status);