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 // $Id: BPatch.C,v 1.48 2002/09/19 01:21:37 buck Exp $
50 #include "BPatch_libInfo.h"
52 #include "BPatch_collections.h"
53 #include "common/h/timing.h"
55 #if defined(i386_unknown_nt4_0) || defined(mips_unknown_ce2_11) //ccw 20 july 2000 : 28 mar 2001
56 #include "nt_signal_emul.h"
59 extern bool dyninstAPI_init();
60 extern int handleSigChild(int pid, int status);
63 BPatch *BPatch::bpatch = NULL;
68 * Constructor for BPatch. Performs one-time initialization needed by the
74 dynLibraryCallback(NULL),
78 baseTrampDeletionOn(false),
79 trampRecursiveOn(false),
80 forceRelocation_NP(false),
88 // Save a pointer to the one-and-only bpatch object.
91 #ifdef mips_unknown_ce2_11 //ccw 10 aug 2000 : 28 mar 2001
92 rDevice = new remoteDevice(); //ccw 8 aug 2000
97 * (indicate an error somehow)
100 // XXX dyninstAPI_init returns success/failure -- should pass on somehow
102 initCyclesPerSecond();
105 * Create the library private info object.
107 info = new BPatch_libInfo;
110 * Create the "error" and "untyped" types.
112 type_Error = new BPatch_type("<error>", true);
113 type_Untyped = new BPatch_type("<no type>", true);
116 * Initialize hash table of standard types.
118 stdTypes = new BPatch_typeCollection;
119 stdTypes->addType(new BPatch_type("int",-1, BPatch_dataScalar, sizeof(int)));
120 stdTypes->addType(new BPatch_type("char *",-3, BPatch_dataScalar, sizeof(char*)));
121 BPatch_type *voidType = new BPatch_type("void",-11, BPatch_dataScalar, 0);
122 stdTypes->addType(voidType);
123 stdTypes->addType(new BPatch_type("void *",-4, BPatch_dataPointer, voidType));
124 stdTypes->addType(new BPatch_type("float",-12, BPatch_dataScalar, sizeof(float)));
125 #if !defined(i386_unknown_nt4_0)
126 stdTypes->addType(new BPatch_type("long long",-31, BPatch_dataScalar, sizeof(long long int)));
130 * Initialize hash table of API types.
132 APITypes = new BPatch_typeCollection;
135 * Initialize hash table of Built-in types.
136 * Negative type numbers defined in the gdb stab-docs
139 builtInTypes = new BPatch_builtInTypeCollection;
141 // NOTE: integral type mean twos-complement
142 // -1 int, 32 bit signed integral type
143 // in stab document, size specified in bits, system size is in bytes
144 builtInTypes->addBuiltInType(new BPatch_type("int",-1, BPatch_dataBuilt_inType,
146 // -2 char, 8 bit type holding a character. GDB & dbx(AIX) treat as signed
147 builtInTypes->addBuiltInType(new BPatch_type("char",-2,
148 BPatch_dataBuilt_inType, 1));
149 // -3 short, 16 bit signed integral type
150 builtInTypes->addBuiltInType(new BPatch_type("short",-3,
151 BPatch_dataBuilt_inType, 2));
152 // -4 long, 32/64 bit signed integral type
153 builtInTypes->addBuiltInType(new BPatch_type("long",-4,
154 BPatch_dataBuilt_inType,
156 // -5 unsigned char, 8 bit unsigned integral type
157 builtInTypes->addBuiltInType(new BPatch_type("unsigned char",-5,
158 BPatch_dataBuilt_inType, 1));
159 // -6 signed char, 8 bit signed integral type
160 builtInTypes->addBuiltInType(new BPatch_type("signed char",-6,
161 BPatch_dataBuilt_inType, 1));
162 // -7 unsigned short, 16 bit unsigned integral type
163 builtInTypes->addBuiltInType(new BPatch_type("unsigned short",-7,
164 BPatch_dataBuilt_inType, 2));
165 // -8 unsigned int, 32 bit unsigned integral type
166 builtInTypes->addBuiltInType(new BPatch_type("unsigned int",-8,
167 BPatch_dataBuilt_inType, 4));
168 // -9 unsigned, 32 bit unsigned integral type
169 builtInTypes->addBuiltInType(new BPatch_type("unsigned",-9,
170 BPatch_dataBuilt_inType,4));
171 // -10 unsigned long, 32 bit unsigned integral type
172 builtInTypes->addBuiltInType(new BPatch_type("unsigned long",-10,
173 BPatch_dataBuilt_inType,
174 sizeof(unsigned long)));
175 // -11 void, type indicating the lack of a value
176 // XXX-size may not be correct jdd 4/22/99
177 builtInTypes->addBuiltInType(new BPatch_type("void",-11,
178 BPatch_dataBuilt_inType,
180 // -12 float, IEEE single precision
181 builtInTypes->addBuiltInType(new BPatch_type("float",-12,
182 BPatch_dataBuilt_inType,
184 // -13 double, IEEE double precision
185 builtInTypes->addBuiltInType(new BPatch_type("double",-13,
186 BPatch_dataBuilt_inType,
188 // -14 long double, IEEE double precision, size may increase in future
189 builtInTypes->addBuiltInType(new BPatch_type("long double",-14,
190 BPatch_dataBuilt_inType,
191 sizeof(long double)));
192 // -15 integer, 32 bit signed integral type
193 builtInTypes->addBuiltInType(new BPatch_type("integer",-15,
194 BPatch_dataBuilt_inType, 4));
195 // -16 boolean, 32 bit type. GDB/GCC 0=False, 1=True, all other values
196 // have unspecified meaning
197 builtInTypes->addBuiltInType(new BPatch_type("boolean",-16,
198 BPatch_dataBuilt_inType, 4));
199 // -17 short real, IEEE single precision
200 // XXX-size may not be correct jdd 4/22/99
201 builtInTypes->addBuiltInType(new BPatch_type("short real",-17,
202 BPatch_dataBuilt_inType,
204 // -18 real, IEEE double precision XXX-size may not be correct jdd 4/22/99
205 builtInTypes->addBuiltInType(new BPatch_type("real",-18,
206 BPatch_dataBuilt_inType,
208 // -19 stringptr XXX- size of void * -- jdd 4/22/99
209 builtInTypes->addBuiltInType(new BPatch_type("stringptr",-19,
210 BPatch_dataBuilt_inType,
212 // -20 character, 8 bit unsigned character type
213 builtInTypes->addBuiltInType(new BPatch_type("character",-20,
214 BPatch_dataBuilt_inType, 1));
215 // -21 logical*1, 8 bit type (Fortran, used for boolean or unsigned int)
216 builtInTypes->addBuiltInType(new BPatch_type("logical*1",-21,
217 BPatch_dataBuilt_inType, 1));
218 // -22 logical*2, 16 bit type (Fortran, some for boolean or unsigned int)
219 builtInTypes->addBuiltInType(new BPatch_type("logical*2",-22,
220 BPatch_dataBuilt_inType, 2));
221 // -23 logical*4, 32 bit type (Fortran, some for boolean or unsigned int)
222 builtInTypes->addBuiltInType(new BPatch_type("logical*4",-23,
223 BPatch_dataBuilt_inType, 4));
224 // -24 logical, 32 bit type (Fortran, some for boolean or unsigned int)
225 builtInTypes->addBuiltInType(new BPatch_type("logical",-24,
226 BPatch_dataBuilt_inType, 4));
227 // -25 complex, consists of 2 IEEE single-precision floating point values
228 builtInTypes->addBuiltInType(new BPatch_type("complex",-25,
229 BPatch_dataBuilt_inType,
231 // -26 complex, consists of 2 IEEE double-precision floating point values
232 builtInTypes->addBuiltInType(new BPatch_type("complex",-26,
233 BPatch_dataBuilt_inType,
234 (sizeof(double)*2)));
235 // -27 integer*1, 8 bit signed integral type
236 builtInTypes->addBuiltInType(new BPatch_type("integer*1",-27,
237 BPatch_dataBuilt_inType, 1));
238 // -28 integer*2, 16 bit signed integral type
239 builtInTypes->addBuiltInType(new BPatch_type("integer*2",-28,
240 BPatch_dataBuilt_inType, 2));
242 /* Quick hack to make integer*4 compatible with int for Fortran
245 builtInTypes->addBuiltInType(new BPatch_type("int",-29,
246 BPatch_built_inType, 4));
247 /* // -29 integer*4, 32 bit signed integral type
248 builtInTypes->addBuiltInType(new BPatch_type("integer*4",-29,
249 BPatch_built_inType, 4)); */
251 // -30 wchar, Wide character, 16 bits wide, unsigned (unknown format)
252 builtInTypes->addBuiltInType(new BPatch_type("wchar",-30,
253 BPatch_dataBuilt_inType, 2));
254 // -31 long long, 64 bit signed integral type
255 builtInTypes->addBuiltInType(new BPatch_type("long long",-31,
256 BPatch_dataBuilt_inType, 8));
257 // -32 unsigned long long, 64 bit unsigned integral type
258 builtInTypes->addBuiltInType(new BPatch_type("unsigned long long", -32,
259 BPatch_dataBuilt_inType, 8));
260 // -33 logical*8, 64 bit unsigned integral type
261 builtInTypes->addBuiltInType(new BPatch_type("logical*8",-33,
262 BPatch_dataBuilt_inType, 8));
263 // -34 integer*8, 64 bit signed integral type
264 builtInTypes->addBuiltInType(new BPatch_type("integer*8",-34,
265 BPatch_dataBuilt_inType, 8));
267 // default callbacks are null
268 postForkCallback = NULL;
269 preForkCallback = NULL;
271 dynLibraryCallback = NULL;
274 oneTimeCodeCallback = NULL;
276 #ifdef DETACH_ON_THE_FLY
277 // Register handler for notification from detached inferiors
278 extern void initDetachOnTheFly();
279 initDetachOnTheFly();
287 * Destructor for BPatch. Free allocated memory.
303 * BPatch::registerErrorCallback
305 * Registers a function that is to be called by the library when an error
306 * occurs or when there is status to report. Returns the address of the
307 * previously registered error callback function.
309 * function The function to be called.
311 BPatchErrorCallback BPatch::registerErrorCallback(BPatchErrorCallback function)
313 BPatchErrorCallback ret;
316 errorHandler = function;
323 * BPatch::registerPostForkCallback
325 * Registers a function that is to be called by the library when a new
326 * process has been forked off by an mutatee process.
328 * function The function to be called.
330 BPatchForkCallback BPatch::registerPostForkCallback(BPatchForkCallback func)
333 #if !defined(sparc_sun_solaris2_4) && \
334 !defined(i386_unknown_solaris2_5) && \
335 !defined(alpha_dec_osf4_0) && \
336 !defined(mips_sgi_irix6_4)
338 reportError(BPatchWarning, 0,
339 "postfork callbacks not implemented on this platform\n");
342 BPatchForkCallback ret;
344 ret = postForkCallback;
345 postForkCallback = func;
352 * BPatch::registerPreForkCallback
354 * Registers a function that is to be called by the library when a process
355 * is about to fork a new process
357 * function The function to be called.
359 BPatchForkCallback BPatch::registerPreForkCallback(BPatchForkCallback func)
361 #if !defined(sparc_sun_solaris2_4) && \
362 !defined(i386_unknown_solaris2_5) &&\
363 !defined(alpha_dec_osf4_0) && \
364 !defined(mips_sgi_irix6_4)
365 reportError(BPatchWarning, 0,
366 "prefork callbacks not implemented on this platform\n");
369 BPatchForkCallback ret;
371 ret = preForkCallback;
372 preForkCallback = func;
379 * BPatch::registerExecCallback
381 * Registers a function that is to be called by the library when a
382 * process has just completed an exec* call
384 * func The function to be called.
386 BPatchExecCallback BPatch::registerExecCallback(BPatchExecCallback func)
389 #if !defined(sparc_sun_solaris2_4) && \
390 !defined(i386_unknown_solaris2_5) &&\
391 !defined(alpha_dec_osf4_0) && \
392 !defined(mips_sgi_irix6_4)
393 reportError(BPatchWarning, 0,
394 "exec callbacks not implemented on this platform\n");
397 BPatchExecCallback ret;
407 * BPatch::registerExecCallback
409 * Registers a function that is to be called by the library when a
410 * process has just called the exit system call
412 * func The function to be called.
414 BPatchExitCallback BPatch::registerExitCallback(BPatchExitCallback func)
417 #if !defined(sparc_sun_solaris2_4) && \
418 !defined(i386_unknown_solaris2_5) &&\
419 !defined(alpha_dec_osf4_0) && \
420 !defined(mips_sgi_irix6_4)
421 reportError(BPatchWarning, 0,
422 "exit callbacks not implemented on this platform\n");
425 BPatchExitCallback ret;
435 * BPatch::registerOneTimeCodeCallback
437 * Registers a function that is to be called by the library when a
438 * oneTimeCode (inferior RPC) is completed.
440 * func The function to be called.
442 BPatchOneTimeCodeCallback BPatch::registerOneTimeCodeCallback(BPatchOneTimeCodeCallback func)
444 BPatchOneTimeCodeCallback ret;
446 ret = oneTimeCodeCallback;
447 oneTimeCodeCallback = func;
452 #ifdef IBM_BPATCH_COMPAT
453 BPatchExitCallback BPatch::registerExitCallback(BPatchThreadEventCallback func)
456 BPatchExitCallback ret;
459 exitCallback = (BPatchExitCallback) func;
467 * BPatch::registerDynLibraryCallback
469 * Registers a function that is to be called by the library when a dynamically
470 * loaded library is loaded or unloaded by a process under the API's control.
471 * Returns the address of the previously registered callback function.
473 * function The function to be called.
475 BPatchDynLibraryCallback
476 BPatch::registerDynLibraryCallback(BPatchDynLibraryCallback function)
478 BPatchDynLibraryCallback ret;
480 ret = dynLibraryCallback;
481 dynLibraryCallback = function;
488 * BPatch::getEnglishErrorString
490 * Returns the descriptive error string for the passed error number.
492 * number The number that identifies the error.
494 const char *BPatch::getEnglishErrorString(int /* number */)
501 * BPatch::reportError
503 * Report an error using the callback mechanism.
505 * severity The severity level of the error.
506 * number Identifies the error.
507 * str A string to pass as the first element of the list of strings
508 * given to the callback function.
510 void BPatch::reportError(BPatchErrorLevel severity, int number, const char *str)
512 assert(bpatch != NULL);
514 // don't log BPatchWarning or BPatchInfo messages as "errors"
515 if ((severity == BPatchFatal) || (severity == BPatchSerious))
516 bpatch->lastError = number;
518 if (bpatch->errorHandler != NULL) {
519 bpatch->errorHandler(severity, number, &str);
520 } else if ((severity == BPatchFatal) || (severity == BPatchSerious)){
521 fprintf(stdout, "DYNINST ERROR: %s\n", str);
528 * BPatch::formatErrorString
530 * Takes a format string with an error message (obtained from
531 * getEnglishErrorString) and an array of parameters that were passed to an
532 * error callback function, and creates a string with the parameters
533 * substituted into it.
535 * dst The address into which the formatted string should be copied.
536 * size If the formatted string is equal to or longer than this number
537 * of characters, then it will be truncated to size-1 characters
538 * and terminated with a nul ('\0').
539 * fmt The format string (returned by a function such as
540 * getEnglishErrorString).
541 * params The array of parameters that were passed to an error callback
544 void BPatch::formatErrorString(char *dst, int size,
545 const char *fmt, const char **params)
549 while (size > 1 && *fmt) {
551 if (fmt[1] == '\0') {
553 } else if (fmt[1] == '%') {
556 } else if (fmt[1] == 's') {
557 char *p = const_cast<char *>(params[cur_param++]);
558 while (size > 1 && *p) {
580 * BPatch::getThreadByPid
582 * Given a process ID, this function returns a pointer to the associated
583 * BPatch_thread object (or NULL if there is none). Since a process may be
584 * registered provisionally with a thread object pointer of NULL, the boolean
585 * pointed to by the parameter "exists" is set to true if the pid exists in
586 * the table of processes, and false if it does not.
588 * pid The pid to look up.
589 * exists A pointer to a boolean to fill in with true if the pid exists
590 * in the table and false if it does not. NULL may be passed in
591 * if this information is not required.
593 BPatch_thread *BPatch::getThreadByPid(int pid, bool *exists)
595 if (info->threadsByPid.defines(pid)) {
596 if (exists) *exists = true;
597 return info->threadsByPid[pid];
599 if (exists) *exists = false;
608 * Returns a vector of all threads that are currently defined. Includes
609 * threads created directly using the library and those created with UNIX fork
610 * or Windows NT spawn system calls. The caller is responsible for deleting
611 * the vector when it is no longer needed.
613 BPatch_Vector<BPatch_thread *> *BPatch::getThreads()
615 BPatch_Vector<BPatch_thread *> *result = new BPatch_Vector<BPatch_thread *>;
617 dictionary_hash_iter<int, BPatch_thread *> ti(info->threadsByPid);
620 BPatch_thread *thread;
622 while (ti.next(pid, thread))
623 result->push_back(thread);
630 * BPatch::registerProvisionalThread
632 * Register a new process that is not yet associated with a thread.
633 * (this function is called only by createProcess).
635 * pid The pid of the process to register.
637 void BPatch::registerProvisionalThread(int pid)
639 assert(!info->threadsByPid.defines(pid));
640 info->threadsByPid[pid] = NULL;
645 * BPatch::registerForkedThread
647 * Register a new process that is not yet associated with a thread.
648 * (this function is an upcall when a new process is created).
650 * parentPid the pid of the parent process.
651 * childPid The pid of the process to register.
652 * proc lower lever handle to process specific stuff
655 void BPatch::registerForkedThread(int parentPid, int childPid, process *proc)
657 assert(!info->threadsByPid.defines(childPid));
659 BPatch_thread *parent = info->threadsByPid[parentPid];
662 info->threadsByPid[childPid] = new BPatch_thread(childPid, proc);
664 if (postForkCallback) {
665 postForkCallback(parent, info->threadsByPid[childPid]);
671 * BPatch::registerExec
673 * Register a process that has just done an exec call.
675 * thread thread that has just performed the exec
678 void BPatch::registerExec(BPatch_thread *thread)
680 // build a new BPatch_image for this one
681 thread->image = new BPatch_image(thread->proc);
684 execCallback(thread);
690 * BPatch::registerExit
692 * Register a process that has just done an exit call.
694 * thread thread that has just performed the exec
695 * code the exit status code
698 void BPatch::registerExit(BPatch_thread *thread, int code)
701 exitCallback(thread, code);
707 * BPatch::registerThread
709 * Register a new BPatch_thread object with the BPatch library (this function
710 * is called only by the constructor for BPatch_thread).
712 * thread A pointer to the thread to register.
714 void BPatch::registerThread(BPatch_thread *thread)
716 assert(!info->threadsByPid.defines(thread->getPid()) ||
717 info->threadsByPid[thread->getPid()] == NULL);
718 info->threadsByPid[thread->getPid()] = thread;
723 * BPatch::unRegisterThread
725 * Remove the BPatch_thread associated with a given pid from the list of
726 * threads being managed by the library.
728 * pid The pid of the thread to be removed.
730 void BPatch::unRegisterThread(int pid)
732 assert(info->threadsByPid.defines(pid));
733 info->threadsByPid.undef(pid);
738 * BPatch::createProcess
740 * Create a process and return a BPatch_thread representing it.
741 * Returns NULL upon failure.
743 * path The pathname of the executable for the new process.
744 * argv A list of the arguments for the new process, terminated by a
746 * envp A list of values that make up the environment for the new
747 * process, terminated by a NULL. If envp is NULL, the new
748 * new process will inherit the environemnt of the parent.
749 * stdin_fd file descriptor to use for stdin for the application
750 * stdout_fd file descriptor to use for stdout for the application
751 * stderr_fd file descriptor to use for stderr for the application
754 BPatch_thread *BPatch::createProcess(char *path, char *argv[],
755 char *envp[], int stdin_fd, int stdout_fd, int stderr_fd)
760 new BPatch_thread(path, argv, envp, stdin_fd, stdout_fd, stderr_fd);
763 (ret->proc->status() != stopped) ||
764 !ret->proc->isBootstrappedYet()) {
768 ret->proc->collectSaveWorldData = false;
769 //ccw 23 jan 2002 : this forces the user to call
770 //BPatch_thread::startSaveWorld() if they want to use the save the world
777 * BPatch::attachProcess
779 * Attach to a running process and return a BPatch_thread representing it.
780 * Returns NULL upon failure.
782 * path The pathname of the executable for the process.
783 * pid The id of the process to attach to.
785 BPatch_thread *BPatch::attachProcess(char *path, int pid)
789 BPatch_thread *ret = new BPatch_thread(path, pid);
792 (ret->proc->status() != stopped) ||
793 !ret->proc->isBootstrappedYet()) {
794 // It would be considerate to (attempt to) leave the process running
795 // at this point (*before* deleting the BPatch_thread handle for it!),
796 // even though it might be in bad shape after the attempted attach.
798 sprintf(msg,"attachProcess failed: process %d may now be killed!",pid);
799 reportError(BPatchWarning, 26, msg);
808 * BPatch::getThreadEvent
810 * Checks for changes in any child process, and optionally blocks until such a
811 * change has occurred. Also performs housekeeping on behalf of Dyninst:
812 * - Launches pending oneTimeCode calls (aka inferior RPCs)
813 * - Updates the process object representing each process for which a
814 * change is detected.
816 * The return value is true if a change was detected, otherwise it is false.
818 * block Set this parameter to true to block waiting for a change,
819 * set to false to poll and return immediately, whether or not a
822 bool BPatch::getThreadEvent(bool block)
824 launchDeferredOneTimeCode();
826 return getThreadEventOnly(block);
830 * BPatch::getThreadEventOnly
832 * Like getThreadEvent (which actually calls this function), this function
833 * checks for changes in any child process, optionally blocking until such a
834 * change occurs. It also updates the process objects with information about
835 * such changes. Unlike getThreadEvent, it does not perform any additional
836 * housekeeping like launching deferred RPCs.
838 * Returns true if a change was detected, otherwise returns false.
840 * block Set this parameter to true to block waiting for a change,
841 * set to false to poll and return immediately, whether or not a
844 bool BPatch::getThreadEventOnly(bool block)
849 // while ((pid = process::waitProcs(&status, block)) > 0) {
850 if ((pid = process::waitProcs(&status, block)) > 0) {
851 // There's been a change in a child process
853 // Since we found something, we don't want to block anymore
857 BPatch_thread *thread = getThreadByPid(pid, &exists);
858 if (thread == NULL) {
860 if (WIFSIGNALED(status) || WIFEXITED(status))
861 unRegisterThread(pid);
863 fprintf(stderr, "Warning - wait returned status of an unknown process (%d)\n", pid);
866 if (thread != NULL) {
867 if (WIFSTOPPED(status)) {
868 thread->lastSignal = WSTOPSIG(status);
869 thread->setUnreportedStop(true);
870 } else if (WIFSIGNALED(status)) {
871 thread->lastSignal = WTERMSIG(status);
872 thread->setUnreportedTermination(true);
873 } else if (WIFEXITED(status)) {
874 #if !defined(i386_unknown_nt4_0) && !defined(mips_unknown_ce2_11) //ccw 20 july 2000 : 28 mar 2001
875 thread->proc->exitCode_ = WEXITSTATUS(status);
877 thread->exitCode = thread->proc->exitCode();
878 thread->lastSignal = 0; /* XXX Make into some constant */
879 thread->setUnreportedTermination(true);
882 #if !(defined i386_unknown_nt4_0) && !(defined mips_unknown_ce2_11) //ccw 20 july 2000 : 28 mar 2001
884 handleSigChild(pid, status);
886 if (thread->lastSignal == SIGSTOP) {
887 // need to continue process after initial sigstop
888 // thread->continueExecution();
889 printf("BPatch past handleSigChild for SIGSTOP\n");
890 if (thread->proc->wasCreatedViaFork()) {
891 printf("marking forked process stopped\n");
892 thread->proc->status_ = stopped;
893 // thread->lastSignal = SIGSTOP;
894 // thread->setUnreportedStop(true);
895 // thread->proc->continueProc();
909 * Returns true if any thread has stopped or terminated and that fact hasn't
910 * been reported to the user of the library. Otherwise, returns false.
912 bool BPatch::havePendingEvent()
914 #if defined(i386_unknown_nt4_0) || defined(mips_unknown_ce2_11) //ccw 20 july 2001 : 28 mar 2001
915 // On NT, we need to poll for events as often as possible, so that we can
917 if (getThreadEvent(false))
921 // For now, we'll do it by iterating over the threads and checking them,
922 // and we'll change it to something more efficient later on.
923 dictionary_hash_iter<int, BPatch_thread *> ti(info->threadsByPid);
926 BPatch_thread *thread;
928 while (ti.next(pid, thread)) {
929 if (thread != NULL &&
930 (thread->pendingUnreportedStop() ||
931 thread->pendingUnreportedTermination())) {
941 * pollForStatusChange
943 * Checks for unreported changes to the status of any child process, and
944 * returns true if any are detected. Returns false otherwise.
946 * This function is declared as a friend of BPatch_thread so that it can use
947 * the BPatch_thread::getThreadEvent call to check for status changes.
949 bool BPatch::pollForStatusChange()
951 if (havePendingEvent())
954 // No changes were previously detected, so check for new changes
955 return getThreadEvent(false);
960 * waitForStatusChange
962 * Blocks waiting for a change to occur in the running status of a child
963 * process. Returns true upon success, false upon failure.
965 * This function is declared as a friend of BPatch_thread so that it can use
966 * the BPatch_thread::getThreadEvent call to check for status changes.
968 bool BPatch::waitForStatusChange()
970 if (havePendingEvent())
973 // No changes were previously detected, so wait for a new change
974 return getThreadEvent(true);
980 * This function is a wrapper for the BPatch_type constructors for API/User
983 * It returns a pointer to a BPatch_type that was added to the APITypes
986 BPatch_type * BPatch::createEnum( const char * name,
987 BPatch_Vector<char *> elementNames,
988 BPatch_Vector<int> elementIds)
991 if (elementNames.size() != elementIds.size()) {
995 BPatch_type * newType = new BPatch_type( name, BPatch_dataEnumerated );
996 if (!newType) return NULL;
998 APITypes->addType(newType);
1000 // ADD components to type
1001 for (unsigned int i=0; i < elementNames.size(); i++) {
1002 newType->addField(elementNames[i], BPatch_dataScalar, elementIds[i]);
1012 * This function is a wrapper for the BPatch_type constructors for API/User
1013 * created types. The user has left element id specification to us
1015 * It returns a pointer to a BPatch_type that was added to the APITypes
1018 BPatch_type * BPatch::createEnum( const char * name,
1019 BPatch_Vector<char *> elementNames)
1021 BPatch_type * newType = new BPatch_type( name, BPatch_dataEnumerated );
1023 if (!newType) return NULL;
1025 APITypes->addType(newType);
1027 // ADD components to type
1028 for (unsigned int i=0; i < elementNames.size(); i++) {
1029 newType->addField(elementNames[i], BPatch_dataScalar, i);
1038 * This function is a wrapper for the BPatch_type constructors for API/User
1041 * It returns a pointer to a BPatch_type that was added to the APITypes
1045 BPatch_type * BPatch::createStruct( const char * name,
1046 BPatch_Vector<char *> fieldNames,
1047 BPatch_Vector<BPatch_type *> fieldTypes)
1053 if (fieldNames.size() != fieldTypes.size()) {
1057 //Compute the size of the struct
1058 for (i=0; i < fieldNames.size(); i++) {
1059 BPatch_type *type = fieldTypes[i];
1060 size = type->getSize();
1064 BPatch_type *newType = new BPatch_type(name, BPatch_dataStructure, size);
1065 if (!newType) return NULL;
1067 APITypes->addType(newType);
1069 // ADD components to type
1071 for (i=0; i < fieldNames.size(); i++) {
1072 BPatch_type *type = fieldTypes[i];
1073 size = type->getSize();
1074 newType->addField(fieldNames[i], type->getDataClass(), type, offset, size);
1076 // Calculate next offset (in bits) into the struct
1077 offset += (size * 8);
1086 * This function is a wrapper for the BPatch_type constructors for API/User
1089 * It returns a pointer to a BPatch_type that was added to the APITypes
1093 BPatch_type * BPatch::createUnion( const char * name,
1094 BPatch_Vector<char *> fieldNames,
1095 BPatch_Vector<BPatch_type *> fieldTypes)
1098 int offset, size, newsize;
1099 offset = size = newsize = 0;
1101 if (fieldNames.size() != fieldTypes.size()) {
1105 // Compute the size of the union
1106 for (i=0; i < fieldTypes.size(); i++) {
1107 BPatch_type *type = fieldTypes[i];
1108 newsize = type->getSize();
1109 if(size < newsize) size = newsize;
1112 BPatch_type * newType = new BPatch_type(name, BPatch_dataUnion, size);
1113 if (!newType) return NULL;
1115 APITypes->addType(newType);
1117 // ADD components to type
1118 for (i=0; i < fieldNames.size(); i++) {
1119 BPatch_type *type = fieldTypes[i];
1120 size = type->getSize();
1121 newType->addField(fieldNames[i], type->getDataClass(), type, offset, size);
1128 * createArray for Arrays and SymTypeRanges
1130 * This function is a wrapper for the BPatch_type constructors for API/User
1133 * It returns a pointer to a BPatch_type that was added to the APITypes
1136 BPatch_type * BPatch::createArray( const char * name, BPatch_type * ptr,
1137 unsigned int low, unsigned int hi)
1140 BPatch_type * newType;
1145 newType = new BPatch_type(name, BPatch_dataArray , ptr, low, hi);
1146 if (!newType) return NULL;
1149 APITypes->addType(newType);
1155 * createPointer for BPatch_pointers
1157 * This function is a wrapper for the BPatch_type constructors for API/User
1160 * It returns a pointer to a BPatch_type that was added to the APITypes
1163 BPatch_type * BPatch::createPointer(const char * name, BPatch_type * ptr,
1167 BPatch_type * newType = new BPatch_type(name, ptr, size);
1168 if(!newType) return NULL;
1170 APITypes->addType(newType);
1176 * createScalar for scalars with a size and no range
1178 * This function is a wrapper for the BPatch_type constructors for API/User
1181 * It returns a pointer to a BPatch_type that was added to the APITypes
1185 BPatch_type * BPatch::createScalar( const char * name, int size)
1187 BPatch_type * newType = new BPatch_type(name, BPatch_dataScalar, size);
1188 if (!newType) return NULL;
1190 APITypes->addType(newType);
1196 * createType for typedefs
1198 * This function is a wrapper for the BPatch_type constructors for API/User
1201 * It returns a pointer to a BPatch_type that was added to the APITypes
1204 BPatch_type * BPatch::createTypedef( const char * name, BPatch_type * ptr)
1206 BPatch_type * newType = new BPatch_type(name, ptr);
1208 if (!newType) return NULL;
1210 APITypes->addType(newType);
1215 bool BPatch::waitUntilStopped(BPatch_thread *appThread){
1216 while (!appThread->isStopped() && !appThread->isTerminated())
1217 this->waitForStatusChange();
1219 if (!appThread->isStopped())
1221 cerr << "ERROR : process did not signal mutator via stop"
1225 #if defined(i386_unknown_nt4_0) || \
1226 defined(mips_unknown_ce2_11)
1227 else if((appThread->stopSignal() != SIGTRAP) &&
1228 (appThread->stopSignal() != -1))
1230 cerr << "ERROR : process stopped on signal different"
1231 << " than SIGTRAP" << endl;
1235 #ifdef DETACH_ON_THE_FLY
1236 else if ((appThread->stopSignal() != SIGSTOP) &&
1237 (appThread->stopSignal() != SIGHUP) &&
1238 (appThread->stopSignal() != SIGILL)) {
1240 else if ((appThread->stopSignal() != SIGSTOP) &&
1241 #ifdef USE_IRIX_FIXES
1242 (appThread->stopSignal() != SIGEMT) &&
1243 #endif /* USE_IRIX_FIXES */
1244 (appThread->stopSignal() != SIGHUP)) {
1245 #endif /* DETACH_ON_THE_FLY */
1246 cerr << "ERROR : process stopped on signal "
1247 << "different than SIGSTOP" << endl;
1254 #ifdef IBM_BPATCH_COMPAT
1257 * Register a function to call when an RPC (i.e. oneshot) is done.
1259 * dyninst version is a callback that is defined for BPatch_thread
1262 BPatchThreadEventCallback BPatch::registerRPCTerminationCallback(BPatchThreadEventCallback func)
1264 BPatchThreadEventCallback ret;
1266 ret = RPCdoneCallback;
1267 RPCdoneCallback = func;
1272 void setLogging_NP(BPatchLoggingCallback, int)
1280 * BPatch::launchDeferredOneTimeCode
1282 * Launch any deferred oneTimeCode calls (aka inferior RPCs) that might exist,
1283 * if it is now okay to do so.
1285 void BPatch::launchDeferredOneTimeCode()
1287 for (unsigned int p = 0; p < processVec.size(); p++) {
1288 process *proc = processVec[p];
1293 if (proc->status() == exited || proc->status() == neonatal)
1296 proc->launchRPCifAppropriate(proc->status() == running, false);